Просмотр исходного кода

Merge branch 'helpful-additions-screenshot' into next

Rcmaniac25 12 лет назад
Родитель
Сommit
36429f943a

+ 18 - 0
gameplay/src/FrameBuffer.cpp

@@ -269,6 +269,24 @@ FrameBuffer* FrameBuffer::bind()
     return previousFrameBuffer;
 }
 
+Image* FrameBuffer::getCurrentScreenshot()
+{
+	//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.
+
+	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) );
+
+	Image* screenshot = Image::create(width, height, Image::RGBA, data);
+
+	SAFE_DELETE_ARRAY(data);
+
+	return screenshot;
+}
+
 FrameBuffer* FrameBuffer::bindDefault()
 {
     GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _defaultFrameBuffer->_handle) );

+ 8 - 0
gameplay/src/FrameBuffer.h

@@ -4,6 +4,7 @@
 #include "Base.h"
 #include "RenderTarget.h"
 #include "DepthStencilTarget.h"
+#include "Image.h"
 
 namespace gameplay
 {
@@ -151,6 +152,13 @@ public:
      */
     FrameBuffer* bind();
 
+	/**
+	 * Records a screenshot of what is stored on the current FrameBuffer.
+	 * 
+	 * @return A screenshot of the current framebuffer's content.
+	 */
+	static Image* getCurrentScreenshot();
+
     /**
      * Binds the default FrameBuffer for rendering to the display.
      *

+ 28 - 0
gameplay/src/Image.cpp

@@ -107,6 +107,34 @@ Image* Image::create(const char* path)
     return image;
 }
 
+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);
+
+	unsigned int pixelSize = 0;
+	switch(format)
+	{
+	case Image::RGB:
+		pixelSize = 3;
+		break;
+	case Image::RGBA:
+		pixelSize = 4;
+		break;
+	}
+
+	Image* image = new Image();
+
+	image->_width = width;
+	image->_height = height;
+	image->_format = format;
+	image->_data = new unsigned char[width * height * pixelSize];
+	memcpy(image->_data, data, width * height * pixelSize);
+
+	return image;
+}
+
 Image::Image()
 {
     // Unused

+ 12 - 0
gameplay/src/Image.h

@@ -31,6 +31,18 @@ public:
      */
     static Image* create(const char* path);
 
+	/**
+     * Creates an image from the data provided
+     * 
+     * @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.
+     * @return The newly created image.
+     * @script{create}
+     */
+	static Image* create(unsigned int width, unsigned int height, Format format, unsigned char* data);
+
     /**
      * Gets the image's raw pixel data.
      * 

+ 38 - 0
gameplay/src/lua/lua_FrameBuffer.cpp

@@ -33,6 +33,7 @@ void luaRegister_FrameBuffer()
         {"bindDefault", lua_FrameBuffer_static_bindDefault},
         {"create", lua_FrameBuffer_static_create},
         {"getCurrent", lua_FrameBuffer_static_getCurrent},
+        {"getCurrentScreenshot", lua_FrameBuffer_static_getCurrentScreenshot},
         {"getFrameBuffer", lua_FrameBuffer_static_getFrameBuffer},
         {"getMaxRenderTargets", lua_FrameBuffer_static_getMaxRenderTargets},
         {NULL, NULL}
@@ -797,6 +798,43 @@ int lua_FrameBuffer_static_getCurrent(lua_State* state)
     return 0;
 }
 
+int lua_FrameBuffer_static_getCurrentScreenshot(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 0:
+        {
+            void* returnPtr = (void*)FrameBuffer::getCurrentScreenshot();
+            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");
+                lua_setmetatable(state, -2);
+            }
+            else
+            {
+                lua_pushnil(state);
+            }
+
+            return 1;
+            break;
+        }
+        default:
+        {
+            lua_pushstring(state, "Invalid number of parameters (expected 0).");
+            lua_error(state);
+            break;
+        }
+    }
+    return 0;
+}
+
 int lua_FrameBuffer_static_getFrameBuffer(lua_State* state)
 {
     // Get the number of parameters.

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

@@ -22,6 +22,7 @@ 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_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);
 

+ 63 - 17
gameplay/src/lua/lua_Image.cpp

@@ -292,27 +292,73 @@ int lua_Image_static_create(lua_State* state)
     {
         case 1:
         {
-            if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
+            do
             {
-                // Get parameter 1 off the stack.
-                const char* param1 = gameplay::ScriptUtil::getString(1, false);
-
-                void* returnPtr = (void*)Image::create(param1);
-                if (returnPtr)
+                if ((lua_type(state, 1) == LUA_TSTRING || lua_type(state, 1) == LUA_TNIL))
                 {
-                    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);
+                    // Get parameter 1 off the stack.
+                    const char* param1 = gameplay::ScriptUtil::getString(1, false);
+
+                    void* returnPtr = (void*)Image::create(param1);
+                    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;
                 }
-                else
+            } 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
+            {
+                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) &&
+                    (lua_type(state, 4) == LUA_TTABLE || lua_type(state, 4) == LUA_TLIGHTUSERDATA))
                 {
-                    lua_pushnil(state);
+                    // 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));
+
+                    // Get parameter 4 off the stack.
+                    gameplay::ScriptUtil::LuaArray<unsigned char> param4 = gameplay::ScriptUtil::getUnsignedCharPointer(4);
+
+                    void* returnPtr = (void*)Image::create(param1, param2, param3, param4);
+                    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;
                 }
-
-                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);
@@ -320,7 +366,7 @@ int lua_Image_static_create(lua_State* state)
         }
         default:
         {
-            lua_pushstring(state, "Invalid number of parameters (expected 1).");
+            lua_pushstring(state, "Invalid number of parameters (expected 1 or 4).");
             lua_error(state);
             break;
         }