- added FBO's for map preview rendering, which improves fps in the custom menu for video cards that support Frame Buffer Objects

This commit is contained in:
Mark Vejvoda 2011-02-08 05:54:05 +00:00
parent dd75518af0
commit 86baa04a3b
4 changed files with 372 additions and 329 deletions

View File

@ -4391,17 +4391,20 @@ VisibleQuadContainerCache & Renderer::getQuadCache( bool updateOnDirtyFrame,
void Renderer::renderMapPreview( const MapPreview *map, bool renderAll, void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
int screenPosX, int screenPosY, int screenPosX, int screenPosY,
Texture2D **renderToTexture) { 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(); 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 // stretch small maps to 128x128
if(map->getW() < map->getH()) { if(map->getW() < map->getH()) {
cellSize = cellSize * renderMapHeight / map->getH(); cellSize = cellSize * renderMapHeight / map->getH();
@ -4412,30 +4415,18 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
assertGl(); assertGl();
/* if(supportFBOs == true && renderToTexture != NULL) {
if(renderToTexture != NULL) {
Config &config= Config::getInstance(); Config &config= Config::getInstance();
Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter")); Texture2D::Filter textureFilter = strToTextureFilter(config.getString("Filter"));
int maxAnisotropy = config.getInt("FilterMaxAnisotropy"); int maxAnisotropy = config.getInt("FilterMaxAnisotropy");
*renderToTexture = GraphicsInterface::getInstance().getFactory()->newTexture2D(); *renderToTexture = GraphicsInterface::getInstance().getFactory()->newTexture2D();
Texture2DGl *texture = static_cast<Texture2DGl *>(*renderToTexture); Texture2DGl *texture = static_cast<Texture2DGl *>(*renderToTexture);
//texture->setFormat(Texture::fAlpha);
texture->setMipmap(false); texture->setMipmap(false);
Pixmap2D *pixmapScreenShot = texture->getPixmap(); Pixmap2D *pixmapScreenShot = texture->getPixmap();
pixmapScreenShot->init(metrics.getVirtualW(), metrics.getVirtualH(), 3); pixmapScreenShot->init(metrics.getVirtualW(), metrics.getVirtualH(), 4);
//pixmapScreenShot->init(map->getW(),map->getH(),3);
//pixmapScreenShot->init(200, 360, 3);
texture->setForceCompressionDisabled(true); texture->setForceCompressionDisabled(true);
texture->init(textureFilter,maxAnisotropy); texture->init(textureFilter,maxAnisotropy);
//texture->initFrameBuffer();
//texture->attachFrameBufferToTexture();
//texture->initRenderBuffer();
//texture->attachRenderBuffer();
texture->setup_FBO_RBO(); texture->setup_FBO_RBO();
if(texture->checkFrameBufferStatus() == false) { if(texture->checkFrameBufferStatus() == false) {
@ -4445,212 +4436,253 @@ void Renderer::renderMapPreview( const MapPreview *map, bool renderAll,
*renderToTexture=NULL; *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); glFrontFace(GL_CW);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
//glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
//glViewport(screenPosX, screenPosY, metrics.getVirtualW(),metrics.getVirtualH());
// glOrtho(0, clientW, 0, clientH, -1, 1);
//glOrtho(screenPosX, screenPosX+clientW, screenPosY+clientH, screenPosY, 0, 1); GLint viewport[4]; // Where The original Viewport Values Will Be Stored
glOrtho(0, metrics.getVirtualW(), 0, metrics.getVirtualH(), 0, 1);
//gluOrtho2D (0, metrics.getVirtualW(), 0, metrics.getVirtualH());
//glEnable( GL_SCISSOR_TEST ); if(supportFBOs == true && renderToTexture != NULL) {
//glScissor(screenPosX, screenPosY,metrics.getVirtualW(), metrics.getVirtualH()); 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); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
glTranslatef(static_cast<float>(screenPosX),static_cast<float>(screenPosY)-clientH,0.0f); if(supportFBOs == false || renderToTexture == NULL) {
glTranslatef(static_cast<float>(screenPosX),static_cast<float>(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<float>(newX),static_cast<float>(newY),0.0f);
glPushAttrib(GL_CURRENT_BIT); glPushAttrib(GL_CURRENT_BIT);
//glTranslatef(static_cast<float>(x), static_cast<float>(y), 0.0f);
glLineWidth(1); glLineWidth(1);
//glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0, 0, 0); glColor3f(0, 0, 0);
for (int j = 0; j < map->getH(); j++) { for (int j = 0; j < map->getH(); j++) {
for (int i = 0; i < map->getW(); i++) { for (int i = 0; i < map->getW(); i++) {
//surface //surface
alt = map->getHeight(i, j) / 20.f; alt = map->getHeight(i, j) / 20.f;
showWater = map->getWaterLevel()/ 20.f - alt; showWater = map->getWaterLevel()/ 20.f - alt;
showWater = (showWater > 0)? showWater:0; showWater = (showWater > 0)? showWater:0;
Vec3f surfColor; Vec3f surfColor;
switch (map->getSurface(i, j)) { switch (map->getSurface(i, j)) {
case st_Grass: case st_Grass:
surfColor = Vec3f(0.0, 0.8f * alt, 0.f + showWater); 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);
break; break;
case 1: case st_Secondary_Grass:
glColor3f(1.f, 0.f, 0.f); surfColor = Vec3f(0.4f * alt, 0.6f * alt, 0.f + showWater);
break; break;
case 2: case st_Road:
glColor3f(1.f, 1.f, 1.f); surfColor = Vec3f(0.6f * alt, 0.3f * alt, 0.f + showWater);
break; break;
case 3: case st_Stone:
glColor3f(0.5f, 0.5f, 1.f); surfColor = Vec3f(0.7f * alt, 0.7f * alt, 0.7f * alt + showWater);
break; break;
case 4: case st_Ground:
glColor3f(0.f, 0.f, 1.f); surfColor = Vec3f(0.7f * alt, 0.5f * alt, 0.3f * alt + showWater);
break; 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) ) { glColor3fv(surfColor.ptr());
glPointSize(cellSize / 2.f);
glBegin(GL_POINTS);
glVertex2f(i * cellSize + cellSize / 2.f, clientH - j * cellSize - cellSize / 2.f);
glEnd();
}
}
// 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 //objects
// 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) { if(renderAll == true) {
switch (map->getResource(i, j)) { switch (map->getObject(i, j)) {
case 1: glColor3f(1.f, 1.f, 0.f); break; case 0:
case 2: glColor3f(0.5f, 0.5f, 0.5f); break; glColor3f(0.f, 0.f, 0.f);
case 3: glColor3f(1.f, 0.f, 0.f); break; break;
case 4: glColor3f(0.f, 0.f, 1.f); break; case 1:
case 5: glColor3f(0.5f, 0.5f, 1.f); break; 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) { if ( renderAll && (map->getObject(i, j) != 0) && (map->getObject(i, j) != 10) ) {
glBegin(GL_LINES); glPointSize(cellSize / 2.f);
glVertex2f(i * cellSize, clientH - j * cellSize - cellSize); glBegin(GL_POINTS);
glVertex2f(i * cellSize + cellSize, clientH - j * cellSize); glVertex2f(i * cellSize + cellSize / 2.f, clientH - j * cellSize - cellSize / 2.f);
glVertex2f(i * cellSize, clientH - j * cellSize);
glVertex2f(i * cellSize + cellSize, clientH - j * cellSize - cellSize);
glEnd(); 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 //start locations
glLineWidth(3); glLineWidth(3);
// force playerCrossSize to be at least of size 4 if(supportFBOs == true && renderToTexture != NULL) {
if(cellSize < 4) { glLineWidth(14);
playerCrossSize = 4; playerCrossSize = 24;
} }
else { 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++) { for (int i = 0; i < map->getMaxFactions(); i++) {
switch (i) { switch (i) {
case 0: glColor3f(1.f, 0.f, 0.f); break; case 0:
case 1: glColor3f(0.f, 0.f, 1.f); break; glColor3f(1.f, 0.f, 0.f);
case 2: glColor3f(0.f, 1.f, 0.f); break; break;
case 3: glColor3f(1.f, 1.f, 0.f); break; case 1:
case 4: glColor3f(1.f, 1.f, 1.f); break; glColor3f(0.f, 0.f, 1.f);
case 5: glColor3f(0.f, 1.f, 0.8f); break; break;
case 6: glColor3f(1.f, 0.5f, 0.f); break; case 2:
case 7: glColor3f(1.f, 0.5f, 1.f); break; 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); glBegin(GL_LINES);
glVertex2f((map->getStartLocationX(i) - 1) * cellSize, clientH - (map->getStartLocationY(i) - 1) * cellSize); 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); glMatrixMode(GL_PROJECTION);
glPopMatrix(); glPopMatrix();
//glDisable( GL_SCISSOR_TEST ); if(supportFBOs == true && renderToTexture != NULL) {
//glViewport(0, 0, 0, 0);
if(renderToTexture != NULL) {
// *renderToTexture = saveScreenToTexture(screenPosX, screenPosY, metrics.getVirtualW(), metrics.getVirtualH());
// *renderToTexture = saveScreenToTexture(0, 0, metrics.getVirtualW(), metrics.getVirtualH());
/*
Texture2DGl *texture = static_cast<Texture2DGl *>(*renderToTexture); Texture2DGl *texture = static_cast<Texture2DGl *>(*renderToTexture);
if(texture != NULL) { if(texture != NULL) {
// *renderToTexture = saveScreenToTexture(screenPosX, screenPosY, clientW, clientH);
texture->dettachFrameBufferFromTexture(); 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(); assertGl();
} }

View File

@ -674,6 +674,7 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){
else if (listBoxAdvanced.getSelectedItemIndex() == 1 && listBoxFogOfWar.mouseClick(x, y)) { else if (listBoxAdvanced.getSelectedItemIndex() == 1 && listBoxFogOfWar.mouseClick(x, y)) {
MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__)); MutexSafeWrapper safeMutex((publishToMasterserverThread != NULL ? publishToMasterserverThread->getMutexThreadObjectAccessor() : NULL),string(__FILE__) + "_" + intToStr(__LINE__));
cleanupMapPreviewTexture();
if(listBoxPublishServer.getSelectedItemIndex() == 0) { if(listBoxPublishServer.getSelectedItemIndex() == 0) {
needToRepublishToMasterserver = true; needToRepublishToMasterserver = true;
} }
@ -1213,8 +1214,7 @@ void MenuStateCustomGame::render() {
renderer.renderTextureQuad(800,600,200,150,factionTexture,0.7f); renderer.renderTextureQuad(800,600,200,150,factionTexture,0.7f);
} }
if(mapPreviewTexture != NULL) { if(mapPreviewTexture != NULL) {
//renderer.renderTextureQuad(10,350,-1,-1,mapPreviewTexture,0.7); renderer.renderTextureQuad(5,165,180,180,mapPreviewTexture,1.0f);
renderer.renderTextureQuad(800,300,200,150,mapPreviewTexture,0.7f);
//printf("=================> Rendering map preview texture\n"); //printf("=================> Rendering map preview texture\n");
} }
@ -1349,9 +1349,9 @@ void MenuStateCustomGame::render() {
renderer.renderMapPreview(&mapPreview, renderAll, 10, 350,&mapPreviewTexture); renderer.renderMapPreview(&mapPreview, renderAll, 10, 350,&mapPreviewTexture);
//printf("=================> Rendering map preview into a texture AFTER (%p)\n", mapPreviewTexture); //printf("=================> Rendering map preview into a texture AFTER (%p)\n", mapPreviewTexture);
} }
else { //else {
renderer.renderMapPreview(&mapPreview, renderAll, 10, 350); //renderer.renderMapPreview(&mapPreview, renderAll, 10, 350);
} //}
} }
if(hasNetworkGameSettings() == true) { if(hasNetworkGameSettings() == true) {

View File

@ -28,6 +28,10 @@ protected:
GLuint renderBufferId; GLuint renderBufferId;
GLuint frameBufferId; GLuint frameBufferId;
void initRenderBuffer();
void initFrameBuffer();
void attachRenderBuffer();
public: public:
TextureGl(); TextureGl();
virtual ~TextureGl(); virtual ~TextureGl();
@ -36,14 +40,11 @@ public:
GLuint getRenderBufferHandle() const {return renderBufferId;} GLuint getRenderBufferHandle() const {return renderBufferId;}
GLuint getFrameBufferHandle() const {return frameBufferId;} GLuint getFrameBufferHandle() const {return frameBufferId;}
void initRenderBuffer(); bool supports_FBO_RBO();
void initFrameBuffer();
void attachRenderBuffer();
void attachFrameBufferToTexture();
bool checkFrameBufferStatus();
void dettachFrameBufferFromTexture();
void setup_FBO_RBO(); void setup_FBO_RBO();
void attachFrameBufferToTexture();
void dettachFrameBufferFromTexture();
bool checkFrameBufferStatus();
void teardown_FBO_RBO(); void teardown_FBO_RBO();
virtual int getTextureWidth() const = 0; virtual int getTextureWidth() const = 0;

View File

@ -21,11 +21,39 @@
using namespace std; 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 { namespace Shared { namespace Graphics { namespace Gl {
using namespace Platform; using namespace Platform;
using namespace Shared::Util; 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; const uint64 MIN_BYTES_TO_COMPRESS = 12;
static std::string getSupportCompressedTextureFormatString(int format) { static std::string getSupportCompressedTextureFormatString(int format) {
@ -425,6 +453,11 @@ TextureGl::TextureGl() {
handle = 0; handle = 0;
renderBufferId = 0; renderBufferId = 0;
frameBufferId = 0; frameBufferId = 0;
setupGLExtensionMethods();
}
bool TextureGl::supports_FBO_RBO() {
return (glGenFramebuffersEXT != NULL);
} }
void TextureGl::setup_FBO_RBO() { void TextureGl::setup_FBO_RBO() {
@ -432,158 +465,149 @@ void TextureGl::setup_FBO_RBO() {
throw runtime_error("getTextureWidth() < 0 || getTextureHeight() < 0"); 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) // Need some work to get extensions properly working in Windows (use Glew lib)
#ifndef WIN32 // 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; //SystemFlags::OutputDebug(SystemFlags::debugSystem,"width = %d, height = %d\n",width,height);
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); //RGBA8 2D texture, 24 bit depth texture, 256x256
//glGenTextures(1, &color_tex);
//RGBA8 2D texture, 24 bit depth texture, 256x256 //glBindTexture(GL_TEXTURE_2D, color_tex);
//glGenTextures(1, &color_tex); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glBindTexture(GL_TEXTURE_2D, color_tex); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //NULL means reserve texture memory, but texels are undefined
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
//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);
glGenFramebuffersEXT(1, &frameBufferId); //Attach 2D texture to this FBO
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, handle, 0);
//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);
glGenRenderbuffersEXT(1, &renderBufferId); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, getTextureWidth(), getTextureHeight());
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);
//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;
//Does the GPU support current FBO configuration? status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
GLenum status; switch(status)
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); {
switch(status) case GL_FRAMEBUFFER_COMPLETE_EXT:
{ //SystemFlags::OutputDebug(SystemFlags::debugSystem,"FBO attachment OK!\n");
case GL_FRAMEBUFFER_COMPLETE_EXT: break;
SystemFlags::OutputDebug(SystemFlags::debugSystem,"FBO attachment OK!\n"); default:
break; //SystemFlags::OutputDebug(SystemFlags::debugSystem,"FBO attachment BAD!\n");
default: break;
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() { void TextureGl::teardown_FBO_RBO() {
// Need some work to get extensions properly working in Windows (use Glew lib) // Need some work to get extensions properly working in Windows (use Glew lib)
#ifndef WIN32 if(glGenFramebuffersEXT) {
//----------------
//---------------- //Bind 0, which means render to back buffer
//Bind 0, which means render to back buffer glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); //And in the end, cleanup
//And in the end, cleanup //Delete resources
//Delete resources //glDeleteTextures(1, &handle);
//glDeleteTextures(1, &handle); glDeleteRenderbuffersEXT(1, &frameBufferId);
glDeleteRenderbuffersEXT(1, &frameBufferId); //Bind 0, which means render to back buffer, as a result, fb is unbound
//Bind 0, which means render to back buffer, as a result, fb is unbound glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glDeleteFramebuffersEXT(1, &frameBufferId);
glDeleteFramebuffersEXT(1, &frameBufferId); }
#endif
} }
void TextureGl::initRenderBuffer() { void TextureGl::initRenderBuffer() {
// Need some work to get extensions properly working in Windows (use Glew lib) // Need some work to get extensions properly working in Windows (use Glew lib)
#ifndef WIN32 if(glGenFramebuffersEXT) {
// create a renderbuffer object to store depth info
// create a renderbuffer object to store depth info glGenRenderbuffersEXT(1, &renderBufferId);
glGenRenderbuffersEXT(1, &renderBufferId); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderBufferId); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,getTextureWidth(), getTextureHeight());
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,getTextureWidth(), getTextureHeight()); //glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
//glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); }
#endif
} }
void TextureGl::initFrameBuffer() { void TextureGl::initFrameBuffer() {
// Need some work to get extensions properly working in Windows (use Glew lib) // Need some work to get extensions properly working in Windows (use Glew lib)
#ifndef WIN32 if(glGenFramebuffersEXT) {
// create a framebuffer object // create a framebuffer object
glGenFramebuffersEXT(1, &frameBufferId); glGenFramebuffersEXT(1, &frameBufferId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferId);
#endif }
} }
void TextureGl::attachRenderBuffer() { void TextureGl::attachRenderBuffer() {
// Need some work to get extensions properly working in Windows (use Glew lib) // Need some work to get extensions properly working in Windows (use Glew lib)
#ifndef WIN32 if(glGenFramebuffersEXT) {
// attach the renderbuffer to depth attachment point // attach the renderbuffer to depth attachment point
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, renderBufferId); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, renderBufferId);
#endif }
} }
void TextureGl::attachFrameBufferToTexture() { void TextureGl::attachFrameBufferToTexture() {
// Need some work to get extensions properly working in Windows (use Glew lib) // Need some work to get extensions properly working in Windows (use Glew lib)
#ifndef WIN32 if(glGenFramebuffersEXT) {
// attach the texture to FBO color attachment point // attach the texture to FBO color attachment point
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, handle, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, handle, 0);
#endif }
} }
bool TextureGl::checkFrameBufferStatus() { bool TextureGl::checkFrameBufferStatus() {
// Need some work to get extensions properly working in Windows (use Glew lib) // Need some work to get extensions properly working in Windows (use Glew lib)
#ifndef WIN32 if(glGenFramebuffersEXT) {
// check FBO status
// check FBO status // Does the GPU support current FBO configuration?
// Does the GPU support current FBO configuration? GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); if(status != GL_FRAMEBUFFER_COMPLETE_EXT) {
if(status != GL_FRAMEBUFFER_COMPLETE_EXT) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"checkFrameBufferStatus() status = %d [%X]\n",status,status);
SystemFlags::OutputDebug(SystemFlags::debugSystem,"checkFrameBufferStatus() status = %d [%X]\n",status,status); return false;
return false; }
return true;
} }
return true;
#else
return false; return false;
#endif
} }
void TextureGl::dettachFrameBufferFromTexture() { void TextureGl::dettachFrameBufferFromTexture() {
// Need some work to get extensions properly working in Windows (use Glew lib) // Need some work to get extensions properly working in Windows (use Glew lib)
#ifndef WIN32 if(glGenFramebuffersEXT) {
// switch back to window-system-provided framebuffer
// switch back to window-system-provided framebuffer glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); }
#endif
} }
TextureGl::~TextureGl() { TextureGl::~TextureGl() {
// Need some work to get extensions properly working in Windows (use Glew lib) // Need some work to get extensions properly working in Windows (use Glew lib)
#ifndef WIN32 if(glGenFramebuffersEXT) {
if(renderBufferId != 0) {
if(renderBufferId != 0) { glDeleteRenderbuffersEXT(1, &renderBufferId);
glDeleteRenderbuffersEXT(1, &renderBufferId); renderBufferId = 0;
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
} }
// ===================================================== // =====================================================