From 86baa04a3bb3eac56d1e0c8f317db5cac3bd50f1 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Tue, 8 Feb 2011 05:54:05 +0000 Subject: [PATCH] - added FBO's for map preview rendering, which improves fps in the custom menu for video cards that support Frame Buffer Objects --- source/glest_game/graphics/renderer.cpp | 412 +++++++++--------- .../menu/menu_state_custom_game.cpp | 10 +- .../include/graphics/gl/texture_gl.h | 15 +- .../sources/graphics/gl/texture_gl.cpp | 264 ++++++----- 4 files changed, 372 insertions(+), 329 deletions(-) diff --git a/source/glest_game/graphics/renderer.cpp b/source/glest_game/graphics/renderer.cpp index 188be574..56b3759f 100644 --- a/source/glest_game/graphics/renderer.cpp +++ b/source/glest_game/graphics/renderer.cpp @@ -4391,17 +4391,20 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame, void Renderer::renderMapPreview( const MapPreview *map, bool renderAll, int screenPosX, int screenPosY, Texture2D **renderToTexture) { - float alt=0; - float showWater=0; - int renderMapHeight=64; - int renderMapWidth=64; - float cellSize=2; - float playerCrossSize=2; - float clientW=renderMapWidth*cellSize; - float clientH=renderMapHeight*cellSize;; + static bool supportFBOs = Texture2DGl().supports_FBO_RBO(); + //static bool supportFBOs = false; const Metrics &metrics= Metrics::getInstance(); + float alt = 0; + float showWater = 0; + int renderMapHeight = 64; + int renderMapWidth = 64; + float cellSize = 2; + float playerCrossSize = 2; + float clientW = renderMapWidth * cellSize; + float clientH = renderMapHeight * cellSize;; + // stretch small maps to 128x128 if(map->getW() < map->getH()) { cellSize = cellSize * renderMapHeight / map->getH(); @@ -4412,30 +4415,18 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll, assertGl(); -/* - if(renderToTexture != NULL) { + if(supportFBOs == true && renderToTexture != NULL) { Config &config= Config::getInstance(); Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter")); int maxAnisotropy = config.getInt("FilterMaxAnisotropy"); *renderToTexture = GraphicsInterface::getInstance().getFactory()->newTexture2D(); Texture2DGl *texture = static_cast(*renderToTexture); - //texture->setFormat(Texture::fAlpha); texture->setMipmap(false); Pixmap2D *pixmapScreenShot = texture->getPixmap(); - pixmapScreenShot->init(metrics.getVirtualW(), metrics.getVirtualH(), 3); - //pixmapScreenShot->init(map->getW(),map->getH(),3); - //pixmapScreenShot->init(200, 360, 3); + pixmapScreenShot->init(metrics.getVirtualW(), metrics.getVirtualH(), 4); texture->setForceCompressionDisabled(true); texture->init(textureFilter,maxAnisotropy); - - - //texture->initFrameBuffer(); - //texture->attachFrameBufferToTexture(); - - //texture->initRenderBuffer(); - //texture->attachRenderBuffer(); - texture->setup_FBO_RBO(); if(texture->checkFrameBufferStatus() == false) { @@ -4445,212 +4436,253 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll, *renderToTexture=NULL; } } -*/ + + if(supportFBOs == true && renderToTexture != NULL) { + cellSize =1; + clientW = metrics.getVirtualW(); + clientH = metrics.getVirtualH(); + int mapMaxDimensionSize = std::max(map->getW(),map->getH()); + switch(mapMaxDimensionSize) { + case 8: + cellSize = 96; + break; + case 16: + cellSize = 48; + break; + case 32: + cellSize = 24; + break; + case 64: + cellSize = 12; + break; + case 128: + cellSize = 6; + break; + case 256: + cellSize = 3; + break; + case 512: + cellSize = 2; + break; + } + } glFrontFace(GL_CW); glEnable(GL_CULL_FACE); - //glDisable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glPushMatrix(); - glLoadIdentity(); - //glViewport(screenPosX, screenPosY, metrics.getVirtualW(),metrics.getVirtualH()); - // glOrtho(0, clientW, 0, clientH, -1, 1); - //glOrtho(screenPosX, screenPosX+clientW, screenPosY+clientH, screenPosY, 0, 1); - glOrtho(0, metrics.getVirtualW(), 0, metrics.getVirtualH(), 0, 1); - //gluOrtho2D (0, metrics.getVirtualW(), 0, metrics.getVirtualH()); + GLint viewport[4]; // Where The original Viewport Values Will Be Stored - //glEnable( GL_SCISSOR_TEST ); - //glScissor(screenPosX, screenPosY,metrics.getVirtualW(), metrics.getVirtualH()); + if(supportFBOs == true && renderToTexture != NULL) { + glGetIntegerv(GL_VIEWPORT, viewport); + glOrtho(0, clientW, 0, clientH, 0, 1); + glViewport(0, 0, clientW, clientH); + } + else { + glOrtho(0, metrics.getVirtualW(), 0, metrics.getVirtualH(), 0, 1); + } glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - glTranslatef(static_cast(screenPosX),static_cast(screenPosY)-clientH,0.0f); - - //glEnable( GL_SCISSOR_TEST ); - //glScissor(screenPosX, screenPosY,screenPosX-clientW, screenPosY-clientH); - - //int newX = screenPosX - (metrics.getVirtualW() / 2); - //int newY = screenPosY - (metrics.getVirtualH() / 2); - //int newX = 0; - //int newY = 0; - //glTranslatef(static_cast(newX),static_cast(newY),0.0f); + if(supportFBOs == false || renderToTexture == NULL) { + glTranslatef(static_cast(screenPosX),static_cast(screenPosY)-clientH,0.0f); + } glPushAttrib(GL_CURRENT_BIT); - //glTranslatef(static_cast(x), static_cast(y), 0.0f); glLineWidth(1); - //glClear(GL_COLOR_BUFFER_BIT); glColor3f(0, 0, 0); for (int j = 0; j < map->getH(); j++) { for (int i = 0; i < map->getW(); i++) { - //surface - alt = map->getHeight(i, j) / 20.f; - showWater = map->getWaterLevel()/ 20.f - alt; - showWater = (showWater > 0)? showWater:0; - Vec3f surfColor; - switch (map->getSurface(i, j)) { - case st_Grass: - surfColor = Vec3f(0.0, 0.8f * alt, 0.f + showWater); - break; - case st_Secondary_Grass: - surfColor = Vec3f(0.4f * alt, 0.6f * alt, 0.f + showWater); - break; - case st_Road: - surfColor = Vec3f(0.6f * alt, 0.3f * alt, 0.f + showWater); - break; - case st_Stone: - surfColor = Vec3f(0.7f * alt, 0.7f * alt, 0.7f * alt + showWater); - break; - case st_Ground: - surfColor = Vec3f(0.7f * alt, 0.5f * alt, 0.3f * alt + showWater); - break; - } - - glColor3fv(surfColor.ptr()); - - glBegin(GL_TRIANGLE_STRIP); - glVertex2f(i * cellSize, clientH - j * cellSize - cellSize); - glVertex2f(i * cellSize, clientH - j * cellSize); - glVertex2f(i * cellSize + cellSize, clientH - j * cellSize - cellSize); - glVertex2f(i * cellSize + cellSize, clientH - j * cellSize); - glEnd(); - - //objects - if(renderAll == true) { - switch (map->getObject(i, j)) { - case 0: - glColor3f(0.f, 0.f, 0.f); + //surface + alt = map->getHeight(i, j) / 20.f; + showWater = map->getWaterLevel()/ 20.f - alt; + showWater = (showWater > 0)? showWater:0; + Vec3f surfColor; + switch (map->getSurface(i, j)) { + case st_Grass: + surfColor = Vec3f(0.0, 0.8f * alt, 0.f + showWater); break; - case 1: - glColor3f(1.f, 0.f, 0.f); + case st_Secondary_Grass: + surfColor = Vec3f(0.4f * alt, 0.6f * alt, 0.f + showWater); break; - case 2: - glColor3f(1.f, 1.f, 1.f); + case st_Road: + surfColor = Vec3f(0.6f * alt, 0.3f * alt, 0.f + showWater); break; - case 3: - glColor3f(0.5f, 0.5f, 1.f); + case st_Stone: + surfColor = Vec3f(0.7f * alt, 0.7f * alt, 0.7f * alt + showWater); break; - case 4: - glColor3f(0.f, 0.f, 1.f); + case st_Ground: + surfColor = Vec3f(0.7f * alt, 0.5f * alt, 0.3f * alt + showWater); break; - case 5: - glColor3f(0.5f, 0.5f, 0.5f); - break; - case 6: - glColor3f(1.f, 0.8f, 0.5f); - break; - case 7: - glColor3f(0.f, 1.f, 1.f); - break; - case 8: - glColor3f(0.7f, 0.1f, 0.3f); - break; - case 9: - glColor3f(0.5f, 1.f, 0.1f); - break; - case 10: - glColor3f(1.f, 0.2f, 0.8f); - break;// we don't render unvisible blocking objects } - if ( renderAll && (map->getObject(i, j) != 0) && (map->getObject(i, j) != 10) ) { - glPointSize(cellSize / 2.f); - glBegin(GL_POINTS); - glVertex2f(i * cellSize + cellSize / 2.f, clientH - j * cellSize - cellSize / 2.f); - glEnd(); - } - } + glColor3fv(surfColor.ptr()); -// bool found = false; + glBegin(GL_TRIANGLE_STRIP); + glVertex2f(i * cellSize, clientH - j * cellSize - cellSize); + glVertex2f(i * cellSize, clientH - j * cellSize); + glVertex2f(i * cellSize + cellSize, clientH - j * cellSize - cellSize); + glVertex2f(i * cellSize + cellSize, clientH - j * cellSize); + glEnd(); - //height lines -// if (!found) { - - //left - if (i > 0 && map->getHeight(i - 1, j) > map->getHeight(i, j)) { - glColor3fv((surfColor*0.5f).ptr()); - glBegin(GL_LINES); - glVertex2f(i * cellSize, clientH - (j + 1) * cellSize); - glVertex2f(i * cellSize, clientH - j * cellSize); - glEnd(); - } - //down - if (j > 0 && map->getHeight(i, j - 1) > map->getHeight(i, j)) { - glColor3fv((surfColor*0.5f).ptr()); - glBegin(GL_LINES); - glVertex2f(i * cellSize, clientH - j * cellSize); - glVertex2f((i + 1) * cellSize, clientH - j * cellSize); - glEnd(); - } - - - //left - if (i > 0 && map->getHeight(i - 1, j) < map->getHeight(i, j)) { - glColor3fv((surfColor*2.f).ptr()); - glBegin(GL_LINES); - glVertex2f(i * cellSize, clientH - (j + 1) * cellSize); - glVertex2f(i * cellSize, clientH - j * cellSize); - glEnd(); - } - if (j > 0 && map->getHeight(i, j - 1) < map->getHeight(i, j)) { - glColor3fv((surfColor*2.f).ptr()); - glBegin(GL_LINES); - glVertex2f(i * cellSize, clientH - j * cellSize); - glVertex2f((i + 1) * cellSize, clientH - j * cellSize); - glEnd(); - } -// } - - //resources + //objects if(renderAll == true) { - switch (map->getResource(i, j)) { - case 1: glColor3f(1.f, 1.f, 0.f); break; - case 2: glColor3f(0.5f, 0.5f, 0.5f); break; - case 3: glColor3f(1.f, 0.f, 0.f); break; - case 4: glColor3f(0.f, 0.f, 1.f); break; - case 5: glColor3f(0.5f, 0.5f, 1.f); break; + switch (map->getObject(i, j)) { + case 0: + glColor3f(0.f, 0.f, 0.f); + break; + case 1: + glColor3f(1.f, 0.f, 0.f); + break; + case 2: + glColor3f(1.f, 1.f, 1.f); + break; + case 3: + glColor3f(0.5f, 0.5f, 1.f); + break; + case 4: + glColor3f(0.f, 0.f, 1.f); + break; + case 5: + glColor3f(0.5f, 0.5f, 0.5f); + break; + case 6: + glColor3f(1.f, 0.8f, 0.5f); + break; + case 7: + glColor3f(0.f, 1.f, 1.f); + break; + case 8: + glColor3f(0.7f, 0.1f, 0.3f); + break; + case 9: + glColor3f(0.5f, 1.f, 0.1f); + break; + case 10: + glColor3f(1.f, 0.2f, 0.8f); + break;// we don't render unvisible blocking objects } - if (renderAll && map->getResource(i, j) != 0) { - glBegin(GL_LINES); - glVertex2f(i * cellSize, clientH - j * cellSize - cellSize); - glVertex2f(i * cellSize + cellSize, clientH - j * cellSize); - glVertex2f(i * cellSize, clientH - j * cellSize); - glVertex2f(i * cellSize + cellSize, clientH - j * cellSize - cellSize); + if ( renderAll && (map->getObject(i, j) != 0) && (map->getObject(i, j) != 10) ) { + glPointSize(cellSize / 2.f); + glBegin(GL_POINTS); + glVertex2f(i * cellSize + cellSize / 2.f, clientH - j * cellSize - cellSize / 2.f); glEnd(); } } - } + // bool found = false; + + //height lines + // if (!found) { + + //left + if (i > 0 && map->getHeight(i - 1, j) > map->getHeight(i, j)) { + glColor3fv((surfColor*0.5f).ptr()); + glBegin(GL_LINES); + glVertex2f(i * cellSize, clientH - (j + 1) * cellSize); + glVertex2f(i * cellSize, clientH - j * cellSize); + glEnd(); + } + //down + if (j > 0 && map->getHeight(i, j - 1) > map->getHeight(i, j)) { + glColor3fv((surfColor*0.5f).ptr()); + glBegin(GL_LINES); + glVertex2f(i * cellSize, clientH - j * cellSize); + glVertex2f((i + 1) * cellSize, clientH - j * cellSize); + glEnd(); + } + + + //left + if (i > 0 && map->getHeight(i - 1, j) < map->getHeight(i, j)) { + glColor3fv((surfColor*2.f).ptr()); + glBegin(GL_LINES); + glVertex2f(i * cellSize, clientH - (j + 1) * cellSize); + glVertex2f(i * cellSize, clientH - j * cellSize); + glEnd(); + } + if (j > 0 && map->getHeight(i, j - 1) < map->getHeight(i, j)) { + glColor3fv((surfColor*2.f).ptr()); + glBegin(GL_LINES); + glVertex2f(i * cellSize, clientH - j * cellSize); + glVertex2f((i + 1) * cellSize, clientH - j * cellSize); + glEnd(); + } + // } + + //resources + if(renderAll == true) { + switch (map->getResource(i, j)) { + case 1: glColor3f(1.f, 1.f, 0.f); break; + case 2: glColor3f(0.5f, 0.5f, 0.5f); break; + case 3: glColor3f(1.f, 0.f, 0.f); break; + case 4: glColor3f(0.f, 0.f, 1.f); break; + case 5: glColor3f(0.5f, 0.5f, 1.f); break; + } + + if (renderAll && map->getResource(i, j) != 0) { + glBegin(GL_LINES); + glVertex2f(i * cellSize, clientH - j * cellSize - cellSize); + glVertex2f(i * cellSize + cellSize, clientH - j * cellSize); + glVertex2f(i * cellSize, clientH - j * cellSize); + glVertex2f(i * cellSize + cellSize, clientH - j * cellSize - cellSize); + glEnd(); + } + } + } } //start locations glLineWidth(3); - // force playerCrossSize to be at least of size 4 - if(cellSize < 4) { - playerCrossSize = 4; + if(supportFBOs == true && renderToTexture != NULL) { + glLineWidth(14); + playerCrossSize = 24; } else { - playerCrossSize = cellSize; + // force playerCrossSize to be at least of size 4 + if(cellSize < 4) { + playerCrossSize = 4; + } + else { + playerCrossSize = cellSize; + } } for (int i = 0; i < map->getMaxFactions(); i++) { switch (i) { - case 0: glColor3f(1.f, 0.f, 0.f); break; - case 1: glColor3f(0.f, 0.f, 1.f); break; - case 2: glColor3f(0.f, 1.f, 0.f); break; - case 3: glColor3f(1.f, 1.f, 0.f); break; - case 4: glColor3f(1.f, 1.f, 1.f); break; - case 5: glColor3f(0.f, 1.f, 0.8f); break; - case 6: glColor3f(1.f, 0.5f, 0.f); break; - case 7: glColor3f(1.f, 0.5f, 1.f); break; + case 0: + glColor3f(1.f, 0.f, 0.f); + break; + case 1: + glColor3f(0.f, 0.f, 1.f); + break; + case 2: + glColor3f(0.f, 1.f, 0.f); + break; + case 3: + glColor3f(1.f, 1.f, 0.f); + break; + case 4: + glColor3f(1.f, 1.f, 1.f); + break; + case 5: + glColor3f(0.f, 1.f, 0.8f); + break; + case 6: + glColor3f(1.f, 0.5f, 0.f); + break; + case 7: + glColor3f(1.f, 0.5f, 1.f); + break; } glBegin(GL_LINES); glVertex2f((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) - 1) * cellSize); @@ -4665,29 +4697,15 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll, glMatrixMode(GL_PROJECTION); glPopMatrix(); - //glDisable( GL_SCISSOR_TEST ); - //glViewport(0, 0, 0, 0); - - if(renderToTexture != NULL) { - - // *renderToTexture = saveScreenToTexture(screenPosX, screenPosY, metrics.getVirtualW(), metrics.getVirtualH()); - // *renderToTexture = saveScreenToTexture(0, 0, metrics.getVirtualW(), metrics.getVirtualH()); -/* + if(supportFBOs == true && renderToTexture != NULL) { Texture2DGl *texture = static_cast(*renderToTexture); if(texture != NULL) { - // *renderToTexture = saveScreenToTexture(screenPosX, screenPosY, clientW, clientH); texture->dettachFrameBufferFromTexture(); - - // Signal the threads queue to add a screenshot save request - // MutexSafeWrapper safeMutex(&saveScreenShotThreadAccessor); - // saveScreenQueue.push_back(make_pair("bob.png",texture->getPixmap())); - // *renderToTexture=NULL; - // safeMutex.ReleaseLock(); - - // texture->teardown_FBO_RBO(); } -*/ + + glViewport(viewport[0], viewport[1], viewport[2], viewport[3]); } + assertGl(); } diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index bbcb3a03..5181d634 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -674,6 +674,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){ else if (listBoxAdvanced.getSelectedItemIndex() == 1 && listBoxFogOfWar.mouseClick(x, y)) { MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); + cleanupMapPreviewTexture(); if(listBoxPublishServer.getSelectedItemIndex() == 0) { needToRepublishToMasterserver = true; } @@ -1213,8 +1214,7 @@ void MenuStateCustomGame::render() { renderer.renderTextureQuad(800,600,200,150,factionTexture,0.7f); } if(mapPreviewTexture != NULL) { - //renderer.renderTextureQuad(10,350,-1,-1,mapPreviewTexture,0.7); - renderer.renderTextureQuad(800,300,200,150,mapPreviewTexture,0.7f); + renderer.renderTextureQuad(5,165,180,180,mapPreviewTexture,1.0f); //printf("=================> Rendering map preview texture\n"); } @@ -1349,9 +1349,9 @@ void MenuStateCustomGame::render() { renderer.renderMapPreview(&mapPreview, renderAll, 10, 350,&mapPreviewTexture); //printf("=================> Rendering map preview into a texture AFTER (%p)\n", mapPreviewTexture); } - else { - renderer.renderMapPreview(&mapPreview, renderAll, 10, 350); - } + //else { + //renderer.renderMapPreview(&mapPreview, renderAll, 10, 350); + //} } if(hasNetworkGameSettings() == true) { diff --git a/source/shared_lib/include/graphics/gl/texture_gl.h b/source/shared_lib/include/graphics/gl/texture_gl.h index 8e125285..92aa8d3b 100644 --- a/source/shared_lib/include/graphics/gl/texture_gl.h +++ b/source/shared_lib/include/graphics/gl/texture_gl.h @@ -28,6 +28,10 @@ protected: GLuint renderBufferId; GLuint frameBufferId; + void initRenderBuffer(); + void initFrameBuffer(); + void attachRenderBuffer(); + public: TextureGl(); virtual ~TextureGl(); @@ -36,14 +40,11 @@ public: GLuint getRenderBufferHandle() const {return renderBufferId;} GLuint getFrameBufferHandle() const {return frameBufferId;} - void initRenderBuffer(); - void initFrameBuffer(); - void attachRenderBuffer(); - void attachFrameBufferToTexture(); - bool checkFrameBufferStatus(); - void dettachFrameBufferFromTexture(); - + bool supports_FBO_RBO(); void setup_FBO_RBO(); + void attachFrameBufferToTexture(); + void dettachFrameBufferFromTexture(); + bool checkFrameBufferStatus(); void teardown_FBO_RBO(); virtual int getTextureWidth() const = 0; diff --git a/source/shared_lib/sources/graphics/gl/texture_gl.cpp b/source/shared_lib/sources/graphics/gl/texture_gl.cpp index 4d332a5b..c57c91d1 100644 --- a/source/shared_lib/sources/graphics/gl/texture_gl.cpp +++ b/source/shared_lib/sources/graphics/gl/texture_gl.cpp @@ -21,11 +21,39 @@ using namespace std; +// Define FBO's (Frame Buffer Objects) for win32 + +#ifdef WIN32 + +PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT; +PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT; +PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT; +PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT; +PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT; + +#endif + namespace Shared { namespace Graphics { namespace Gl { using namespace Platform; using namespace Shared::Util; +void setupGLExtensionMethods() { +#ifdef WIN32 + + static bool setupExtensions=true; + if(setupExtensions == true) { + setupExtensions = false; + glGenFramebuffersEXT= (PFNGLGENFRAMEBUFFERSEXTPROC)SDL_GL_GetProcAddress("glGenFramebuffersEXT"); + glBindFramebufferEXT= (PFNGLBINDFRAMEBUFFEREXTPROC)SDL_GL_GetProcAddress("glBindFramebufferEXT"); + glFramebufferTexture2DEXT= (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)SDL_GL_GetProcAddress("glFramebufferTexture2DEXT"); + glDeleteFramebuffersEXT = (PFNGLDELETEFRAMEBUFFERSEXTPROC)SDL_GL_GetProcAddress("glDeleteFramebuffersEXT"); + glCheckFramebufferStatusEXT= (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT"); + } + +#endif +} + const uint64 MIN_BYTES_TO_COMPRESS = 12; static std::string getSupportCompressedTextureFormatString(int format) { @@ -425,6 +453,11 @@ TextureGl::TextureGl() { handle = 0; renderBufferId = 0; frameBufferId = 0; + setupGLExtensionMethods(); +} + +bool TextureGl::supports_FBO_RBO() { + return (glGenFramebuffersEXT != NULL); } void TextureGl::setup_FBO_RBO() { @@ -432,158 +465,149 @@ void TextureGl::setup_FBO_RBO() { throw runtime_error("getTextureWidth() < 0 || getTextureHeight() < 0"); } - SystemFlags::OutputDebug(SystemFlags::debugSystem,"getTextureWidth() = %d, getTextureHeight() = %d\n",getTextureWidth(),getTextureHeight()); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"getTextureWidth() = %d, getTextureHeight() = %d\n",getTextureWidth(),getTextureHeight()); -// Need some work to get extensions properly working in Windows (use Glew lib) -#ifndef WIN32 + // Need some work to get extensions properly working in Windows (use Glew lib) + // Did we successfully setup FBO's? + if(glGenFramebuffersEXT) { + GLint width=0; + glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&width); + GLint height=0; + glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&height); - GLint width=0; - glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&width); - GLint height=0; - glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&height); + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"width = %d, height = %d\n",width,height); - SystemFlags::OutputDebug(SystemFlags::debugSystem,"width = %d, height = %d\n",width,height); - - //RGBA8 2D texture, 24 bit depth texture, 256x256 - //glGenTextures(1, &color_tex); - //glBindTexture(GL_TEXTURE_2D, color_tex); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - //NULL means reserve texture memory, but texels are undefined - //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); - //------------------------- - glGenFramebuffersEXT(1, &frameBufferId); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); - //Attach 2D texture to this FBO - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, handle, 0); - //------------------------- - glGenRenderbuffersEXT(1, &renderBufferId); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, getTextureWidth(), getTextureHeight()); - //------------------------- - //Attach depth buffer to FBO - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderBufferId); - //------------------------- - //Does the GPU support current FBO configuration? - GLenum status; - status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - switch(status) - { - case GL_FRAMEBUFFER_COMPLETE_EXT: - SystemFlags::OutputDebug(SystemFlags::debugSystem,"FBO attachment OK!\n"); - break; - default: - SystemFlags::OutputDebug(SystemFlags::debugSystem,"FBO attachment BAD!\n"); - break; + //RGBA8 2D texture, 24 bit depth texture, 256x256 + //glGenTextures(1, &color_tex); + //glBindTexture(GL_TEXTURE_2D, color_tex); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + //NULL means reserve texture memory, but texels are undefined + //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); + //------------------------- + glGenFramebuffersEXT(1, &frameBufferId); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); + //Attach 2D texture to this FBO + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, handle, 0); + //------------------------- + glGenRenderbuffersEXT(1, &renderBufferId); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, getTextureWidth(), getTextureHeight()); + //------------------------- + //Attach depth buffer to FBO + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderBufferId); + //------------------------- + //Does the GPU support current FBO configuration? + GLenum status; + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + switch(status) + { + case GL_FRAMEBUFFER_COMPLETE_EXT: + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"FBO attachment OK!\n"); + break; + default: + //SystemFlags::OutputDebug(SystemFlags::debugSystem,"FBO attachment BAD!\n"); + break; + } + //------------------------- + //and now you can render to GL_TEXTURE_2D + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } - //------------------------- - //and now you can render to GL_TEXTURE_2D - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - -#endif } void TextureGl::teardown_FBO_RBO() { -// Need some work to get extensions properly working in Windows (use Glew lib) -#ifndef WIN32 - - //---------------- - //Bind 0, which means render to back buffer - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - //And in the end, cleanup - //Delete resources - //glDeleteTextures(1, &handle); - glDeleteRenderbuffersEXT(1, &frameBufferId); - //Bind 0, which means render to back buffer, as a result, fb is unbound - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - glDeleteFramebuffersEXT(1, &frameBufferId); -#endif + // Need some work to get extensions properly working in Windows (use Glew lib) + if(glGenFramebuffersEXT) { + //---------------- + //Bind 0, which means render to back buffer + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + //And in the end, cleanup + //Delete resources + //glDeleteTextures(1, &handle); + glDeleteRenderbuffersEXT(1, &frameBufferId); + //Bind 0, which means render to back buffer, as a result, fb is unbound + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glDeleteFramebuffersEXT(1, &frameBufferId); + } } void TextureGl::initRenderBuffer() { -// Need some work to get extensions properly working in Windows (use Glew lib) -#ifndef WIN32 - - // create a renderbuffer object to store depth info - glGenRenderbuffersEXT(1, &renderBufferId); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,getTextureWidth(), getTextureHeight()); - //glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); -#endif + // Need some work to get extensions properly working in Windows (use Glew lib) + if(glGenFramebuffersEXT) { + // create a renderbuffer object to store depth info + glGenRenderbuffersEXT(1, &renderBufferId); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,getTextureWidth(), getTextureHeight()); + //glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } } void TextureGl::initFrameBuffer() { -// Need some work to get extensions properly working in Windows (use Glew lib) -#ifndef WIN32 - // create a framebuffer object - glGenFramebuffersEXT(1, &frameBufferId); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); -#endif + // Need some work to get extensions properly working in Windows (use Glew lib) + if(glGenFramebuffersEXT) { + // create a framebuffer object + glGenFramebuffersEXT(1, &frameBufferId); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); +} } void TextureGl::attachRenderBuffer() { -// Need some work to get extensions properly working in Windows (use Glew lib) -#ifndef WIN32 - // attach the renderbuffer to depth attachment point - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, renderBufferId); -#endif + // Need some work to get extensions properly working in Windows (use Glew lib) + if(glGenFramebuffersEXT) { + // attach the renderbuffer to depth attachment point + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, renderBufferId); +} } void TextureGl::attachFrameBufferToTexture() { -// Need some work to get extensions properly working in Windows (use Glew lib) -#ifndef WIN32 - // attach the texture to FBO color attachment point - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, handle, 0); -#endif + // Need some work to get extensions properly working in Windows (use Glew lib) + if(glGenFramebuffersEXT) { + // attach the texture to FBO color attachment point + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, handle, 0); +} } bool TextureGl::checkFrameBufferStatus() { -// Need some work to get extensions properly working in Windows (use Glew lib) -#ifndef WIN32 - - // check FBO status - // Does the GPU support current FBO configuration? - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if(status != GL_FRAMEBUFFER_COMPLETE_EXT) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"checkFrameBufferStatus() status = %d [%X]\n",status,status); - return false; + // Need some work to get extensions properly working in Windows (use Glew lib) + if(glGenFramebuffersEXT) { + // check FBO status + // Does the GPU support current FBO configuration? + GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if(status != GL_FRAMEBUFFER_COMPLETE_EXT) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"checkFrameBufferStatus() status = %d [%X]\n",status,status); + return false; + } + return true; } - return true; -#else return false; -#endif } void TextureGl::dettachFrameBufferFromTexture() { -// Need some work to get extensions properly working in Windows (use Glew lib) -#ifndef WIN32 - - // switch back to window-system-provided framebuffer - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); -#endif + // Need some work to get extensions properly working in Windows (use Glew lib) + if(glGenFramebuffersEXT) { + // switch back to window-system-provided framebuffer + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } } TextureGl::~TextureGl() { -// Need some work to get extensions properly working in Windows (use Glew lib) -#ifndef WIN32 - - if(renderBufferId != 0) { - glDeleteRenderbuffersEXT(1, &renderBufferId); - renderBufferId = 0; + // Need some work to get extensions properly working in Windows (use Glew lib) + if(glGenFramebuffersEXT) { + if(renderBufferId != 0) { + glDeleteRenderbuffersEXT(1, &renderBufferId); + renderBufferId = 0; + } + if(frameBufferId != 0) { + glDeleteFramebuffersEXT(1, &frameBufferId); + frameBufferId = 0; + } + //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); } - if(frameBufferId != 0) { - glDeleteFramebuffersEXT(1, &frameBufferId); - frameBufferId = 0; - } - - //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - -#endif } // =====================================================