فهرست منبع

Updated FrameBuffer bind and bindDefault to return the previously bound framebuffer.

setaylor 13 سال پیش
والد
کامیت
30749eab2f
4فایلهای تغییر یافته به همراه73 افزوده شده و 46 حذف شده
  1. 11 11
      gameplay/src/Form.cpp
  2. 22 24
      gameplay/src/FrameBuffer.cpp
  3. 10 5
      gameplay/src/FrameBuffer.h
  4. 30 6
      gameplay/src/lua/lua_FrameBuffer.cpp

+ 11 - 11
gameplay/src/Form.cpp

@@ -233,7 +233,7 @@ void Form::setSize(float width, float height)
         _u2 = width / (float)w;
         _v1 = height / (float)h;
 
-        // Create framebuffer if necessary.
+        // Create framebuffer if necessary. TODO: Use pool to cache.
         if (_frameBuffer)
             SAFE_RELEASE(_frameBuffer)
         
@@ -250,16 +250,17 @@ void Form::setSize(float width, float height)
 
         // Clear the framebuffer black
         Game* game = Game::getInstance();
-        _frameBuffer->bind();
-        Rectangle prevViewport = game->getViewport();
+        FrameBuffer* previousFrameBuffer = _frameBuffer->bind();
+        Rectangle previousViewport = game->getViewport();
+
         game->setViewport(Rectangle(0, 0, width, height));
         _theme->setProjectionMatrix(_projectionMatrix);
         game->clear(Game::CLEAR_COLOR, Vector4::zero(), 1.0, 0);
         _theme->setProjectionMatrix(_defaultProjectionMatrix);
-        FrameBuffer::bindDefault();
-        game->setViewport(prevViewport);
+
+        previousFrameBuffer->bind();
+        game->setViewport(previousViewport);
     }
-    
     _bounds.width = width;
     _bounds.height = height;
     _dirty = true;
@@ -535,7 +536,7 @@ void Form::draw()
     if (isDirty())
     {
         GP_ASSERT(_frameBuffer);
-        _frameBuffer->bind();
+        FrameBuffer* previousFrameBuffer = _frameBuffer->bind();
 
         Game* game = Game::getInstance();
         Rectangle prevViewport = game->getViewport();
@@ -543,12 +544,11 @@ void Form::draw()
 
         GP_ASSERT(_theme);
         _theme->setProjectionMatrix(_projectionMatrix);
-        Container::draw(_theme->getSpriteBatch(), Rectangle(0, 0, _bounds.width, _bounds.height),
-                        true/*WAS _skin!=NULL*/, false, _bounds.height);
+        Container::draw(_theme->getSpriteBatch(), Rectangle(0, 0, _bounds.width, _bounds.height),  true/*WAS _skin!=NULL*/, false, _bounds.height);
         _theme->setProjectionMatrix(_defaultProjectionMatrix);
 
-        // Rebind the default framebuffer and game viewport.
-        FrameBuffer::bindDefault();
+        // Rebind the previous framebuffer and game viewport.
+        previousFrameBuffer->bind();
 
         // restore the previous game viewport
         game->setViewport(prevViewport);

+ 22 - 24
gameplay/src/FrameBuffer.cpp

@@ -4,17 +4,19 @@
 
 #include "Base.h"
 #include "FrameBuffer.h"
+#include "Game.h"
+
+#define FRAMEBUFFER_ID_DEFAULT "org.gameplay3d.framebuffer.default"
 
 namespace gameplay
 {
-
 static unsigned int __maxRenderTargets = 0;
 static std::vector<FrameBuffer*> __frameBuffers;
-static FrameBufferHandle __defaultHandle = 0;
-static FrameBufferHandle __currentHandle = 0;
+static FrameBuffer* __defaultFrameBuffer = NULL;
+static FrameBuffer* __currentFrameBuffer = NULL;
 
-FrameBuffer::FrameBuffer(const char* id, unsigned int width, unsigned int height) :
-    _id(id ? id : ""), _width(width), _height(height), _handle(0), 
+FrameBuffer::FrameBuffer(const char* id, unsigned int width, unsigned int height, FrameBufferHandle handle) :
+    _id(id ? id : ""), _width(width), _height(height), _handle(handle), 
     _renderTargets(NULL), _depthStencilTarget(NULL)
 {
 }
@@ -57,8 +59,8 @@ void FrameBuffer::initialize()
     // On many platforms this will simply be the zero (0) handle, but this is not always the case.
     GLint fbo;
     glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fbo);
-    __defaultHandle = (FrameBufferHandle)fbo;
-    __currentHandle = __defaultHandle;
+    __defaultFrameBuffer = new FrameBuffer(FRAMEBUFFER_ID_DEFAULT, 0, 0, (FrameBufferHandle)fbo);
+    __currentFrameBuffer = __defaultFrameBuffer;
 
     // Query the max supported color attachments. This glGet operation is not supported
     // on GL ES 2.x, so if the define does not exist, assume a value of 1.
@@ -96,8 +98,7 @@ FrameBuffer* FrameBuffer::create(const char* id, unsigned int width, unsigned in
     // Create the frame buffer
     GLuint handle = 0;
     GL_ASSERT( glGenFramebuffers(1, &handle) );
-    FrameBuffer* frameBuffer = new FrameBuffer(id, width, height);
-    frameBuffer->_handle = handle;
+    FrameBuffer* frameBuffer = new FrameBuffer(id, width, height, handle);
     
     // Create the render target array for the new frame buffer
     frameBuffer->_renderTargets = new RenderTarget*[__maxRenderTargets];
@@ -157,11 +158,9 @@ void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
     GP_ASSERT(index < __maxRenderTargets);
     GP_ASSERT(_renderTargets);
 
+    // No change
     if (_renderTargets[index] == target)
-    {
-        // No change.
         return;
-    }
 
     // Release our reference to the current RenderTarget at this index.
     SAFE_RELEASE(_renderTargets[index]);
@@ -186,8 +185,9 @@ void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
         }
 
         // Restore the FBO binding
-        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __currentHandle) );
+        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __currentFrameBuffer->_handle) );
     }
+
 }
 
 RenderTarget* FrameBuffer::getRenderTarget(unsigned int index) const
@@ -234,7 +234,7 @@ void FrameBuffer::setDepthStencilTarget(DepthStencilTarget* target)
         }
 
         // Restore the FBO binding
-        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __currentHandle) );
+        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __currentFrameBuffer->_handle) );
     }
 }
 
@@ -243,21 +243,19 @@ DepthStencilTarget* FrameBuffer::getDepthStencilTarget() const
     return _depthStencilTarget;
 }
 
-void FrameBuffer::bind()
+FrameBuffer* FrameBuffer::bind()
 {
-    // Bind this FrameBuffer for rendering.
     GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
-
-    // Update the current FBO handle
-    __currentHandle = _handle;
+    FrameBuffer* previousFrameBuffer = __currentFrameBuffer;
+    __currentFrameBuffer = this;
+    return previousFrameBuffer;
 }
 
-void FrameBuffer::bindDefault()
+FrameBuffer* FrameBuffer::bindDefault()
 {
-    GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __defaultHandle) );
-
-    // Update the current FBO handle
-    __currentHandle = __defaultHandle;
+    GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, __defaultFrameBuffer->_handle) );
+    __currentFrameBuffer = __defaultFrameBuffer;
+    return __defaultFrameBuffer;
 }
 
 

+ 10 - 5
gameplay/src/FrameBuffer.h

@@ -125,22 +125,27 @@ public:
     DepthStencilTarget* getDepthStencilTarget() const;
  
     /**
-     * Binds this FrameBuffer for off-screen rendering.
+     * Binds this FrameBuffer for off-screen rendering and return you the curently bound one.
+     *
+     * You should keep the return FrameBuffer and store it and call bind() when you rendering is complete.
+     *
+     * @ return The currently bound framebuffer.
      */
-    void bind();
+    FrameBuffer* bind();
 
     /**
      * Binds the default FrameBuffer for rendering to the display.
+     *
+     * @ return The default framebuffer.
      */
-    static void bindDefault(); 
+    static FrameBuffer* bindDefault(); 
      
 private:
 
-
     /**
      * Constructor.
      */
-    FrameBuffer(const char* id, unsigned int width, unsigned int height);
+    FrameBuffer(const char* id, unsigned int width, unsigned int height, FrameBufferHandle handle);
 
     /**
      * Destructor.

+ 30 - 6
gameplay/src/lua/lua_FrameBuffer.cpp

@@ -129,9 +129,21 @@ int lua_FrameBuffer_bind(lua_State* state)
             if ((lua_type(state, 1) == LUA_TUSERDATA))
             {
                 FrameBuffer* instance = getInstance(state);
-                instance->bind();
-                
-                return 0;
+                void* returnPtr = (void*)instance->bind();
+                if (returnPtr)
+                {
+                    ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                    object->instance = returnPtr;
+                    object->owns = false;
+                    luaL_getmetatable(state, "FrameBuffer");
+                    lua_setmetatable(state, -2);
+                }
+                else
+                {
+                    lua_pushnil(state);
+                }
+
+                return 1;
             }
 
             lua_pushstring(state, "lua_FrameBuffer_bind - Failed to match the given parameters to a valid function signature.");
@@ -560,9 +572,21 @@ int lua_FrameBuffer_static_bindDefault(lua_State* state)
     {
         case 0:
         {
-            FrameBuffer::bindDefault();
-            
-            return 0;
+            void* returnPtr = (void*)FrameBuffer::bindDefault();
+            if (returnPtr)
+            {
+                ScriptUtil::LuaObject* object = (ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(ScriptUtil::LuaObject));
+                object->instance = returnPtr;
+                object->owns = false;
+                luaL_getmetatable(state, "FrameBuffer");
+                lua_setmetatable(state, -2);
+            }
+            else
+            {
+                lua_pushnil(state);
+            }
+
+            return 1;
             break;
         }
         default: