diff --git a/src/modules/graphics/opengl/Framebuffer.cpp b/src/modules/graphics/opengl/Framebuffer.cpp index b62b95a77..287db0048 100644 --- a/src/modules/graphics/opengl/Framebuffer.cpp +++ b/src/modules/graphics/opengl/Framebuffer.cpp @@ -1,6 +1,8 @@ #include "Framebuffer.h" #include +#include + #include #include #include @@ -275,6 +277,37 @@ namespace opengl glPopMatrix(); } + love::image::ImageData * Framebuffer::getImageData(love::image::Image * image) + { + int row = 4 * width; + int size = row * height; + + // see Graphics::newScreenshot. OpenGL reads from lower-left, + // but we need the pixels from upper-left. + GLubyte* pixels = new GLubyte[size]; + GLubyte* screenshot = new GLubyte[size]; + + strategy->bindFBO( fbo ); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + if (current) + strategy->bindFBO( current->fbo ); + else + strategy->bindFBO( 0 ); + + GLubyte* src = pixels - row; // second line of buffer + GLubyte* dst = screenshot + size; // end of buffer + + for (int i = 0; i < height; ++i) + memcpy(dst -= row, src += row, row); + + love::image::ImageData * img = image->newImageData(width, height, (void*)screenshot); + + delete[] screenshot; + delete[] pixels; + + return img; + } + } // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/Framebuffer.h b/src/modules/graphics/opengl/Framebuffer.h index 22b4025e6..3e356c5a4 100644 --- a/src/modules/graphics/opengl/Framebuffer.h +++ b/src/modules/graphics/opengl/Framebuffer.h @@ -2,7 +2,8 @@ #define LOVE_GRAPHICS_FRAMEBUFFER_H #include -#include +#include +#include #include #include #include "GLee.h" @@ -29,7 +30,7 @@ namespace opengl void stopGrab(); virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const; - + love::image::ImageData * getImageData(love::image::Image * image); private: GLsizei width; diff --git a/src/modules/graphics/opengl/wrap_Framebuffer.cpp b/src/modules/graphics/opengl/wrap_Framebuffer.cpp index db882805f..5bb67fdc9 100644 --- a/src/modules/graphics/opengl/wrap_Framebuffer.cpp +++ b/src/modules/graphics/opengl/wrap_Framebuffer.cpp @@ -32,8 +32,18 @@ namespace opengl return 0; } + int w_Framebuffer_getImageData(lua_State * L) + { + Framebuffer * fbo = luax_checkfbo(L, 1); + love::image::Image * image = luax_getmodule(L, "image", MODULE_IMAGE_T); + love::image::ImageData * img = fbo->getImageData( image ); + luax_newtype(L, "ImageData", IMAGE_IMAGE_DATA_T, (void *)img); + return 1; + } + static const luaL_Reg functions[] = { { "renderTo", w_Framebuffer_renderTo }, + { "getImageData", w_Framebuffer_getImageData }, { 0, 0 } }; diff --git a/src/modules/graphics/opengl/wrap_Framebuffer.h b/src/modules/graphics/opengl/wrap_Framebuffer.h index 563a3abbd..ecb491604 100644 --- a/src/modules/graphics/opengl/wrap_Framebuffer.h +++ b/src/modules/graphics/opengl/wrap_Framebuffer.h @@ -14,6 +14,7 @@ namespace opengl //see Framebuffer.h Framebuffer * luax_checkfbo(lua_State * L, int idx); int w_Framebuffer_renderTo(lua_State * L); + int w_Framebuffer_getImageData(lua_State * L); int luaopen_framebuffer(lua_State * L); } // opengl