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