Improved map preview.

Removes the need for FBOs, shows the map undistorted, unblurred and as large as
possible. Refs #1873.

git-svn-id: https://warzone2100.svn.sourceforge.net/svnroot/warzone2100/trunk@10888 4a71c877-e1ca-e34f-864e-861f7616d084
master
Christian Ohm 2010-05-31 16:24:33 +00:00 committed by Git SVN Gateway
parent b2dcb26e7c
commit f2ae61805c
9 changed files with 151 additions and 286 deletions

View File

@ -264,7 +264,7 @@ void pie_ImageFileIDTile(IMAGEFILE *ImageFile, UWORD ID, int x, int y, int Width
* was retrofitted onto something else. - Per */
void pie_UploadDisplayBuffer()
{
screen_Upload(NULL);
screen_Upload(NULL, false);
}
BOOL pie_InitRadar(void)

View File

@ -42,7 +42,6 @@
#include "lib/ivis_common/pieclip.h"
#include "screen.h"
/***************************************************************************/
/*
* Source
@ -123,7 +122,7 @@ void pie_ScreenFlip(int clearMode)
}
if (screen_GetBackDrop())
{
screen_Upload(NULL);
screen_Upload(NULL, screen_getMapPreview());
}
}

View File

@ -34,6 +34,7 @@
#include "lib/ivis_common/tex.h"
#include "lib/framework/frameint.h"
#include "lib/ivis_common/textdraw.h"
#include "lib/ivis_common/piestate.h"
#include "lib/ivis_common/pieblitfunc.h"
@ -60,12 +61,10 @@ static char screendump_filename[PATH_MAX];
static BOOL screendump_required = false;
static GLuint backDropTexture = ~0;
// Variables needed for our FBO
GLuint fbo; // Our handle to the FBO
GLuint FBOtexture; // The texture we are going to use
GLuint FBOdepthbuffer; // Our handle to the depth render buffer
static BOOL FBOinit = false;
BOOL bFboProblem = false; // hack to work around people with bad drivers. (*cough*intel*cough*)
static int preview_width = 0, preview_height = 0;
static Vector2i player_pos[MAX_PLAYERS];
static BOOL mappreview = false;
static char mapname[256];
/* Initialise the double buffered display */
bool screenInitialise(
@ -352,9 +351,11 @@ BOOL screen_GetBackDrop(void)
//******************************************************************
//slight hack to display maps (or whatever) in background.
//bitmap MUST be (BACKDROP_HACK_WIDTH * BACKDROP_HACK_HEIGHT) for now.
void screen_Upload(const char *newBackDropBmp)
void screen_Upload(const char *newBackDropBmp, BOOL preview)
{
static bool processed = false;
int x1 = 0, x2 = screenWidth, y1 = 0, y2 = screenHeight, i, scale, w, h;
float tx = 1, ty = 1;
if(newBackDropBmp != NULL)
{
@ -389,16 +390,92 @@ void screen_Upload(const char *newBackDropBmp)
glBindTexture(GL_TEXTURE_2D, backDropTexture);
glColor3f(1, 1, 1);
if (preview)
{
int s1, s2;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
s1 = screenWidth / preview_width;
s2 = screenHeight / preview_height;
scale = MIN(s1, s2);
w = preview_width * scale;
h = preview_height * scale;
x1 = screenWidth / 2 - w / 2;
x2 = screenWidth / 2 + w / 2;
y1 = screenHeight / 2 - h / 2;
y2 = screenHeight / 2 + h / 2;
tx = preview_width / (float)BACKDROP_HACK_WIDTH;
ty = preview_height / (float)BACKDROP_HACK_HEIGHT;
}
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0, 0);
glVertex2f(0, 0);
glTexCoord2f(1, 0);
glVertex2f(screenWidth, 0);
glTexCoord2f(0, 1);
glVertex2f(0, screenHeight);
glTexCoord2f(1, 1);
glVertex2f(screenWidth, screenHeight);
glVertex2f(x1, y1);
glTexCoord2f(tx, 0);
glVertex2f(x2, y1);
glTexCoord2f(0, ty);
glVertex2f(x1, y2);
glTexCoord2f(tx, ty);
glVertex2f(x2, y2);
glEnd();
if (preview)
{
for (i = 0; i < MAX_PLAYERS; i++)
{
int x = player_pos[i].x;
int y = player_pos[i].y;
char text[5];
if (x == 0x77777777)
continue;
x = screenWidth / 2 - w / 2 + x * scale;
y = screenHeight / 2 - h / 2 + y * scale;
ssprintf(text, "%d", i);
iV_SetFont(font_large);
iV_SetTextColour(WZCOL_BLACK);
iV_DrawText(text, x - 1, y - 1);
iV_DrawText(text, x + 1, y - 1);
iV_DrawText(text, x - 1, y + 1);
iV_DrawText(text, x + 1, y + 1);
iV_SetTextColour(WZCOL_WHITE);
iV_DrawText(text, x, y);
}
}
}
void screen_enableMapPreview(char *name, int width, int height, Vector2i *playerpositions)
{
int i;
mappreview = true;
preview_width = width;
preview_height = height;
sstrcpy(mapname, name);
for (i = 0; i < MAX_PLAYERS; i++)
{
player_pos[i].x = playerpositions[i].x;
player_pos[i].y = playerpositions[i].y;
}
}
const char *screen_getMapName(void)
{
return mapname;
}
void screen_disableMapPreview(void)
{
mappreview = false;
sstrcpy(mapname, "none");
}
BOOL screen_getMapPreview(void)
{
return mappreview;
}
/* Swap between windowed and full screen mode */
@ -493,103 +570,3 @@ void screenDumpToDisk(const char* path)
screendump_required = true;
}
BOOL Init_FBO(unsigned int width, unsigned int height)
{
GLenum status;
glErrors();
// Bail out if FBOs aren't supported
if (!GLEE_EXT_framebuffer_object)
return false;
// No need to create two FBOs
if (FBOinit)
return true;
// Create the FBO
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
// create depthbuffer
glGenRenderbuffersEXT(1, &FBOdepthbuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, FBOdepthbuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, FBOdepthbuffer);
// Now setup a texture to render to
glGenTextures(1, &FBOtexture);
glBindTexture(GL_TEXTURE_2D, FBOtexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// attach that texture to the color
glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, FBOtexture, 0);
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); // unbind FBO
// make sure everything went OK
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(status != GL_FRAMEBUFFER_COMPLETE_EXT)
{
switch (status)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
debug(LOG_ERROR, "Error: FBO missing a required image/buffer attachment!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
debug(LOG_ERROR, "Error: FBO has no images/buffers attached!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
debug(LOG_ERROR, "Error: FBO has mismatched image/buffer dimensions!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
debug(LOG_ERROR, "Error: FBO colorbuffer attachments have different types!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
debug(LOG_ERROR, "Error: FBO trying to draw to non-attached color buffer!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
debug(LOG_ERROR, "Error: FBO trying to read from a non-attached color buffer!");
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
debug(LOG_ERROR, "Error: FBO format is not supported by current graphics card/driver!");
break;
case GL_INVALID_FRAMEBUFFER_OPERATION_EXT :
debug(LOG_ERROR, "Error: FBO Non-framebuffer passed to glCheckFramebufferStatusEXT()!");
break;
default:
debug(LOG_ERROR, "*UNKNOWN FBO ERROR* reported from glCheckFramebufferStatusEXT() for %x!", (unsigned int)status);
break;
}
FBOinit = false; //we have a error with the FBO setup
return false;
}
else
{
FBOinit = true; //everything is OK with FBO setup.
}
glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0); // unbind it for now.
bFboProblem |= glErrors(); // don't use FBOs if something here caused an error
return true;
}
void Delete_FBO(void)
{
if(FBOinit)
{
glErrors();
glDeleteFramebuffersEXT(1, &fbo);
glDeleteRenderbuffersEXT(1, &FBOdepthbuffer);
glDeleteTextures(1,&FBOtexture);
bFboProblem |= glErrors();
fbo = FBOdepthbuffer = FBOtexture = FBOinit = 0; //reset everything.
}
}

View File

@ -48,7 +48,7 @@ extern void screen_SetBackDropFromFile(const char* filename);
extern void screen_StopBackDrop(void);
extern void screen_RestartBackDrop(void);
extern BOOL screen_GetBackDrop(void);
extern void screen_Upload(const char *newBackDropBmp);
extern void screen_Upload(const char *newBackDropBmp, BOOL preview);
/* screendump */
extern void screenDumpToDisk(const char* path);
@ -60,6 +60,8 @@ extern int wz_texture_compression;
extern void screenDoDumpToDiskIfRequired(void);
extern BOOL Init_FBO(unsigned int width, unsigned int height);
extern void Delete_FBO(void);
void screen_enableMapPreview(char *name, int width, int height, Vector2i *playerpositions);
void screen_disableMapPreview(void);
BOOL screen_getMapPreview(void);
const char *screen_getMapName(void);
#endif

View File

@ -27,6 +27,7 @@
#include "lib/framework/configfile.h"
#include "lib/netplay/netplay.h"
#include "lib/sound/mixer.h"
#include "lib/ivis_opengl/screen.h"
#include "advvis.h"
#include "ai.h"

View File

@ -11506,14 +11506,13 @@ static BOOL getNameFromComp(UDWORD compType, char *pDest, UDWORD compIndex)
/**
* \param[out] backDropSprite The premade map texture.
* \param scale Scale of the map texture.
* \param offX,offY X and Y offset for map
* \param[out] playeridpos Will contain the position on the map where the player's HQ are located.
*
* Reads the current map and colours the map preview for any structures
* present. Additionally we load the player's HQ location into playeridpos so
* we know the player's starting location.
*/
BOOL plotStructurePreview16(char *backDropSprite, UBYTE scale, UDWORD offX, UDWORD offY,Vector2i playeridpos[])
BOOL plotStructurePreview16(char *backDropSprite, Vector2i playeridpos[])
{
SAVE_STRUCTURE sSave; // close eyes now.
SAVE_STRUCTURE *psSaveStructure = &sSave; // assumes save_struct is larger than all previous ones...
@ -11527,7 +11526,7 @@ BOOL plotStructurePreview16(char *backDropSprite, UBYTE scale, UDWORD offX, UDWO
STRUCT_SAVEHEADER *psHeader;
char aFileName[256];
UDWORD xx,yy,x,y,count,fileSize,sizeOfSaveStruture;
UDWORD xx,yy,count,fileSize,sizeOfSaveStruture;
UDWORD playerid =0;
char *pFileData = NULL;
LEVEL_DATASET *psLevel;
@ -11942,15 +11941,9 @@ BOOL plotStructurePreview16(char *backDropSprite, UBYTE scale, UDWORD offX, UDWO
}
// and now we blit the color to the texture
for(x = (xx*scale);x < (xx*scale)+scale ;x++)
{
for(y = (yy*scale);y< (yy*scale)+scale ;y++)
{
backDropSprite[3 * (((offY + y) * BACKDROP_HACK_WIDTH) + x + offX)] = color.byte.r;
backDropSprite[3 * (((offY + y) * BACKDROP_HACK_WIDTH) + x + offX) + 1] = color.byte.g;
backDropSprite[3 * (((offY + y) * BACKDROP_HACK_WIDTH) + x + offX) + 2] = color.byte.b;
}
}
backDropSprite[3 * ((yy * BACKDROP_HACK_WIDTH) + xx)] = color.byte.r;
backDropSprite[3 * ((yy * BACKDROP_HACK_WIDTH) + xx) + 1] = color.byte.g;
backDropSprite[3 * ((yy * BACKDROP_HACK_WIDTH) + xx) + 2] = color.byte.b;
}
// NOTE: would do fallback if FBO is not available here.

View File

@ -145,7 +145,7 @@ extern void game_SetValidityKey(UDWORD keys);
/*returns the current type of save game being loaded*/
extern UDWORD getSaveGameType(void);
BOOL plotStructurePreview16(char *backDropSprite, UBYTE scale, UDWORD offX, UDWORD offY, Vector2i playeridpos[]);
BOOL plotStructurePreview16(char *backDropSprite, Vector2i playeridpos[]);
#ifdef __cplusplus
}

View File

@ -39,6 +39,7 @@
#include "lib/ivis_common/piedef.h"
#include "lib/ivis_common/piestate.h"
#include "lib/ivis_common/pieclip.h"
#include "lib/ivis_common/piemode.h"
#include "lib/ivis_common/piepalette.h"
#include "lib/ivis_common/rendmode.h"
#include "lib/ivis_opengl/piematrix.h" // for setgeometricoffset
@ -135,10 +136,6 @@
extern char MultiCustomMapsPath[PATH_MAX];
extern char MultiPlayersPath[PATH_MAX];
extern char VersionString[80]; // from netplay.c
extern GLuint fbo; // Our handle to the FBO
extern GLuint FBOtexture; // The texture we are going to use
extern GLuint FBOdepthbuffer; // Our handle to the depth render buffer
extern BOOL bFboProblem; // hack to work around people with bad drivers. (*cough*intel*cough*)
extern BOOL bSendingMap; // used to indicate we are sending a map
extern void intDisplayTemplateButton(WIDGET *psWidget, UDWORD xOffset, UDWORD yOffset, PIELIGHT *pColours);
@ -258,18 +255,18 @@ static int guessMapTilesetType(void)
/// a picture of it
void loadMapPreview(bool hideInterface)
{
char aFileName[256];
static char aFileName[256], bFileName[256];
UDWORD fileSize;
char *pFileData = NULL;
LEVEL_DATASET *psLevel = NULL;
PIELIGHT plCliffL, plCliffH, plWater, plRoadL, plRoadH, plGroundL, plGroundH;
UDWORD i, j, x, y, height, offX2, offY2;
UBYTE scale,col;
UDWORD x, y, height;
UBYTE col;
MAPTILE *psTile,*WTile;
UDWORD oursize;
Vector2i playerpos[MAX_PLAYERS]; // Will hold player positions
char *ptr = NULL, *imageData = NULL, *fboData = NULL;
char *ptr = NULL, *imageData = NULL;
if(psMapTiles)
{
@ -284,6 +281,16 @@ void loadMapPreview(bool hideInterface)
aFileName[strlen(aFileName)-4] = '\0';
sstrcat(aFileName, "/ttypes.ttp");
pFileData = fileLoadBuffer;
sstrcpy(bFileName, screen_getMapName());
if (!sstrcmp(aFileName, bFileName))
{
if (hideInterface)
{
hideTime = gameTime;
}
return;
}
sstrcpy(bFileName, aFileName);
if (!loadFileToBuffer(aFileName, pFileData, FILE_LOAD_BUFFER_SIZE, &fileSize))
{
debug(LOG_ERROR, "loadMapPreview: Failed to load terrain types file");
@ -341,23 +348,6 @@ void loadMapPreview(bool hideInterface)
break;
}
scale = 1;
if((mapHeight < 240)&&(mapWidth < 320))
{
scale = 2;
}
if((mapHeight < 120)&&(mapWidth < 160))
{
scale = 3;
}
if((mapHeight < 60)&&(mapWidth < 80))
{
scale = 4;
}
if((mapHeight < 30)&&(mapWidth < 40))
{
scale = 5;
}
oursize = sizeof(char) * BACKDROP_HACK_WIDTH * BACKDROP_HACK_HEIGHT;
imageData = (char*)malloc(oursize * 3); // used for the texture
if( !imageData )
@ -366,57 +356,41 @@ void loadMapPreview(bool hideInterface)
abort(); // should be a fatal error ?
return;
}
fboData = (char*)malloc(oursize* 3); // used for the FBO texture
if( !fboData )
{
debug(LOG_FATAL,"Out of memory for FBO texture!");
free(imageData);
abort(); // should be a fatal error?
return ;
}
ptr = imageData;
memset(ptr, 0x45, sizeof(char) * BACKDROP_HACK_WIDTH * BACKDROP_HACK_HEIGHT * 3); //dunno about background color
memset(ptr, 0, sizeof(char) * BACKDROP_HACK_WIDTH * BACKDROP_HACK_HEIGHT * 3); //dunno about background color
psTile = psMapTiles;
offX2 = (BACKDROP_HACK_WIDTH / 2) - ((scale * mapWidth) / 2);
offY2 = (BACKDROP_HACK_HEIGHT / 2 ) - ((scale * mapHeight) / 2);
for (i = 0; i < mapHeight; i++)
for (y = 0; y < mapHeight; y++)
{
WTile = psTile;
for (j = 0; j < mapWidth; j++)
for (x = 0; x < mapWidth; x++)
{
char * const p = imageData + (3 * (y * BACKDROP_HACK_WIDTH + x));
height = WTile->height;
col = height;
for (x = (j * scale); x < (j * scale) + scale; x++)
switch (terrainType(WTile))
{
for (y = (i * scale); y < (i * scale) + scale; y++)
{
char * const p = imageData + (3 * ((offY2 + y) * BACKDROP_HACK_WIDTH + (x + offX2)));
switch (terrainType(WTile))
{
case TER_CLIFFFACE:
p[0] = plCliffL.byte.r + (plCliffH.byte.r-plCliffL.byte.r) * col / 256;
p[1] = plCliffL.byte.g + (plCliffH.byte.g-plCliffL.byte.g) * col / 256;
p[2] = plCliffL.byte.b + (plCliffH.byte.b-plCliffL.byte.b) * col / 256;
break;
case TER_WATER:
p[0] = plWater.byte.r;
p[1] = plWater.byte.g;
p[2] = plWater.byte.b;
break;
case TER_ROAD:
p[0] = plRoadL.byte.r + (plRoadH.byte.r-plRoadL.byte.r) * col / 256;
p[1] = plRoadL.byte.g + (plRoadH.byte.g-plRoadL.byte.g) * col / 256;
p[2] = plRoadL.byte.b + (plRoadH.byte.b-plRoadL.byte.b) * col / 256;
break;
default:
p[0] = plGroundL.byte.r + (plGroundH.byte.r-plGroundL.byte.r) * col / 256;
p[1] = plGroundL.byte.g + (plGroundH.byte.g-plGroundL.byte.g) * col / 256;
p[2] = plGroundL.byte.b + (plGroundH.byte.b-plGroundL.byte.b) * col / 256;
break;
}
}
case TER_CLIFFFACE:
p[0] = plCliffL.byte.r + (plCliffH.byte.r-plCliffL.byte.r) * col / 256;
p[1] = plCliffL.byte.g + (plCliffH.byte.g-plCliffL.byte.g) * col / 256;
p[2] = plCliffL.byte.b + (plCliffH.byte.b-plCliffL.byte.b) * col / 256;
break;
case TER_WATER:
p[0] = plWater.byte.r;
p[1] = plWater.byte.g;
p[2] = plWater.byte.b;
break;
case TER_ROAD:
p[0] = plRoadL.byte.r + (plRoadH.byte.r-plRoadL.byte.r) * col / 256;
p[1] = plRoadL.byte.g + (plRoadH.byte.g-plRoadL.byte.g) * col / 256;
p[2] = plRoadL.byte.b + (plRoadH.byte.b-plRoadL.byte.b) * col / 256;
break;
default:
p[0] = plGroundL.byte.r + (plGroundH.byte.r-plGroundL.byte.r) * col / 256;
p[1] = plGroundL.byte.g + (plGroundH.byte.g-plGroundL.byte.g) * col / 256;
p[2] = plGroundL.byte.b + (plGroundH.byte.b-plGroundL.byte.b) * col / 256;
break;
}
WTile += 1;
}
@ -425,95 +399,12 @@ void loadMapPreview(bool hideInterface)
// Slight hack to init array with a special value used to determine how many players on map
memset(playerpos,0x77,sizeof(playerpos));
// color our texture with clancolors @ correct position
plotStructurePreview16(imageData, scale, offX2, offY2,playerpos);
glErrors(); // clear openGL errorcodes
// and now, for those that have FBO available on their card
// added hack to work around bad drivers that report FBO available, when it is not.
if(Init_FBO(BACKDROP_HACK_WIDTH,BACKDROP_HACK_HEIGHT) && !bFboProblem)
{
// Save the view port and set it to the size of the texture
glPushAttrib(GL_VIEWPORT_BIT);
plotStructurePreview16(imageData, playerpos);
// First we bind the FBO so we can render to it
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
bFboProblem |= glErrors();
screen_enableMapPreview(bFileName, mapWidth, mapHeight, playerpos);
//set up projection & model matrix for the texture(!)
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0f,(double)BACKDROP_HACK_HEIGHT,0,(double)BACKDROP_HACK_WIDTH,-1.0f,1.0f);
screen_Upload(imageData, true);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glViewport( 0, 0, BACKDROP_HACK_WIDTH, BACKDROP_HACK_HEIGHT );
// Then render as normal
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT ); //| GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// and start drawing here
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, FBOtexture);
//upload the texture to the FBO
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,BACKDROP_HACK_WIDTH,BACKDROP_HACK_HEIGHT,GL_RGB,GL_UNSIGNED_BYTE,imageData);
iV_SetFont(font_large);
glDisable(GL_CULL_FACE);
for(i=0;i < MAX_PLAYERS;i++)//
{
float fx,fy;
if(playerpos[i].x==0x77777777) continue; // no player is available, so skip
fx =(float)playerpos[i].x;
fy =(float)playerpos[i].y;
fx*=(float)scale;
fy*=(float)scale;
fx+=(float)offX2;
fy+=(float)offY2;
glcRenderStyle(GLC_TEXTURE);
// first draw a slightly bigger font of the number using said color
iV_SetTextColour(WZCOL_DBLUE);
iV_SetTextSize(28.f);
iV_DrawTextF(fx,fy,"%d",i);
// now draw it again using smaller font and said color
iV_SetTextColour(WZCOL_LBLUE);
iV_SetTextSize(24.f);
iV_DrawTextF(fx,fy,"%d",i);
}
glcRenderStyle(GLC_TEXTURE);
// set rendering back to default frame buffer
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, BACKDROP_HACK_WIDTH, BACKDROP_HACK_HEIGHT,GL_RGB,GL_UNSIGNED_BYTE,fboData);
//done with the FBO, so unbind it.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
bFboProblem |= glErrors();
// if we detected a error, then we must fallback to old texture, or user will not see anything.
if(!bFboProblem)
{
screen_Upload(fboData);
}
else
{
screen_Upload(imageData);
}
bFboProblem |= glErrors();
glEnable(GL_CULL_FACE);
}
else
{
// no FBO was available, just show them what we got.
screen_Upload(imageData);
}
free(fboData);
free(imageData);
if (hideInterface)
@ -521,7 +412,6 @@ void loadMapPreview(bool hideInterface)
hideTime = gameTime;
}
mapShutdown();
Delete_FBO();
}
// ////////////////////////////////////////////////////////////////////////////

View File

@ -154,6 +154,9 @@ TITLECODE titleLoop(void)
pie_SetMouse(CURSOR_DEFAULT, war_GetColouredCursor());
}
if (titleMode != MULTIOPTION && titleMode != MULTILIMIT && titleMode != STARTGAME)
screen_disableMapPreview();
switch(titleMode) // run relevant title screen code.
{
// MULTIPLAYER screens