From 4f0028050d5ac25b46295bd49902b8e051e9535f Mon Sep 17 00:00:00 2001 From: vrld Date: Thu, 8 Sep 2011 12:25:43 +0200 Subject: [PATCH] Fix issue #294 (really this time). Add stencil attachment to framebuffer creation. Needed to remove depth attachment to make it work, but that should not change anything, since depth test is not enabled anyway. May need testing nonetheless. --- src/modules/graphics/opengl/Canvas.cpp | 85 ++++++++++--------- src/modules/graphics/opengl/Canvas.h | 2 +- src/modules/graphics/opengl/wrap_Graphics.cpp | 3 - 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index 5d82d6637..ee5c07dcf 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -14,39 +14,44 @@ namespace opengl // strategy for fbo creation, interchangable at runtime: // none, opengl >= 3.0, extensions struct FramebufferStrategy { - /// create a new framebuffer, depthbuffer and texture + /// create a new framebuffer, stencilbuffer and texture /** - * @param[out] framebuffer Framebuffer name - * @param[out] depthbuffer Depthbuffer name - * @param[out] img Texture name - * @param[in] width Width of framebuffer - * @param[in] height Height of framebuffer + * @param[out] framebuffer Framebuffer name + * @param[out] stencilbuffer Stencilbuffer name + * @param[out] img Texture name + * @param[in] width Width of framebuffer + * @param[in] height Height of framebuffer * @return Creation status */ virtual GLenum createFBO(GLuint&, GLuint&, GLuint&, int, int) { return GL_FRAMEBUFFER_UNSUPPORTED; } /// remove objects /** - * @param[in] framebuffer Framebuffer name - * @param[in] depthbuffer Depthbuffer name - * @param[in] img Texture name + * @param[in] framebuffer Framebuffer name + * @param[in] stencilbuffer Stencilbuffer name + * @param[in] img Texture name */ virtual void deleteFBO(GLuint, GLuint, GLuint) {} virtual void bindFBO(GLuint) {} }; struct FramebufferStrategyGL3 : public FramebufferStrategy { - virtual GLenum createFBO(GLuint& framebuffer, GLuint& depthbuffer, GLuint& img, int width, int height) + virtual GLenum createFBO(GLuint& framebuffer, GLuint& stencilbuffer, GLuint& img, int width, int height) { // get currently bound fbo to reset to it later GLint current_fbo; glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); - // generate depth buffer - glGenRenderbuffers(1, &depthbuffer); - glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height); - glBindRenderbuffer(GL_RENDERBUFFER, 0); + // create framebuffer + glGenFramebuffers(1, &framebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); + + // create stencil buffer + glGenRenderbuffers(1, &stencilbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, stencilbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, + GL_RENDERBUFFER, stencilbuffer); // generate texture save target glGenTextures(1, &img); @@ -56,24 +61,21 @@ namespace opengl glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, 0); - - // create framebuffer - glGenFramebuffers(1, &framebuffer); - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, img, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, depthbuffer); + + // check status GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); // unbind framebuffer + glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, (GLuint)current_fbo); return status; } - virtual void deleteFBO(GLuint framebuffer, GLuint depthbuffer, GLuint img) + virtual void deleteFBO(GLuint framebuffer, GLuint stencilbuffer, GLuint img) { glDeleteTextures(1, &img); - glDeleteRenderbuffers(1, &depthbuffer); + glDeleteRenderbuffers(1, &stencilbuffer); glDeleteFramebuffers(1, &framebuffer); } @@ -85,16 +87,21 @@ namespace opengl struct FramebufferStrategyEXT : public FramebufferStrategy { - virtual GLenum createFBO(GLuint& framebuffer, GLuint& depthbuffer, GLuint& img, int width, int height) + virtual GLenum createFBO(GLuint& framebuffer, GLuint& stencilbuffer, GLuint& img, int width, int height) { GLint current_fbo; glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, ¤t_fbo); - // generate depth buffer - glGenRenderbuffersEXT(1, &depthbuffer); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, width, height); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + // create framebuffer + glGenFramebuffersEXT(1, &framebuffer); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer); + + // create stencil buffer + glGenRenderbuffersEXT(1, &stencilbuffer); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencilbuffer); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, width, height); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, stencilbuffer); // generate texture save target glGenTextures(1, &img); @@ -104,25 +111,22 @@ namespace opengl glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, 0); - - // create framebuffer - glGenFramebuffersEXT(1, &framebuffer); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, img, 0); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, - GL_RENDERBUFFER_EXT, depthbuffer); + + // check status GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); // unbind framebuffer + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (GLuint)current_fbo); return status; } - virtual void deleteFBO(GLuint framebuffer, GLuint depthbuffer, GLuint img) + virtual void deleteFBO(GLuint framebuffer, GLuint stencilbuffer, GLuint img) { glDeleteTextures(1, &img); - glDeleteRenderbuffersEXT(1, &depthbuffer); + glDeleteRenderbuffersEXT(1, &stencilbuffer); glDeleteFramebuffersEXT(1, &framebuffer); } @@ -213,9 +217,8 @@ namespace opengl current->stopGrab(); // bind buffer and clear screen - glPushAttrib(GL_VIEWPORT_BIT | GL_DEPTH_BUFFER_BIT | GL_TRANSFORM_BIT); + glPushAttrib(GL_VIEWPORT_BIT | GL_TRANSFORM_BIT); strategy->bindFBO(fbo); - glClear(GL_DEPTH_BUFFER_BIT); glViewport(0, 0, width, height); // Reset the projection matrix @@ -366,7 +369,7 @@ namespace opengl bool Canvas::loadVolatile() { - status = strategy->createFBO(fbo, depthbuffer, img, width, height); + status = strategy->createFBO(fbo, stencilbuffer, img, width, height); if (status != GL_FRAMEBUFFER_COMPLETE) return false; @@ -382,7 +385,7 @@ namespace opengl { settings.filter = getFilter(); settings.wrap = getWrap(); - strategy->deleteFBO(fbo, depthbuffer, img); + strategy->deleteFBO(fbo, stencilbuffer, img); } int Canvas::getWidth() diff --git a/src/modules/graphics/opengl/Canvas.h b/src/modules/graphics/opengl/Canvas.h index ae07ce9c7..0eb4be4f7 100644 --- a/src/modules/graphics/opengl/Canvas.h +++ b/src/modules/graphics/opengl/Canvas.h @@ -77,7 +77,7 @@ namespace opengl GLsizei width; GLsizei height; GLuint fbo; - GLuint depthbuffer; + GLuint stencilbuffer; GLuint img; vertex vertices[4]; diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index 6faaefb53..5d8668944 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -169,9 +169,6 @@ namespace opengl static int setStencil(lua_State * L, bool invert) { - // stencils require the default fb to work properly - Canvas::TemporaryUnbinder unbinder; - // no argument -> clear mask if (lua_isnoneornil(L, 1)) { instance->discardStencil();