소스 검색

Image::create no longer requires data to be created. It will allocate image data if the data parameter is NULL.
Renamed FrameBuffer::getCurrentScreenshot to createScreenshot to imply that something new (the Image) is being created.
Also added getScreenshot so that one Image can be created and be called multiple times without allocating more memory.

Rcmaniac25 12 년 전
부모
커밋
79e257a470

+ 12 - 6
gameplay/src/FrameBuffer.cpp

@@ -269,20 +269,26 @@ FrameBuffer* FrameBuffer::bind()
     return previousFrameBuffer;
 }
 
-Image* FrameBuffer::getCurrentScreenshot()
+void FrameBuffer::getScreenshot(Image* image)
 {
 	//While possible to have a non-static getScreenshot function, it would require the expensive operation 
-	//of binding the FrameBuffer, reading the pixels, then rebinding the original FrameBuffer. This is faster.
+	//of binding the FrameBuffer, reading the pixels, then rebinding the original FrameBuffer. This is faster.(
+
+	GP_ASSERT(image);
+	GP_ASSERT(image->getFormat() == Image::RGBA);
 
 	unsigned int width = _currentFrameBuffer->getWidth();
 	unsigned int height = _currentFrameBuffer->getHeight();
-	unsigned char* data = new unsigned char[width * height * 4];
 
-	GL_ASSERT( glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data) );
+	if (image->getWidth() == width && image->getHeight() == height)
+		GL_ASSERT( glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, image->getData()) );
+}
 
-	Image* screenshot = Image::create(width, height, Image::RGBA, data);
+Image* FrameBuffer::createScreenshot()
+{
+	Image* screenshot = Image::create(_currentFrameBuffer->getWidth(), _currentFrameBuffer->getHeight(), Image::RGBA, NULL);
 
-	SAFE_DELETE_ARRAY(data);
+	getScreenshot(screenshot);
 
 	return screenshot;
 }

+ 11 - 1
gameplay/src/FrameBuffer.h

@@ -157,7 +157,17 @@ public:
 	 * 
 	 * @return A screenshot of the current framebuffer's content.
 	 */
-	static Image* getCurrentScreenshot();
+	static Image* createScreenshot();
+
+	/**
+	 * Records a screenshot of what is stored on the current FrameBuffer to an Image.
+	 * 
+	 * The Image must be the same size as the FrameBuffer, otherwise the operation will fail.
+	 * The Image must be format RGBA.
+	 * 
+	 * @param image The Image to write the current framebuffer's content to.
+	 */
+	static void getScreenshot(Image* image);
 
     /**
      * Binds the default FrameBuffer for rendering to the display.

+ 5 - 3
gameplay/src/Image.cpp

@@ -109,7 +109,6 @@ Image* Image::create(const char* path)
 
 Image* Image::create(unsigned int width, unsigned int height, Image::Format format, unsigned char* data)
 {
-	GP_ASSERT(data);
 	GP_ASSERT(width > 0 && height > 0);
 	GP_ASSERT(format >= RGB && format <= RGBA);
 
@@ -126,11 +125,14 @@ Image* Image::create(unsigned int width, unsigned int height, Image::Format form
 
 	Image* image = new Image();
 
+	unsigned int dataSize = width * height * pixelSize;
+
 	image->_width = width;
 	image->_height = height;
 	image->_format = format;
-	image->_data = new unsigned char[width * height * pixelSize];
-	memcpy(image->_data, data, width * height * pixelSize);
+	image->_data = new unsigned char[dataSize];
+	if (data)
+		memcpy(image->_data, data, dataSize);
 
 	return image;
 }

+ 2 - 2
gameplay/src/Image.h

@@ -37,11 +37,11 @@ public:
      * @param width The width of the image data.
 	 * @param height The height of the image data.
 	 * @param format The format of the image data.
-	 * @param data The image data.
+	 * @param data The image data. If NULL, the data will be allocated.
      * @return The newly created image.
      * @script{create}
      */
-	static Image* create(unsigned int width, unsigned int height, Format format, unsigned char* data);
+	static Image* create(unsigned int width, unsigned int height, Format format, unsigned char* data = NULL);
 
     /**
      * Gets the image's raw pixel data.

+ 48 - 7
gameplay/src/lua/lua_FrameBuffer.cpp

@@ -32,10 +32,11 @@ void luaRegister_FrameBuffer()
     {
         {"bindDefault", lua_FrameBuffer_static_bindDefault},
         {"create", lua_FrameBuffer_static_create},
+        {"createScreenshot", lua_FrameBuffer_static_createScreenshot},
         {"getCurrent", lua_FrameBuffer_static_getCurrent},
-        {"getCurrentScreenshot", lua_FrameBuffer_static_getCurrentScreenshot},
         {"getFrameBuffer", lua_FrameBuffer_static_getFrameBuffer},
         {"getMaxRenderTargets", lua_FrameBuffer_static_getMaxRenderTargets},
+        {"getScreenshot", lua_FrameBuffer_static_getScreenshot},
         {NULL, NULL}
     };
     std::vector<std::string> scopePath;
@@ -761,7 +762,7 @@ int lua_FrameBuffer_static_create(lua_State* state)
     return 0;
 }
 
-int lua_FrameBuffer_static_getCurrent(lua_State* state)
+int lua_FrameBuffer_static_createScreenshot(lua_State* state)
 {
     // Get the number of parameters.
     int paramCount = lua_gettop(state);
@@ -771,13 +772,13 @@ int lua_FrameBuffer_static_getCurrent(lua_State* state)
     {
         case 0:
         {
-            void* returnPtr = (void*)FrameBuffer::getCurrent();
+            void* returnPtr = (void*)FrameBuffer::createScreenshot();
             if (returnPtr)
             {
                 gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
                 object->instance = returnPtr;
                 object->owns = false;
-                luaL_getmetatable(state, "FrameBuffer");
+                luaL_getmetatable(state, "Image");
                 lua_setmetatable(state, -2);
             }
             else
@@ -798,7 +799,7 @@ int lua_FrameBuffer_static_getCurrent(lua_State* state)
     return 0;
 }
 
-int lua_FrameBuffer_static_getCurrentScreenshot(lua_State* state)
+int lua_FrameBuffer_static_getCurrent(lua_State* state)
 {
     // Get the number of parameters.
     int paramCount = lua_gettop(state);
@@ -808,13 +809,13 @@ int lua_FrameBuffer_static_getCurrentScreenshot(lua_State* state)
     {
         case 0:
         {
-            void* returnPtr = (void*)FrameBuffer::getCurrentScreenshot();
+            void* returnPtr = (void*)FrameBuffer::getCurrent();
             if (returnPtr)
             {
                 gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
                 object->instance = returnPtr;
                 object->owns = false;
-                luaL_getmetatable(state, "Image");
+                luaL_getmetatable(state, "FrameBuffer");
                 lua_setmetatable(state, -2);
             }
             else
@@ -909,4 +910,44 @@ int lua_FrameBuffer_static_getMaxRenderTargets(lua_State* state)
     return 0;
 }
 
+int lua_FrameBuffer_static_getScreenshot(lua_State* state)
+{
+    // Get the number of parameters.
+    int paramCount = lua_gettop(state);
+
+    // Attempt to match the parameters to a valid binding.
+    switch (paramCount)
+    {
+        case 1:
+        {
+            if ((lua_type(state, 1) == LUA_TUSERDATA || lua_type(state, 1) == LUA_TTABLE || lua_type(state, 1) == LUA_TNIL))
+            {
+                // Get parameter 1 off the stack.
+                bool param1Valid;
+                gameplay::ScriptUtil::LuaArray<Image> param1 = gameplay::ScriptUtil::getObjectPointer<Image>(1, "Image", false, &param1Valid);
+                if (!param1Valid)
+                {
+                    lua_pushstring(state, "Failed to convert parameter 1 to type 'Image'.");
+                    lua_error(state);
+                }
+
+                FrameBuffer::getScreenshot(param1);
+                
+                return 0;
+            }
+
+            lua_pushstring(state, "lua_FrameBuffer_static_getScreenshot - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 }

+ 2 - 1
gameplay/src/lua/lua_FrameBuffer.h

@@ -21,10 +21,11 @@ int lua_FrameBuffer_setDepthStencilTarget(lua_State* state);
 int lua_FrameBuffer_setRenderTarget(lua_State* state);
 int lua_FrameBuffer_static_bindDefault(lua_State* state);
 int lua_FrameBuffer_static_create(lua_State* state);
+int lua_FrameBuffer_static_createScreenshot(lua_State* state);
 int lua_FrameBuffer_static_getCurrent(lua_State* state);
-int lua_FrameBuffer_static_getCurrentScreenshot(lua_State* state);
 int lua_FrameBuffer_static_getFrameBuffer(lua_State* state);
 int lua_FrameBuffer_static_getMaxRenderTargets(lua_State* state);
+int lua_FrameBuffer_static_getScreenshot(lua_State* state);
 
 void luaRegister_FrameBuffer();
 

+ 40 - 1
gameplay/src/lua/lua_Image.cpp

@@ -321,6 +321,45 @@ int lua_Image_static_create(lua_State* state)
             lua_error(state);
             break;
         }
+        case 3:
+        {
+            do
+            {
+                if (lua_type(state, 1) == LUA_TNUMBER &&
+                    lua_type(state, 2) == LUA_TNUMBER &&
+                    (lua_type(state, 3) == LUA_TSTRING || lua_type(state, 3) == LUA_TNIL))
+                {
+                    // Get parameter 1 off the stack.
+                    unsigned int param1 = (unsigned int)luaL_checkunsigned(state, 1);
+
+                    // Get parameter 2 off the stack.
+                    unsigned int param2 = (unsigned int)luaL_checkunsigned(state, 2);
+
+                    // Get parameter 3 off the stack.
+                    Image::Format param3 = (Image::Format)lua_enumFromString_ImageFormat(luaL_checkstring(state, 3));
+
+                    void* returnPtr = (void*)Image::create(param1, param2, param3);
+                    if (returnPtr)
+                    {
+                        gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject));
+                        object->instance = returnPtr;
+                        object->owns = true;
+                        luaL_getmetatable(state, "Image");
+                        lua_setmetatable(state, -2);
+                    }
+                    else
+                    {
+                        lua_pushnil(state);
+                    }
+
+                    return 1;
+                }
+            } while (0);
+
+            lua_pushstring(state, "lua_Image_static_create - Failed to match the given parameters to a valid function signature.");
+            lua_error(state);
+            break;
+        }
         case 4:
         {
             do
@@ -366,7 +405,7 @@ int lua_Image_static_create(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 1 or 4).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1, 3 or 4).");
             lua_error(state);
             break;
         }