From 290fb5ebe265b7294bc2f8c4bf14f608f4f1fb21 Mon Sep 17 00:00:00 2001 From: Gerard Krol Date: Fri, 30 Mar 2007 17:38:35 +0000 Subject: [PATCH] A speed up for people who are fillrate limited: 1. The stencil buffer is no longer cleared each frame when shadows are disabled. 2. The color buffer is no longer cleared each frame, but care is taken do draw on the entire screen so that no smearing takes place. This patch gives me about +30 fps. (from 45 to 75) git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@1302 4a71c877-e1ca-e34f-864e-861f7616d084 --- lib/ivis_common/piefunc.h | 3 +- lib/ivis_common/piemode.h | 17 ++++--- lib/ivis_common/piestate.h | 1 + lib/ivis_opengl/piedraw.c | 6 ++- lib/ivis_opengl/piefunc.c | 98 +++++++++++++++++--------------------- lib/ivis_opengl/piemode.c | 23 +++++---- lib/ivis_opengl/tex.c | 9 +++- src/display3d.c | 69 +++++++++++++++++++++++---- src/loop.c | 28 +++++------ src/seqdisp.c | 2 +- src/seqdisp.h | 2 +- 11 files changed, 153 insertions(+), 105 deletions(-) diff --git a/lib/ivis_common/piefunc.h b/lib/ivis_common/piefunc.h index 300de7af2..79b4c4fc9 100644 --- a/lib/ivis_common/piefunc.h +++ b/lib/ivis_common/piefunc.h @@ -41,7 +41,8 @@ extern UBYTE pie_ByteScale(UBYTE a, UBYTE b); extern void pie_CornerBox(SDWORD x0, SDWORD y0, SDWORD x1, SDWORD y1, UDWORD colour, UBYTE a, UBYTE b, UBYTE c, UBYTE d); extern void pie_TransColouredTriangle( PIEVERTEX *vrt, UDWORD rgb ); -extern void pie_DrawSkybox(iView player, iView camera, float rotation, int texpage, int u, int v, int w, int h); +extern void pie_DrawSkybox(float scale, int u, int v, int w, int h); +extern void pie_DrawFogBox(float left, float right, float front, float back, float height, float wider); extern void pie_DrawViewingWindow( Vector3i *v, UDWORD x1, UDWORD y1, UDWORD x2, UDWORD y2, UDWORD colour); #endif // _piedef_h diff --git a/lib/ivis_common/piemode.h b/lib/ivis_common/piemode.h index f9d79761a..01fa9a77b 100644 --- a/lib/ivis_common/piemode.h +++ b/lib/ivis_common/piemode.h @@ -39,15 +39,14 @@ * Global Definitions */ /***************************************************************************/ -typedef enum CLEAR_MODE - { - CLEAR_OFF, - CLEAR_OFF_AND_NO_BUFFER_DOWNLOAD, - CLEAR_BLACK, - CLEAR_FOG, - } - CLEAR_MODE; +#define CLEAR_MODE_MASK 0x03 +#define CLEAR_OFF 0x00 +#define CLEAR_OFF_AND_NO_BUFFER_DOWNLOAD 0x01 +#define CLEAR_BLACK 0x02 +#define CLEAR_FOG 0x03 +#define CLEAR_SHADOW_MASK 0x04 +#define CLEAR_SHADOW 0x04 /***************************************************************************/ /* @@ -64,7 +63,7 @@ extern Sint32 _iVPRIM_DIVTABLE[]; /***************************************************************************/ extern BOOL pie_Initialise(void); extern void pie_ShutDown(void); -extern void pie_ScreenFlip(CLEAR_MODE ClearMode); +extern void pie_ScreenFlip(int ClearMode); extern UDWORD pie_GetResScalingFactor( void ); #endif diff --git a/lib/ivis_common/piestate.h b/lib/ivis_common/piestate.h index 215f0dfd7..75a7decf4 100644 --- a/lib/ivis_common/piestate.h +++ b/lib/ivis_common/piestate.h @@ -139,6 +139,7 @@ typedef struct RENDER_STATE RENDER_STATE; #define NO_TEXPAGE -1 +#define SKY_TEXPAGE 30 /***************************************************************************/ /* diff --git a/lib/ivis_opengl/piedraw.c b/lib/ivis_opengl/piedraw.c index a52dddefa..35b10553f 100644 --- a/lib/ivis_opengl/piedraw.c +++ b/lib/ivis_opengl/piedraw.c @@ -800,7 +800,6 @@ static void pie_DrawShadows(void) glDepthFunc(GL_LESS); glDepthMask(GL_FALSE); glEnable(GL_STENCIL_TEST); - glClear(GL_STENCIL_BUFFER_BIT); if (stencil_one_pass()) { glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); @@ -887,7 +886,10 @@ static void pie_DrawRemainingTransShapes(void) void pie_RemainingPasses(void) { - pie_DrawShadows(); + if(shadows) + { + pie_DrawShadows(); + } pie_DrawRemainingTransShapes(); } diff --git a/lib/ivis_opengl/piefunc.c b/lib/ivis_opengl/piefunc.c index 70b8c797e..074b75581 100644 --- a/lib/ivis_opengl/piefunc.c +++ b/lib/ivis_opengl/piefunc.c @@ -149,50 +149,16 @@ void pie_TransColouredTriangle( PIEVERTEX *vrt, UDWORD rgb ) /* ---------------------------------------------------------------------------------- */ -void pie_DrawSkybox(iView player, iView camera, float rotation, int texpage, int u, int v, int w, int h) +void pie_DrawSkybox(float scale, int u, int v, int w, int h) { - const int scale = 10000; const float r = 1.0f; // just because it is shorter than 1.0f - // save previous states - BOOL oldFogState = glIsEnabled(GL_FOG); - BOOL oldAlphaTestState = glIsEnabled(GL_ALPHA_TEST); - - // set up matrices and textures - pie_PerspectiveBegin(); - - // Push identity matrix onto stack - pie_MatBegin(); - - // Now, scale the world according to what resolution we're running in - pie_MatScale(pie_GetResScalingFactor()); - - // Set the camera position - pie_MATTRANS(camera.p.x, camera.p.y, camera.p.z); - - // Rotate for the player and for the wind - pie_MatRotZ(player.r.z); - pie_MatRotX(player.r.x); - pie_MatRotY(player.r.y + DEG(1) * rotation); - - // Apply scale matrix - glScalef(scale,scale / 2.0,scale); - - // move it somewhat below ground level for the blending effect - glTranslatef(0, -1 * r / 4, 0); - - // Standard color/alpha for texturing - glColor4f(1.0, 1.0, 1.0, 1.0f); - - // Set the texture page - pie_SetTexturePage(texpage); - - // the texture wraps over at the edges (repeat) - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - + glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_FOG_BIT); // fog should not affect the sky glDisable(GL_FOG); + + // So we have realistic colors + glColor4ub(0xFF,0xFF,0xFF,0xFF); // enable alpha glEnable(GL_BLEND); @@ -200,9 +166,9 @@ void pie_DrawSkybox(iView player, iView camera, float rotation, int texpage, int // for the nice blend of the sky with the fog glDisable(GL_ALPHA_TEST); - - // It is behind everything - glDisable(GL_DEPTH_TEST); + + // Apply scale matrix + glScalef(scale,scale / 2.0,scale); glBegin(GL_QUAD_STRIP); // Front @@ -224,20 +190,42 @@ void pie_DrawSkybox(iView player, iView camera, float rotation, int texpage, int glTexCoord2i(u + w * 8, v); glVertex3f(-r, r, r); // top r glEnd(); - // Load Saved State - pie_MatEnd(); - pie_PerspectiveEnd(); + glPopAttrib(); +} + +/// Draws a fog colored box which is wider at the top +void pie_DrawFogBox(float left, float right, float front, float back, float height, float wider) +{ + PIELIGHT fog_colour; + + fog_colour.argb = pie_GetFogColour(); + glColor4ub(fog_colour.byte.r,fog_colour.byte.g,fog_colour.byte.b,0xFF); + + glPushAttrib(GL_ENABLE_BIT | GL_FOG_BIT); + glDepthMask(GL_FALSE); + glDisable(GL_FOG); + pie_SetRendMode(REND_FLAT); + glBegin(GL_QUAD_STRIP); + // Front + glVertex3f(-left, 0, front); // bottom left + glVertex3f(-left-wider, height, front+wider); // top left + glVertex3f( right, 0, front); // bottom right + glVertex3f( right+wider, height, front+wider); // top right + + // Right + glVertex3f( right, 0,-back); // bottom r + glVertex3f( right+wider, height,-back-wider); // top r + + // Back + glVertex3f(-left, 0, -back); // bottom right + glVertex3f(-left-wider, height, -back-wider); // top right + + // Left + glVertex3f(-left, 0, front); // bottom r + glVertex3f(-left-wider, height, front+wider); // top r + glEnd(); + glPopAttrib(); - if (oldFogState) - { - glEnable(GL_FOG); - } - if (oldAlphaTestState) - { - glEnable(GL_ALPHA_TEST); - } - glDisable (GL_BLEND); - glEnable(GL_DEPTH_TEST); } /* ---------------------------------------------------------------------------------- */ diff --git a/lib/ivis_opengl/piemode.c b/lib/ivis_opengl/piemode.c index 44560b28a..14629ce3a 100644 --- a/lib/ivis_opengl/piemode.c +++ b/lib/ivis_opengl/piemode.c @@ -136,30 +136,33 @@ void pie_ShutDown(void) { /***************************************************************************/ -void pie_ScreenFlip(CLEAR_MODE clearMode) { +void pie_ScreenFlip(int clearMode) { PIELIGHT fog_colour; + GLbitfield clearFlags = 0; screenDoDumpToDiskIfRequired(); SDL_GL_SwapBuffers(); - switch (clearMode) { + switch (clearMode&CLEAR_MODE_MASK) { case CLEAR_OFF_AND_NO_BUFFER_DOWNLOAD: break; case CLEAR_BLACK: glDepthMask(GL_TRUE); glClearColor(0.0f,0.0f,0.0f,0.0f); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + clearFlags = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; break; default: glDepthMask(GL_TRUE); - fog_colour.argb = pie_GetFogColour(); - glClearColor(fog_colour.byte.r/255.0f, - fog_colour.byte.g/255.0f, - fog_colour.byte.b/255.0f, - fog_colour.byte.a/255.0f); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + clearFlags = GL_DEPTH_BUFFER_BIT; break; } - + if(clearMode&CLEAR_SHADOW_MASK) + { + clearFlags |= GL_STENCIL_BUFFER_BIT; + } + if(clearFlags) + { + glClear(clearFlags); + } if (screen_GetBackDrop()) { screen_Upload(NULL); } diff --git a/lib/ivis_opengl/tex.c b/lib/ivis_opengl/tex.c index 9ba5ed9b2..a94aef968 100644 --- a/lib/ivis_opengl/tex.c +++ b/lib/ivis_opengl/tex.c @@ -111,7 +111,14 @@ int pie_AddBMPtoTexPages(iTexture* s, const char* filename, int type, BOOL bReso glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + if( i == SKY_TEXPAGE ) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); /* Send back the texpage number so we can store it in the IMD */ diff --git a/src/display3d.c b/src/display3d.c index c7bcc0108..1cdb62875 100644 --- a/src/display3d.c +++ b/src/display3d.c @@ -131,7 +131,7 @@ static UDWORD getTargettingGfx(void); static void drawDroidGroupNumber(DROID *psDroid); static void trackHeight(SDWORD desiredHeight); static void getDefaultColours(void); -static void renderSky(void); +static void renderSurroundings(void); static void locateMouse(void); static void preprocessTiles(void); static BOOL renderWallSection(STRUCTURE *psStructure); @@ -359,8 +359,6 @@ SDWORD getCentreZ( void ) return(gridCentreZ); } - - /* Render the 3D world */ void draw3DScene( void ) { @@ -399,11 +397,13 @@ BOOL bPlayerHasHQ = FALSE; pie_Begin3DScene(); /* Set 3D world origins */ pie_SetGeometricOffset((iV_SCREEN_WIDTH>>1),geoOffset); - // draw skybox - renderSky(); + // draw terrain displayTerrain(); + // draw sky and fogbox + renderSurroundings(); + pie_BeginInterface(); updateLightLevels(); drawDroidSelections(); @@ -4419,12 +4419,57 @@ static void locateMouse(void) } -// Render a skybox -static void renderSky(void) +// Render the sky and surroundings +static void renderSurroundings(void) { static float wind = 0; + const float height = 10*TILE_UNITS; + const float wider = 2*(visibleXTiles*TILE_UNITS); + int left, right, front, back; + const float scale = 10000.0f; + + // set up matrices and textures + pie_PerspectiveBegin(); + + // Push identity matrix onto stack + pie_MatBegin(); + + // Now, scale the world according to what resolution we're running in + pie_MatScale(pie_GetResScalingFactor()); + + // Set the camera position + pie_MATTRANS(camera.p.x, camera.p.y, camera.p.z); + + // Rotate for the player and for the wind + pie_MatRotZ(player.r.z); + pie_MatRotX(player.r.x); + pie_MatRotY(player.r.y); + + // Fogbox // + rx = (player.p.x) & (TILE_UNITS-1); + rz = (player.p.z) & (TILE_UNITS-1); + pie_TRANSLATE(-rx,-player.p.y,rz); + + left = TILE_UNITS * min(visibleXTiles/2, playerXTile+visibleXTiles/2+1); + right = TILE_UNITS * min(visibleXTiles/2, mapWidth-playerXTile-visibleXTiles/2); + front = TILE_UNITS * min(visibleYTiles/2, playerZTile+visibleYTiles/2+1); + back = TILE_UNITS * min(visibleYTiles/2, mapHeight-playerZTile-visibleYTiles/2); + + pie_DrawFogBox(left, right, front, back, height, wider); + + // undo the translation + pie_TRANSLATE(rx,player.p.y,-rz); + + // Skybox // + // rotate it + pie_MatRotY(DEG(1) * wind); + + // move it somewhat below ground level for the blending effect + pie_TRANSLATE(0, -scale / 8, 0); + + // Set the texture page + pie_SetTexturePage(SKY_TEXPAGE); - // Let the winds blow! if(!gamePaused()) { wind += 0.5*frameTime2/GAME_TICKS_PER_SEC; @@ -4433,8 +4478,12 @@ static void renderSky(void) wind = 0; } } - pie_DrawSkybox(player, camera, wind, 30, 0, 128, 256, 128); -}; + pie_DrawSkybox(scale, 0, 128, 256, 128); + + // Load Saved State + pie_MatEnd(); + pie_PerspectiveEnd(); +} /* Flattens an imd to the landscape and handles 4 different rotations */ static iIMDShape *flattenImd(iIMDShape *imd, UDWORD structX, UDWORD structY, UDWORD direction) diff --git a/src/loop.c b/src/loop.c index fbaec65ce..79d2fdba1 100644 --- a/src/loop.c +++ b/src/loop.c @@ -175,7 +175,7 @@ GAMECODE gameLoop(void) UDWORD i,widgval; BOOL quitting=FALSE; INT_RETVAL intRetVal; - CLEAR_MODE clearMode; + int clearMode; // DumpVRAM(); // use mouse to scroll through vram // dumpimdpoints(); @@ -184,25 +184,23 @@ GAMECODE gameLoop(void) heapIntegrityCheck(psDroidHeap); #endif -//JPS 24 feb??? - if (war_GetFog()) + clearMode = CLEAR_FOG; + if (!war_GetFog()) { - // Mist - clearMode = CLEAR_FOG;//screen clear to fog colour D3D - if (loopMissionState == LMS_SAVECONTINUE) - { - pie_SetFogStatus(FALSE); - clearMode = CLEAR_BLACK; - } + // set the fog color to black (RGB) + // the fogbox will get this color + pie_SetFogColour(0x000000); } - else + if(getDrawShadows()) { - // Fog of War - clearMode = CLEAR_BLACK;//force to black 3DFX + clearMode |= CLEAR_SHADOW; + } + if (loopMissionState == LMS_SAVECONTINUE) + { + pie_SetFogStatus(FALSE); + clearMode = CLEAR_BLACK; } pie_ScreenFlip(clearMode);//gameloopflip -//JPS 24 feb??? - fastExit = FALSE; diff --git a/src/seqdisp.c b/src/seqdisp.c index ed53bfe04..4198d3eaf 100644 --- a/src/seqdisp.c +++ b/src/seqdisp.c @@ -511,7 +511,7 @@ static BOOL seq_StartFullScreenVideo(char* videoName, char* audioName) return TRUE; } -BOOL seq_UpdateFullScreenVideo(CLEAR_MODE *pbClear) +BOOL seq_UpdateFullScreenVideo(int *pbClear) { SDWORD i, x, y, w, h; SDWORD frame, frameLag; diff --git a/src/seqdisp.h b/src/seqdisp.h index a9b807206..6c96c0a49 100644 --- a/src/seqdisp.h +++ b/src/seqdisp.h @@ -63,7 +63,7 @@ extern BOOL seq_BlitBufferToScreen(char* screen, SDWORD screenStride, SDWORD xOf //full screen render //extern BOOL seq_PlayVideo(char* pSeq, char* pAudio); -extern BOOL seq_UpdateFullScreenVideo(CLEAR_MODE *bClear); +extern BOOL seq_UpdateFullScreenVideo(int *bClear); extern BOOL seq_StopFullScreenVideo(void); //control