diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 46f7c549..eeb7d2ff 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -139,7 +139,7 @@ enum EPolyFlags PF_Decal = 0x00000800, // Enable polygon offset PF_Modulated = 0x00001000, // Modulation (multiply output with constant ARGB) // When set, pass the color constant into the FSurfaceInfo -> FlatColor - PF_NoTexture = 0x00002000, // Use the small white texture + PF_NoTexture = 0x00002000, // Disable texture PF_Ripple = 0x00004000, // Water shader effect // 0x00008000 PF_RemoveYWrap = 0x00010000, // Force clamp texture on Y diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 78b182bf..d0644067 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -470,7 +470,9 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is else PolyFlags |= PF_Masked|PF_Modulated; - if (PolyFlags & PF_Ripple) + if (PolyFlags & PF_Fog) + HWD.pfnSetShader(6); // fog shader + else if (PolyFlags & PF_Ripple) HWD.pfnSetShader(5); // water shader else HWD.pfnSetShader(1); // floor shader @@ -3651,7 +3653,7 @@ typedef struct static wallinfo_t *wallinfo = NULL; static size_t numwalls = 0; // a list of transparent walls to be drawn -static void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, INT32 lightlevel, extracolormap_t *wallcolormap); +static void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); #define MAX_TRANSPARENTWALL 256 @@ -3935,7 +3937,7 @@ static void HWR_RenderDrawNodes(void) { if (!(sortnode[sortindex[i]].wall->blend & PF_NoTexture)) HWR_GetTexture(sortnode[sortindex[i]].wall->texnum); - HWR_RenderWall(sortnode[sortindex[i]].wall->wallVerts, &sortnode[sortindex[i]].wall->Surf, sortnode[sortindex[i]].wall->blend, + HWR_RenderWall(sortnode[sortindex[i]].wall->wallVerts, &sortnode[sortindex[i]].wall->Surf, sortnode[sortindex[i]].wall->blend, sortnode[sortindex[i]].wall->fogwall, sortnode[sortindex[i]].wall->lightlevel, sortnode[sortindex[i]].wall->wallcolormap); } } @@ -4442,7 +4444,7 @@ static void HWR_DrawSkyBackground(void) v[0].t = v[1].t -= ((float) angle / angleturn); } - HWD.pfnSetShader(6); // sky shader + HWD.pfnSetShader(7); // sky shader HWD.pfnDrawPolygon(NULL, v, 4, 0); HWD.pfnSetShader(0); } @@ -4752,8 +4754,9 @@ static void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, I numwalls++; } -static void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, INT32 lightlevel, extracolormap_t *wallcolormap) +static void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) { + FBITFIELD blendmode = blend; UINT8 alpha = pSurf->PolyColor.s.alpha; // retain the alpha // Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting @@ -4765,10 +4768,19 @@ static void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIE pSurf->PolyColor.s.alpha = alpha; // put the alpha back after lighting HWD.pfnSetShader(2); // wall shader + if (blend & PF_Environment) - HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blend|PF_Modulated|PF_Occlude); // PF_Occlude must be used for solid objects - else - HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blend|PF_Modulated); // No PF_Occlude means overlapping (incorrect) transparency + blendmode |= PF_Occlude; // PF_Occlude must be used for solid objects + + if (fogwall) + { + blendmode |= PF_Fog; + HWD.pfnSetShader(6); // fog shader + } + + blendmode |= PF_Modulated; // No PF_Occlude means overlapping (incorrect) transparency + + HWD.pfnDrawPolygon(pSurf, wallVerts, 4, blendmode); #ifdef WALLSPLATS if (gr_curline->linedef->splats && cv_splats.value) @@ -4946,7 +4958,7 @@ void HWR_LoadShaders(UINT16 wadnum, boolean PK3) int shadertype = 0; int i; - #define SHADER_TYPES 6 + #define SHADER_TYPES 7 shaderxlat_t shaderxlat[SHADER_TYPES] = { {"Flat", 1}, @@ -4954,7 +4966,8 @@ void HWR_LoadShaders(UINT16 wadnum, boolean PK3) {"Sprite", 3}, {"Model", 4}, {"WaterRipple", 5}, - {"Sky", 6}, + {"Fog", 6}, + {"Sky", 7}, }; lump = HWR_CheckShader(wadnum); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 19907a5b..5866e571 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -43,7 +43,7 @@ static const GLubyte white[4] = { 255, 255, 255, 255 }; // ========================================================================== // With OpenGL 1.1+, the first texture should be 1 -#define NOTEXTURE_NUM 1 // small white texture +#define NOTEXTURE_NUM 0 #define FIRST_TEX_AVAIL (NOTEXTURE_NUM + 1) #define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f) @@ -630,9 +630,13 @@ static const char *fragment_shaders[] = { // Water fragment shader SHARED_FRAGMENT_SHADER, + // Fog fragment shader + "void main(void) {\n" + "gl_FragColor = gl_Color;\n" + "}\0", + // Sky fragment shader "uniform sampler2D tex;\n" - "uniform vec2 resolution;\n" "void main(void) {\n" "float texU = gl_TexCoord[0].s;\n" "float texV = gl_TexCoord[0].t;\n" @@ -673,6 +677,9 @@ static const char *vertex_shaders[] = { // Water vertex shader DEFAULT_VERTEX_SHADER, + // Fog vertex shader + DEFAULT_VERTEX_SHADER, + // Sky vertex shader DEFAULT_VERTEX_SHADER, }; @@ -875,7 +882,7 @@ EXPORT void HWRAPI(KillShaders) (void) // -----------------+ static void SetNoTexture(void) { - // Set small white texture. + // Disable texture. if (tex_downloaded != NOTEXTURE_NUM) { pglBindTexture(GL_TEXTURE_2D, NOTEXTURE_NUM);