From 42011745190861de8d9cd3c7699f0d60372d3d8d Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sun, 14 Dec 2025 23:38:50 -0500 Subject: [PATCH] Revert "Port palette rendering from SRB2" This reverts commit 5b7699b29a52a5d11a7705a70b75476f68d49cff. --- src/hardware/CMakeLists.txt | 1 - src/hardware/hw_batching.c | 7 +- src/hardware/hw_cache.c | 245 +------ src/hardware/hw_defs.h | 60 +- src/hardware/hw_draw.c | 30 +- src/hardware/hw_drv.h | 54 +- src/hardware/hw_glob.h | 21 +- src/hardware/hw_main.c | 417 +++++++----- src/hardware/hw_main.h | 11 +- src/hardware/hw_md2.c | 23 +- src/hardware/hw_shaders.h | 425 ------------- src/hardware/r_opengl/r_opengl.c | 1021 ++++++++++++++++++------------ src/hardware/r_opengl/r_opengl.h | 9 +- src/r_data.c | 5 +- src/r_defs.h | 5 - src/sdl/hwsym_sdl.c | 23 +- src/sdl/i_video.cpp | 31 +- src/sdl/ogl_sdl.c | 4 +- src/st_stuff.c | 6 +- src/w_wad.cpp | 3 + src/y_inter.c | 2 +- 21 files changed, 977 insertions(+), 1426 deletions(-) delete mode 100644 src/hardware/hw_shaders.h diff --git a/src/hardware/CMakeLists.txt b/src/hardware/CMakeLists.txt index 8b00fa353..a0a0f280c 100644 --- a/src/hardware/CMakeLists.txt +++ b/src/hardware/CMakeLists.txt @@ -11,6 +11,5 @@ target_sources(SRB2SDL2 PRIVATE hw_model.c u_list.c hw_batching.c - hw_shaders.c r_opengl/r_opengl.c ) diff --git a/src/hardware/hw_batching.c b/src/hardware/hw_batching.c index 1c1633894..591a37349 100644 --- a/src/hardware/hw_batching.c +++ b/src/hardware/hw_batching.c @@ -93,7 +93,7 @@ void HWR_SetCurrentTexture(GLMipmap_t *texture) // If batching is enabled, this function collects the polygon data and the chosen texture // for later use in HWR_RenderBatches. Otherwise the rendering backend is used to // render the polygon immediately. -void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader_target, boolean horizonSpecial) +void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial) { if (currently_batching) { @@ -132,7 +132,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt polygonArray[polygonArraySize].polyFlags = PolyFlags; polygonArray[polygonArraySize].texture = current_texture; polygonArray[polygonArraySize].brightmap = current_brightmap; - polygonArray[polygonArraySize].shader = (shader_target != -1) ? HWR_GetShaderFromTarget(shader_target) : shader_target; + polygonArray[polygonArraySize].shader = shader; polygonArray[polygonArraySize].horizonSpecial = horizonSpecial; polygonArraySize++; @@ -141,7 +141,8 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt } else { - HWD.pfnSetShader((shader_target != SHADER_NONE) ? HWR_GetShaderFromTarget(shader_target) : shader_target); + if (shader) + HWD.pfnSetShader(shader); HWD.pfnDrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags); } } diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 776761490..76536350d 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -39,14 +39,6 @@ INT32 patchformat = GL_TEXFMT_AP_88; // use alpha for holes INT32 textureformat = GL_TEXFMT_P_8; // use chromakey for hole -RGBA_t mapPalette[256] = {0}; // the palette for the currently loaded level or menu etc. - -// Returns a pointer to the palette which should be used for caching textures. -RGBA_t *HWR_GetTexturePalette(void) -{ - return HWR_ShouldUsePaletteRendering() ? mapPalette : pLocalPalette; -} - static INT32 format2bpp(GLTextureFormat_t format) { if (format == GL_TEXFMT_RGBA) @@ -64,7 +56,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm INT32 pblockheight, INT32 blockmodulo, fixed_t yfracstep, fixed_t scale_y, texpatch_t *originPatch, INT32 patchheight, - INT32 bpp, RGBA_t *palette) + INT32 bpp) { fixed_t yfrac, position, count; UINT8 *dest; @@ -136,7 +128,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm texelu16 = (UINT16)((alpha<<8) | texel); memcpy(dest, &texelu16, sizeof(UINT16)); break; - case 3 : colortemp = palette[texel]; + case 3 : colortemp = V_GetColor(texel); if ((originPatch != NULL) && (originPatch->style != AST_COPY)) { RGBA_t rgbatexel; @@ -145,7 +137,7 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm } memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); break; - case 4 : colortemp = palette[texel]; + case 4 : colortemp = V_GetColor(texel); colortemp.s.alpha = alpha; if ((originPatch != NULL) && (originPatch->style != AST_COPY)) { @@ -175,7 +167,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, INT32 pblockheight, INT32 blockmodulo, fixed_t yfracstep, fixed_t scale_y, texpatch_t *originPatch, INT32 patchheight, - INT32 bpp, RGBA_t *palette) + INT32 bpp) { fixed_t yfrac, position, count; UINT8 *dest; @@ -246,7 +238,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, texelu16 = (UINT16)((alpha<<8) | texel); memcpy(dest, &texelu16, sizeof(UINT16)); break; - case 3 : colortemp = palette[texel]; + case 3 : colortemp = V_GetColor(texel); if ((originPatch != NULL) && (originPatch->style != AST_COPY)) { RGBA_t rgbatexel; @@ -255,7 +247,7 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, } memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); break; - case 4 : colortemp = palette[texel]; + case 4 : colortemp = V_GetColor(texel); colortemp.s.alpha = alpha; if ((originPatch != NULL) && (originPatch->style != AST_COPY)) { @@ -299,13 +291,10 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, UINT8 *block = mipmap->data; INT32 bpp; INT32 blockmodulo; - RGBA_t *palette; if (pwidth <= 0 || pheight <= 0) return; - palette = HWR_GetTexturePalette(); - ncols = pwidth; // source advance @@ -331,7 +320,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, pblockheight, blockmodulo, yfracstep, scale_y, NULL, pheight, // not that pheight is going to get used anyway... - bpp, palette); + bpp); } } @@ -350,14 +339,12 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, INT32 bpp; INT32 blockmodulo; INT32 width, height; - RGBA_t *palette; - // Column drawing function pointer. static void (*ColumnDrawerPointer)(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap, INT32 pblockheight, INT32 blockmodulo, fixed_t yfracstep, fixed_t scale_y, texpatch_t *originPatch, INT32 patchheight, - INT32 bpp, RGBA_t *palette); + INT32 bpp); if (texture->width <= 0 || texture->height <= 0) return; @@ -375,8 +362,6 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, if (patch->originy > texture->height || (patch->originy + height) < 0) return; // patch not located within texture's y bounds, ignore - palette = HWR_GetTexturePalette(); - // patch is actually inside the texture! // now check if texture is partly off-screen and adjust accordingly @@ -431,7 +416,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, pblockheight, blockmodulo, yfracstep, scale_y, patch, height, - bpp, palette); + bpp); } } @@ -478,9 +463,6 @@ static void HWR_GenerateTexture(GLMapTexture_t *grtex, INT32 texnum, boolean noe INT32 i, idx; boolean skyspecial = false; //poor hack for Legacy large skies.. - RGBA_t *palette; - palette = HWR_GetTexturePalette(); - texture = textures[texnum]; grtex->mipmap.flags = TF_CHROMAKEYED | TF_WRAPXY; @@ -497,10 +479,7 @@ static void HWR_GenerateTexture(GLMapTexture_t *grtex, INT32 texnum, boolean noe grtex->mipmap.width = (UINT16)texture->width; grtex->mipmap.height = (UINT16)texture->height; - if (skyspecial) - grtex->mipmap.format = GL_TEXFMT_RGBA; // that skyspecial code below assumes this format ... - else - grtex->mipmap.format = textureformat; + grtex->mipmap.format = textureformat; if (!noencoremap && encoremap) colormap += COLORMAP_REMAPOFFSET; @@ -519,7 +498,7 @@ static void HWR_GenerateTexture(GLMapTexture_t *grtex, INT32 texnum, boolean noe INT32 j; RGBA_t col; - col = palette[HWR_PATCHES_CHROMAKEY_COLORINDEX]; + col = V_GetColor(HWR_PATCHES_CHROMAKEY_COLORINDEX); for (idx = 0, j = 0; j < blockheight; j++) { for (i = 0; i < blockwidth; i++, idx++) @@ -1029,6 +1008,19 @@ void HWR_LoadMapTextures(size_t pnumtextures) gl_maptexturesloaded = true; } +void HWR_SetPalette(RGBA_t *palette) +{ + HWD.pfnSetPalette(palette); + + // hardware driver will flush there own cache if cache is non paletized + // now flush data texture cache so 32 bit texture are recomputed + if (patchformat == GL_TEXFMT_RGBA || textureformat == GL_TEXFMT_RGBA) + { + Z_FreeTag(PU_HWRCACHE); + Z_FreeTag(PU_HWRCACHE_UNLOCKED); + } +} + // -------------------------------------------------------------------------- // Make sure texture is downloaded and set it as the source // -------------------------------------------------------------------------- @@ -1390,7 +1382,6 @@ static void HWR_DrawPicInCache(UINT8 *block, INT32 pblockwidth, INT32 pblockheig UINT16 texelu16; INT32 picbpp; RGBA_t col; - RGBA_t *palette = HWR_GetTexturePalette(); stepy = ((INT32)SHORT(pic->height)<width)<>FRACBITS]; - col = palette[texel]; + col = V_GetColor(texel); *dest = col.s.red; // take the red level of the colour and use it for alpha, as fademasks do dest++; @@ -1624,185 +1614,4 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum) Z_ChangeTag(grmip->data, PU_HWRCACHE_UNLOCKED); } -// ================================================= -// PALETTE HANDLING -// ================================================= - -void HWR_SetPalette(RGBA_t *palette) -{ - if (HWR_ShouldUsePaletteRendering()) - { - // set the palette for palette postprocessing - - if (cv_glpalettedepth.value == 16) - { - // crush to 16-bit rgb565, like software currently does in the standard configuration - // Note: Software's screenshots have the 24-bit palette, but the screen gets - // the 16-bit version! For making comparison screenshots either use an external screenshot - // tool or set the palette depth to 24 bits. - RGBA_t crushed_palette[256]; - int i; - for (i = 0; i < 256; i++) - { - float fred = (float)(palette[i].s.red >> 3); - float fgreen = (float)(palette[i].s.green >> 2); - float fblue = (float)(palette[i].s.blue >> 3); - crushed_palette[i].s.red = (UINT8)(fred / 31.0f * 255.0f); - crushed_palette[i].s.green = (UINT8)(fgreen / 63.0f * 255.0f); - crushed_palette[i].s.blue = (UINT8)(fblue / 31.0f * 255.0f); - crushed_palette[i].s.alpha = 255; - } - HWD.pfnSetScreenPalette(crushed_palette); - } - else - { - HWD.pfnSetScreenPalette(palette); - } - - // this part is responsible for keeping track of the palette OUTSIDE of a level. - if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) - HWR_SetMapPalette(); - } - else - { - // set the palette for the textures - HWD.pfnSetTexturePalette(palette); - // reset mapPalette so next call to HWR_SetMapPalette will update everything correctly - memset(mapPalette, 0, sizeof(mapPalette)); - // hardware driver will flush there own cache if cache is non paletized - // now flush data texture cache so 32 bit texture are recomputed - if (patchformat == GL_TEXFMT_RGBA || textureformat == GL_TEXFMT_RGBA) - { - Z_FreeTag(PU_HWRCACHE); - Z_FreeTag(PU_HWRCACHE_UNLOCKED); - } - } -} - -static void HWR_SetPaletteLookup(RGBA_t *palette) -{ - int r, g, b; - UINT8 *lut = Z_Malloc( - HWR_PALETTE_LUT_SIZE*HWR_PALETTE_LUT_SIZE*HWR_PALETTE_LUT_SIZE*sizeof(UINT8), - PU_STATIC, NULL); - #define STEP_SIZE (256/HWR_PALETTE_LUT_SIZE) - for (b = 0; b < HWR_PALETTE_LUT_SIZE; b++) - { - for (g = 0; g < HWR_PALETTE_LUT_SIZE; g++) - { - for (r = 0; r < HWR_PALETTE_LUT_SIZE; r++) - { - lut[b*HWR_PALETTE_LUT_SIZE*HWR_PALETTE_LUT_SIZE+g*HWR_PALETTE_LUT_SIZE+r] = - NearestPaletteColor(r*STEP_SIZE, g*STEP_SIZE, b*STEP_SIZE, palette); - } - } - } - #undef STEP_SIZE - HWD.pfnSetPaletteLookup(lut); - Z_Free(lut); -} - -// Updates mapPalette to reflect the loaded level or other game state. -// Textures are flushed if needed. -// Call this function only in palette rendering mode. -void HWR_SetMapPalette(void) -{ - RGBA_t RGBA_converted[256]; - RGBA_t *palette; - int i; - - if (!(gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction))) - { - // outside of a level, pMasterPalette should have PLAYPAL ready for us - palette = pMasterPalette; - } - else - { - // in a level pMasterPalette might have a flash palette, but we - // want the map's original palette. - lumpnum_t lumpnum = W_GetNumForName(GetPalette()); - size_t palsize = W_LumpLength(lumpnum); - UINT8 *RGB_data; - if (palsize < 768) // 256 * 3 - I_Error("HWR_SetMapPalette: A programmer assumed palette lumps are at least 768 bytes long, but apparently this was a wrong assumption!\n"); - RGB_data = W_CacheLumpNum(lumpnum, PU_CACHE); - // we got the RGB palette now, but we need it in RGBA format. - for (i = 0; i < 256; i++) - { - RGBA_converted[i].s.red = *(RGB_data++); - RGBA_converted[i].s.green = *(RGB_data++); - RGBA_converted[i].s.blue = *(RGB_data++); - RGBA_converted[i].s.alpha = 255; - } - palette = RGBA_converted; - } - - // check if the palette has changed from the previous one - if (memcmp(mapPalette, palette, sizeof(mapPalette))) - { - memcpy(mapPalette, palette, sizeof(mapPalette)); - // in palette rendering mode, this means that all rgba textures now have wrong colors - // and the lookup table is outdated - HWR_SetPaletteLookup(mapPalette); - HWD.pfnSetTexturePalette(mapPalette); - if (patchformat == GL_TEXFMT_RGBA || textureformat == GL_TEXFMT_RGBA) - { - Z_FreeTag(PU_HWRCACHE); - Z_FreeTag(PU_HWRCACHE_UNLOCKED); - } - } -} - -// Creates a hardware lighttable from the supplied lighttable. -// Returns the id of the hw lighttable, usable in FSurfaceInfo. -UINT32 HWR_CreateLightTable(UINT8 *lighttable) -{ - UINT32 i, id; - RGBA_t *palette = HWR_GetTexturePalette(); - RGBA_t *hw_lighttable = Z_Malloc(256 * 32 * sizeof(RGBA_t), PU_STATIC, NULL); - - // To make the palette index -> RGBA mapping easier for the shader, - // the hardware lighttable is composed of RGBA colors instead of palette indices. - for (i = 0; i < 256 * 32; i++) - hw_lighttable[i] = palette[lighttable[i]]; - - id = HWD.pfnCreateLightTable(hw_lighttable); - Z_Free(hw_lighttable); - return id; -} - -// get hwr lighttable id for colormap, create it if it doesn't already exist -UINT32 HWR_GetLightTableID(extracolormap_t *colormap) -{ - boolean default_colormap = false; - if (!colormap) - { - colormap = R_GetDefaultColormap(); // a place to store the hw lighttable id - // alternatively could just store the id in a global variable if there are issues - default_colormap = true; - } - - // create hw lighttable if there isn't one - if (!colormap->gl_lighttable_id) - { - UINT8 *colormap_pointer; - - if (default_colormap) - colormap_pointer = colormaps; // don't actually use the data from the "default colormap" - else - colormap_pointer = colormap->colormap; - colormap->gl_lighttable_id = HWR_CreateLightTable(colormap_pointer); - } - - return colormap->gl_lighttable_id; -} - -// Note: all hardware lighttable ids assigned before this -// call become invalid and must not be used. -void HWR_ClearLightTables(void) -{ - if (vid.glstate == VID_GL_LIBRARY_LOADED) - HWD.pfnClearLightTables(); -} - #endif //HWRENDER diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 3a21c08cc..5e30a6fc9 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -22,12 +22,6 @@ extern "C" { #define ZCLIP_PLANE 4.0f // Used for the actual game drawing #define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures -// The width/height/depth of the palette lookup table used by palette rendering. -// Changing this also requires changing the shader code! -// Also assumed to be a power of two in some parts of the code. -// 64 seems to work perfectly for the vanilla palette. -#define HWR_PALETTE_LUT_SIZE 64 - // ========================================================================== // SIMPLE TYPES // ========================================================================== @@ -141,30 +135,33 @@ typedef struct } FOutVector; #ifdef GL_SHADERS - -// Shader targets used to render specific types of geometry. -// A shader target is resolved to an actual shader with HWR_GetShaderFromTarget. -// The shader returned may be a base shader or a custom shader. +// Predefined shader types enum { SHADER_NONE = -1, + SHADER_DEFAULT = 0, - SHADER_FLOOR = 0, + SHADER_FLOOR, SHADER_WALL, SHADER_SPRITE, - SHADER_MODEL, - SHADER_MODEL_LIGHTING, + SHADER_MODEL, SHADER_MODEL_LIGHTING, SHADER_WATER, SHADER_FOG, SHADER_SKY, - SHADER_PALETTE_POSTPROCESS, - SHADER_UI_COLORMAP_FADE, - NUMSHADERTARGETS + NUMBASESHADERS, }; -// Must be at least NUMSHADERTARGETS*2 to fit base and custom shaders for each shader target. -#define HWR_MAXSHADERS NUMSHADERTARGETS*2 +// Maximum amount of shader programs +// Must be higher than NUMBASESHADERS +#define HWR_MAXSHADERS 16 + +// Shader sources (vertex and fragment) +typedef struct +{ + char *vertex; + char *fragment; +} shadersource_t; // Custom shader reference table typedef struct @@ -293,7 +290,6 @@ struct FSurfaceInfo RGBA_t PolyColor; RGBA_t TintColor; RGBA_t FadeColor; - UINT32 LightTableId; FLightInfo LightInfo; }; typedef struct FSurfaceInfo FSurfaceInfo; @@ -301,7 +297,7 @@ typedef struct FSurfaceInfo FSurfaceInfo; #define GL_DEFAULTMIX 0x00000000 #define GL_DEFAULTFOG 0x19000000 -// Various settings and states for the rendering backend. +//Hurdler: added for backward compatibility enum hwdsetspecialstate { HWD_SET_MODEL_LIGHTING = 1, @@ -313,13 +309,15 @@ enum hwdsetspecialstate }; typedef enum hwdsetspecialstate hwdspecialstate_t; -enum hwdshaderstage +// Lactozilla: Shader options +enum hwdshaderoption { - HWD_SHADERSTAGE_VERTEX, - HWD_SHADERSTAGE_FRAGMENT, + HWD_SHADEROPTION_OFF, + HWD_SHADEROPTION_ON, + HWD_SHADEROPTION_NOCUSTOM, }; -typedef enum hwdshaderstage hwdshaderstage_t; +typedef enum hwdshaderoption hwdshaderoption_t; // Lactozilla: Shader info // Generally set at the start of the frame. @@ -345,20 +343,6 @@ enum hwdfiltermode HWD_SET_TEXTUREFILTER_MIXED3, }; -// Screen texture slots -enum hwdscreentexture -{ - HWD_SCREENTEXTURE_WIPE_START, // source image for the wipe/fade effect - HWD_SCREENTEXTURE_WIPE_END, // destination image for the wipe/fade effect - HWD_SCREENTEXTURE_GENERIC1, // underwater/heat effect, intermission background - HWD_SCREENTEXTURE_GENERIC2, // palette-based colormap fade, screen before palette rendering's postprocessing - HWD_SCREENTEXTURE_GENERIC3, // screen after palette rendering's postprocessing - HWD_SCREENTEXTURE_VHS, - NUMSCREENTEXTURES, // (generic3 is unused if palette rendering is disabled) -}; - -typedef enum hwdscreentexture hwdscreentexture_t; - #ifdef __cplusplus } // extern "C" #endif diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 2c9fb6b75..f2e3cb95a 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -534,26 +534,12 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength) if (color & 0xFF00) // Do COLORMAP fade. { - if (HWR_ShouldUsePaletteRendering()) - { - const hwdscreentexture_t scr_tex = HWD_SCREENTEXTURE_GENERIC2; - - Surf.LightTableId = HWR_GetLightTableID(NULL); - Surf.LightInfo.light_level = strength; - HWD.pfnMakeScreenTexture(scr_tex); - HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_UI_COLORMAP_FADE)); - HWD.pfnDrawScreenTexture(scr_tex, &Surf, PF_ColorMapped|PF_NoDepthTest); - HWD.pfnUnSetShader(); - - return; - } Surf.PolyColor.rgba = UINT2RGBA(0x01010160); Surf.PolyColor.s.alpha = (strength*8); } else // Do TRANSMAP** fade. { - RGBA_t *palette = HWR_GetTexturePalette(); - Surf.PolyColor.rgba = palette[color&0xFF].rgba; + Surf.PolyColor.rgba = V_GetColor(color).rgba; Surf.PolyColor.s.alpha = softwaretranstogl[strength]; } HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); @@ -634,8 +620,7 @@ void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 ac } else // Do TRANSMAP** fade. { - RGBA_t *palette = HWR_GetTexturePalette(); - Surf.PolyColor.rgba = palette[actualcolor&0xFF].rgba; + Surf.PolyColor.rgba = V_GetColor(actualcolor).rgba; Surf.PolyColor.s.alpha = softwaretranstogl[strength]; } HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); @@ -731,9 +716,8 @@ void HWR_drawAMline(const fline_t *fl, INT32 color) { F2DCoord v1, v2; RGBA_t color_rgba; - RGBA_t *palette = HWR_GetTexturePalette(); - color_rgba = palette[color&0xFF]; + color_rgba = V_GetColor(color); v1.x = ((float)fl->a.x-(vid.width/2.0f))*(2.0f/vid.width); v1.y = ((float)fl->a.y-(vid.height/2.0f))*(2.0f/vid.height); @@ -928,7 +912,6 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) float fx, fy, fw, fh; UINT8 alphalevel = ((color & V_ALPHAMASK) >> V_ALPHASHIFT); UINT8 blendmode = ((color & V_BLENDMASK) >> V_BLENDSHIFT); - RGBA_t *palette = HWR_GetTexturePalette(); // 3--2 // | /| @@ -944,7 +927,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) { if (x == 0 && y == 0 && w == BASEVIDWIDTH*FRACUNIT && h == BASEVIDHEIGHT*FRACUNIT) { - RGBA_t rgbaColour = palette[color&0xFF]; + RGBA_t rgbaColour = V_GetColor(color); FRGBAFloat clearColour; clearColour.red = (float)rgbaColour.s.red / 255; clearColour.green = (float)rgbaColour.s.green / 255; @@ -972,7 +955,7 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color) v[0].t = v[1].t = 0.0f; v[2].t = v[3].t = 1.0f; - Surf.PolyColor = palette[color&0xFF]; + Surf.PolyColor = V_GetColor(color); flags = HWR_GetBlendModeFlag(blendmode+1)|PF_Modulated|PF_NoDepthTest|PF_NoTexture; @@ -1061,7 +1044,6 @@ static inline boolean saveTGA(const char *file_name, void *buffer, UINT8 *HWR_GetScreenshot(INT32 scale) { static UINT8 *buf = NULL; - int tex = HWR_ShouldUsePaletteRendering() ? HWD_SCREENTEXTURE_GENERIC3 : HWD_SCREENTEXTURE_GENERIC2; buf = realloc(buf, (vid.width/scale)*(vid.height/scale)*3); @@ -1069,7 +1051,7 @@ UINT8 *HWR_GetScreenshot(INT32 scale) return NULL; // returns 24bit 888 RGB - HWD.pfnReadScreenTexture(tex, (void *)buf, scale); + HWD.pfnReadScreenFinalTexture(buf, scale); return buf; } diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 246bd1d02..63d78e549 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -33,7 +33,7 @@ EXPORT boolean HWRAPI(Init) (void); #ifndef HAVE_SDL EXPORT void HWRAPI(Shutdown) (void); #endif -EXPORT void HWRAPI(SetTexturePalette) (RGBA_t *ppal); +EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal); EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl); EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color); EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags); @@ -44,7 +44,7 @@ EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFl EXPORT void HWRAPI(SetTexture) (GLMipmap_t *TexInfo); EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *TexInfo); EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *TexInfo); -EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT8 *restrict dest, INT32 scale); +EXPORT void HWRAPI(ReadScreenFinalTexture) (UINT8 * restrict dest, INT32 scale); EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip); EXPORT void HWRAPI(ClearMipMapCache) (void); @@ -58,27 +58,26 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); EXPORT void HWRAPI(FlushScreenTextures) (void); -EXPORT void HWRAPI(DoScreenWipe) (int wipeStart, int wipeEnd); -EXPORT void HWRAPI(DrawScreenTexture) (int tex, FSurfaceInfo *surf, FBITFIELD polyflags); +EXPORT void HWRAPI(StartScreenWipe) (void); +EXPORT void HWRAPI(EndScreenWipe) (void); +EXPORT void HWRAPI(DoScreenWipe) (void); +EXPORT void HWRAPI(MakeIntermissionBG) (void); +EXPORT void HWRAPI(DrawIntermissionBG) (void); +EXPORT void HWRAPI(MakeScreenTexture) (void); EXPORT void HWRAPI(RenderVhsEffect) (INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize); -EXPORT void HWRAPI(MakeScreenTexture) (int tex); -EXPORT void HWRAPI(DrawScreenFinalTexture) (int tex, int width, int height); +EXPORT void HWRAPI(MakeScreenFinalTexture) (void); +EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height); #define SCREENVERTS 10 EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); -EXPORT boolean HWRAPI(InitShaders) (void); -EXPORT void HWRAPI(LoadShader) (int slot, char *code, hwdshaderstage_t stage); -EXPORT boolean HWRAPI(CompileShader) (int slot); -EXPORT void HWRAPI(SetShader) (int slot); +EXPORT boolean HWRAPI(CompileShaders) (void); +EXPORT void HWRAPI(CleanShaders) (void); +EXPORT void HWRAPI(SetShader) (int type); EXPORT void HWRAPI(UnSetShader) (void); EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value); - -EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut); -EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable); -EXPORT void HWRAPI(ClearLightTables)(void); -EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette); +EXPORT void HWRAPI(LoadCustomShader) (int number, char *code, size_t size, boolean isfragment); // ========================================================================== // HWR DRIVER OBJECT, FOR CLIENT PROGRAM @@ -89,7 +88,7 @@ EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette); struct hwdriver_s { Init pfnInit; - SetTexturePalette pfnSetTexturePalette; + SetPalette pfnSetPalette; FinishUpdate pfnFinishUpdate; Draw2DLine pfnDraw2DLine; DrawPolygon pfnDrawPolygon; @@ -100,10 +99,10 @@ struct hwdriver_s SetTexture pfnSetTexture; UpdateTexture pfnUpdateTexture; DeleteTexture pfnDeleteTexture; - ReadScreenTexture pfnReadScreenTexture; + ReadScreenFinalTexture pfnReadScreenFinalTexture; GClipRect pfnGClipRect; ClearMipMapCache pfnClearMipMapCache; - SetSpecialState pfnSetSpecialState; + SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility DrawModel pfnDrawModel; CreateModelVBOs pfnCreateModelVBOs; SetTransform pfnSetTransform; @@ -113,24 +112,23 @@ struct hwdriver_s #endif PostImgRedraw pfnPostImgRedraw; FlushScreenTextures pfnFlushScreenTextures; + StartScreenWipe pfnStartScreenWipe; + EndScreenWipe pfnEndScreenWipe; DoScreenWipe pfnDoScreenWipe; - RenderVhsEffect pfnRenderVhsEffect; - DrawScreenTexture pfnDrawScreenTexture; + MakeIntermissionBG pfnMakeIntermissionBG; + DrawIntermissionBG pfnDrawIntermissionBG; MakeScreenTexture pfnMakeScreenTexture; + RenderVhsEffect pfnRenderVhsEffect; + MakeScreenFinalTexture pfnMakeScreenFinalTexture; DrawScreenFinalTexture pfnDrawScreenFinalTexture; - InitShaders pfnInitShaders; - LoadShader pfnLoadShader; - CompileShader pfnCompileShader; + CompileShaders pfnCompileShaders; + CleanShaders pfnCleanShaders; SetShader pfnSetShader; UnSetShader pfnUnSetShader; SetShaderInfo pfnSetShaderInfo; - - SetPaletteLookup pfnSetPaletteLookup; - CreateLightTable pfnCreateLightTable; - ClearLightTables pfnClearLightTables; - SetScreenPalette pfnSetScreenPalette; + LoadCustomShader pfnLoadCustomShader; }; extern struct hwdriver_s hwdriver; diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index ca7b514b5..f04ef1f0b 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -108,8 +108,6 @@ void HWR_FreeExtraSubsectors(void); // -------- // hw_cache.c // -------- -RGBA_t *HWR_GetTexturePalette(void); - void HWR_InitMapTextures(void); void HWR_LoadMapTextures(size_t pnumtextures); void HWR_FreeMapTextures(void); @@ -135,10 +133,7 @@ void HWR_FreeColormapCache(void); void HWR_UnlockCachedPatch(GLPatch_t *gpatch); void HWR_SetPalette(RGBA_t *palette); -void HWR_SetMapPalette(void); -UINT32 HWR_CreateLightTable(UINT8 *lighttable); -UINT32 HWR_GetLightTableID(extracolormap_t *colormap); -void HWR_ClearLightTables(void); + // -------- // hw_draw.c @@ -146,20 +141,6 @@ void HWR_ClearLightTables(void); extern INT32 patchformat; extern INT32 textureformat; -// -------- -// hw_shaders.c -// -------- -boolean HWR_InitShaders(void); -void HWR_CompileShaders(void); - -int HWR_GetShaderFromTarget(int shader_target); - -void HWR_LoadAllCustomShaders(void); -void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3); -const char *HWR_GetShaderName(INT32 shader); - -extern customshaderxlat_t shaderxlat[]; - #ifdef __cplusplus } // extern "C" #endif diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 1c7353b81..9a4430c4a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -131,6 +131,26 @@ static line_t *gl_linedef; static sector_t *gl_frontsector; static sector_t *gl_backsector; +// -------------------------------------------------------------------------- +// STUFF FOR THE PROJECTION CODE +// -------------------------------------------------------------------------- + +FTransform atransform; +// duplicates of the main code, set after R_SetupFrame() passed them into sharedstruct, +// copied here for local use +static fixed_t dup_viewx, dup_viewy, dup_viewz; +static angle_t dup_viewangle; + +static float gl_viewx, gl_viewy, gl_viewz; +float gl_viewsin, gl_viewcos; + +// Maybe not necessary with the new T&L code (needs to be checked!) +static float gl_viewludsin, gl_viewludcos; // look up down kik test +static float gl_fovlud; + +static angle_t gl_aimingangle; +static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); + // Render stats precise_t ps_hw_skyboxtime = 0; precise_t ps_hw_nodesorttime = 0; @@ -152,38 +172,13 @@ precise_t ps_hw_batchdrawtime = 0; boolean gl_init = false; boolean gl_maploaded = false; boolean gl_sessioncommandsadded = false; -// false if shaders have not been initialized yet, or if shaders are not available -boolean gl_shadersavailable = false; - -// Whether the internal state is set to palette rendering or not. -static boolean gl_palette_rendering_state = false; - -// -------------------------------------------------------------------------- -// STUFF FOR THE PROJECTION CODE -// -------------------------------------------------------------------------- - -FTransform atransform; -// duplicates of the main code, set after R_SetupFrame() passed them into sharedstruct, -// copied here for local use -static fixed_t dup_viewx, dup_viewy, dup_viewz; -static angle_t dup_viewangle; - -static float gl_viewx, gl_viewy, gl_viewz; -float gl_viewsin, gl_viewcos; - -// Maybe not necessary with the new T&L code (needs to be checked!) -static float gl_viewludsin, gl_viewludcos; // look up down kik test -static float gl_fovlud; - -static angle_t gl_aimingangle; -static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean skybox); +boolean gl_shadersavailable = true; // ========================================================================== // Lighting // ========================================================================== -// Returns true if shaders can be used. -boolean HWR_UseShader(void) +static boolean HWR_UseShader(void) { return (cv_glshaders.value && gl_shadersavailable); } @@ -315,11 +310,6 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col Surface->LightInfo.newfade = (colormap != NULL) ? !!(colormap->flags & CMF_NEWFADE) : false; Surface->LightInfo.directional = (maplighting.directional == true && directional == true); - - if (HWR_ShouldUsePaletteRendering()) - Surface->LightTableId = HWR_GetLightTableID(colormap); - else - Surface->LightTableId = 0; } UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work @@ -409,7 +399,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool static FOutVector *planeVerts = NULL; static UINT16 numAllocedPlaneVerts = 0; - INT32 shader = SHADER_NONE; + INT32 shader = SHADER_DEFAULT; // no convex poly were generated for this subsector if (!xsub->planepoly) @@ -738,7 +728,7 @@ static void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, I // static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap) { - INT32 shader = SHADER_NONE; + INT32 shader = SHADER_DEFAULT; HWR_Lighting(pSurf, lightlevel, wallcolormap, P_SectorUsesDirectionalLighting(gl_frontsector)); @@ -2371,7 +2361,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, { FSurfaceInfo Surf; FOutVector *v3d; - INT32 shader = SHADER_NONE; + INT32 shader = SHADER_DEFAULT; size_t nrPlaneVerts = polysector->numVertices; INT32 i; @@ -3136,7 +3126,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) float fscale; float fx; float fy; float offset; extracolormap_t *colormap = NULL; FBITFIELD blendmode = PF_ReverseSubtract; - INT32 shader = SHADER_NONE; + INT32 shader = SHADER_DEFAULT; UINT8 i; INT32 heightsec, phs; SINT8 flip = P_MobjFlip(thing); @@ -3328,7 +3318,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) boolean lightset = true; FBITFIELD blend = 0; FBITFIELD occlusion; - INT32 shader = SHADER_NONE; + INT32 shader = SHADER_DEFAULT; boolean use_linkdraw_hack = false; UINT8 alpha; @@ -3916,7 +3906,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) } { - INT32 shader = SHADER_NONE; + INT32 shader = SHADER_DEFAULT; FBITFIELD blend = 0; FBITFIELD occlusion; boolean use_linkdraw_hack = false; @@ -3991,7 +3981,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) // Sprite drawer for precipitation static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) { - INT32 shader = SHADER_NONE; + INT32 shader = SHADER_DEFAULT; FBITFIELD blend = 0; FOutVector wallVerts[4]; patch_t *gpatch; @@ -4478,6 +4468,7 @@ static void HWR_CreateDrawNodes(void) // Okay! Let's draw it all! Woo! HWD.pfnSetTransform(&atransform); + HWD.pfnSetShader(SHADER_DEFAULT); for (i = 0; i < p; i++) { @@ -5594,9 +5585,7 @@ static void HWR_DrawSkyBackground(player_t *player) HWR_BuildSkyDome(); } - if (HWR_UseShader()) - HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_SKY)); - + HWD.pfnSetShader(SHADER_SKY); // sky shader HWD.pfnSetTransform(&dometransform); HWD.pfnRenderSkyDome(&gl_sky); } @@ -5682,6 +5671,8 @@ static void HWR_DrawSkyBackground(player_t *player) HWD.pfnUnSetShader(); HWD.pfnDrawPolygon(NULL, v, 4, 0); } + + HWD.pfnSetShader(SHADER_DEFAULT); } @@ -5797,7 +5788,13 @@ static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean // static void HWR_SetShaderState(void) { - HWD.pfnSetSpecialState(HWD_SET_SHADERS, (INT32)HWR_UseShader()); + hwdshaderoption_t state = cv_glshaders.value; + + if (!cv_glallowshaders.value) + state = (cv_glshaders.value == HWD_SHADEROPTION_ON ? HWD_SHADEROPTION_NOCUSTOM : cv_glshaders.value); + + HWD.pfnSetSpecialState(HWD_SET_SHADERS, (INT32)state); + HWD.pfnSetShader(SHADER_DEFAULT); } static void HWR_ClearClipper(void) @@ -5819,7 +5816,6 @@ void HWR_RenderSkyboxView(player_t *player) camera_t *thiscam = &camera[viewnum]; const float fpov = FIXED_TO_FLOAT(cv_fov[viewssnum].value+player->fovadd); - if (!HWR_ShouldUsePaletteRendering()) { // do we really need to save player (is it not the same)? player_t *saved_player = stplyr; @@ -6163,56 +6159,6 @@ void HWR_RenderPlayerView(void) HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE); } -// Returns whether palette rendering is "actually enabled." -// Can't have palette rendering if shaders are disabled. -boolean HWR_ShouldUsePaletteRendering(void) -{ - return (cv_glpaletterendering.value && HWR_UseShader()); -} - -// enable or disable palette rendering state depending on settings and availability -// called when relevant settings change -// shader recompilation is done in the cvar callback -static void HWR_TogglePaletteRendering(void) -{ - // which state should we go to? - if (HWR_ShouldUsePaletteRendering()) - { - // are we not in that state already? - if (!gl_palette_rendering_state) - { - gl_palette_rendering_state = true; - - // The textures will still be converted to RGBA by r_opengl. - // This however makes hw_cache use paletted blending for composite textures! - // (patchformat is not touched) - textureformat = GL_TEXFMT_P_8; - - HWR_SetMapPalette(); - HWR_SetPalette(pLocalPalette); - - // If the r_opengl "texture palette" stays the same during this switch, these textures - // will not be cleared out. However they are still out of date since the - // composite texture blending method has changed. Therefore they need to be cleared. - HWR_LoadMapTextures(numtextures); - } - } - else - { - // are we not in that state already? - if (gl_palette_rendering_state) - { - gl_palette_rendering_state = false; - textureformat = GL_TEXFMT_RGBA; - HWR_SetPalette(pLocalPalette); - // If the r_opengl "texture palette" stays the same during this switch, these textures - // will not be cleared out. However they are still out of date since the - // composite texture blending method has changed. Therefore they need to be cleared. - HWR_LoadMapTextures(numtextures); - } - } -} - void HWR_LoadLevel(void) { #ifdef ALAM_LIGHTING @@ -6226,9 +6172,6 @@ void HWR_LoadLevel(void) HWR_ClearSkyDome(); HWR_BuildSkyDome(); - if (HWR_ShouldUsePaletteRendering()) - HWR_SetMapPalette(); - gl_maploaded = true; } @@ -6236,7 +6179,7 @@ void HWR_LoadLevel(void) // 3D ENGINE COMMANDS // ========================================================================== -CV_PossibleValue_t glshaders_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Ignore custom shaders"}, {0, NULL}}; +static CV_PossibleValue_t glshaders_cons_t[] = {{HWD_SHADEROPTION_OFF, "Off"}, {HWD_SHADEROPTION_ON, "On"}, {HWD_SHADEROPTION_NOCUSTOM, "Ignore custom shaders"}, {0, NULL}}; #ifdef BAD_MODEL_OPTIONS static CV_PossibleValue_t glmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; #endif @@ -6284,65 +6227,16 @@ consvar_t cv_glsolvetjoin = CVAR_INIT ("gr_solvetjoin", "On", 0, CV_OnOff, NULL) consvar_t cv_glbatching = CVAR_INIT ("gr_batching", "On", 0, CV_OnOff, NULL); -CV_PossibleValue_t glpalettedepth_cons_t[] = {{16, "16 bits"}, {24, "24 bits"}, {0, NULL}}; -void CV_glpaletterendering_OnChange(void); -void CV_glpalettedepth_OnChange(void); - -consvar_t cv_glpaletterendering = CVAR_INIT ("gr_paletteshader", "Off", CV_CALL|CV_SAVE, CV_OnOff, CV_glpaletterendering_OnChange); -consvar_t cv_glpalettedepth = CVAR_INIT ("gr_palettedepth", "16 bits", CV_SAVE|CV_CALL, glpalettedepth_cons_t, CV_glpalettedepth_OnChange); - -#define ONLY_IF_GL_LOADED if (vid.glstate != VID_GL_LIBRARY_LOADED) return; - static void CV_glfiltermode_OnChange(void) { - ONLY_IF_GL_LOADED - HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_glfiltermode.value); + if (rendermode == render_opengl) + HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_glfiltermode.value); } static void CV_glanisotropic_OnChange(void) { - ONLY_IF_GL_LOADED - HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_glanisotropicmode.value); -} - -void CV_glmodellighting_OnChange(void); -void CV_glmodellighting_OnChange(void) -{ - ONLY_IF_GL_LOADED - // if shaders have been compiled, then they now need to be recompiled. - if (gl_shadersavailable) - HWR_CompileShaders(); -} - -void CV_glpaletterendering_OnChange(void) -{ - ONLY_IF_GL_LOADED - if (gl_shadersavailable) - { - HWR_CompileShaders(); - HWR_TogglePaletteRendering(); - } -} - -void CV_glpalettedepth_OnChange(void); -void CV_glpalettedepth_OnChange(void) -{ - ONLY_IF_GL_LOADED - // refresh the screen palette - if (HWR_ShouldUsePaletteRendering()) - HWR_SetPalette(pLocalPalette); -} - -void CV_glshaders_OnChange(void); -void CV_glshaders_OnChange(void) -{ - ONLY_IF_GL_LOADED - HWR_SetShaderState(); - if (cv_glpaletterendering.value) - { - // can't do palette rendering without shaders, so update the state if needed - HWR_TogglePaletteRendering(); - } + if (rendermode == render_opengl) + HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_glanisotropicmode.value); } //added by Hurdler: console varibale that are saved @@ -6377,9 +6271,6 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_glbatching); CV_RegisterVar(&cv_glanisotropicmode); - - CV_RegisterVar(&cv_glpaletterendering); - CV_RegisterVar(&cv_glpalettedepth); } void HWR_AddSessionCommands(void) @@ -6398,8 +6289,6 @@ void HWR_Startup(void) { CONS_Printf("HWR_Startup()...\n"); - textureformat = patchformat = GL_TEXFMT_RGBA; - HWR_InitPolyPool(); HWR_AddSessionCommands(); HWR_InitMapTextures(); @@ -6408,12 +6297,14 @@ void HWR_Startup(void) HWR_InitLight(); #endif - gl_shadersavailable = HWR_InitShaders(); - HWR_SetShaderState(); HWR_LoadAllCustomShaders(); - HWR_TogglePaletteRendering(); + if (!HWR_CompileShaders()) + gl_shadersavailable = false; } + if (rendermode == render_opengl) + textureformat = patchformat = GL_TEXFMT_RGBA; + gl_init = true; } @@ -6508,7 +6399,7 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, FBITFIELD blendmode = blend; UINT8 alpha = pSurf->PolyColor.s.alpha; // retain the alpha - INT32 shader = SHADER_NONE; + INT32 shader = SHADER_DEFAULT; // Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting HWR_Lighting(pSurf, lightlevel, wallcolormap, P_SectorUsesDirectionalLighting(gl_frontsector)); @@ -6546,7 +6437,7 @@ void HWR_DoPostProcessor(player_t *player) // Armageddon Blast Flash! // Could this even be considered postprocessor? - if (player->flashcount && !HWR_ShouldUsePaletteRendering()) + if (player->flashcount) { FOutVector v[4]; FSurfaceInfo Surf; @@ -6572,8 +6463,7 @@ void HWR_DoPostProcessor(player_t *player) } // Capture the screen for intermission and screen waving - if (gamestate != GS_INTERMISSION) - HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_GENERIC1); + HWD.pfnMakeScreenTexture(); if (r_splitscreen) // Not supported in splitscreen - someone want to add support? return; @@ -6618,10 +6508,6 @@ void HWR_DoPostProcessor(player_t *player) } } HWD.pfnPostImgRedraw(v); - - // Capture the screen again for screen waving on the intermission - if (gamestate != GS_INTERMISSION) - HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_GENERIC1); } // Flipping of the screen isn't done here anymore } @@ -6629,18 +6515,23 @@ void HWR_DoPostProcessor(player_t *player) void HWR_StartScreenWipe(void) { //CONS_Debug(DBG_RENDER, "In HWR_StartScreenWipe()\n"); - HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_WIPE_START); + HWD.pfnStartScreenWipe(); } void HWR_EndScreenWipe(void) { //CONS_Debug(DBG_RENDER, "In HWR_EndScreenWipe()\n"); - HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_WIPE_END); + HWD.pfnEndScreenWipe(); +} + +void HWR_MakeIntermissionBG(void) +{ + HWD.pfnMakeIntermissionBG(); } void HWR_DrawIntermissionBG(void) { - HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1, NULL, 0); + HWD.pfnDrawIntermissionBG(); } // @@ -6685,7 +6576,7 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum) return; HWR_GetFadeMask(wipelumpnum); - HWD.pfnDoScreenWipe(HWD_SCREENTEXTURE_WIPE_START, HWD_SCREENTEXTURE_WIPE_END); + HWD.pfnDoScreenWipe(); } void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum) @@ -6701,14 +6592,190 @@ void HWR_RenderVhsEffect(INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 do void HWR_MakeScreenFinalTexture(void) { - int tex = HWR_ShouldUsePaletteRendering() ? HWD_SCREENTEXTURE_GENERIC3 : HWD_SCREENTEXTURE_GENERIC2; - HWD.pfnMakeScreenTexture(tex); + HWD.pfnMakeScreenFinalTexture(); } void HWR_DrawScreenFinalTexture(int width, int height) { - int tex = HWR_ShouldUsePaletteRendering() ? HWD_SCREENTEXTURE_GENERIC3 : HWD_SCREENTEXTURE_GENERIC2; - HWD.pfnDrawScreenFinalTexture(tex, width, height); + HWD.pfnDrawScreenFinalTexture(width, height); +} + +static inline UINT16 HWR_FindShaderDefs(UINT16 wadnum) +{ + UINT16 i; + lumpinfo_t *lump_p; + + lump_p = wadfiles[wadnum]->lumpinfo; + for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lump_p++) + if (memcmp(lump_p->name, "SHADERS", 7) == 0) + return i; + + return INT16_MAX; +} + +boolean HWR_CompileShaders(void) +{ + return HWD.pfnCompileShaders(); +} + +customshaderxlat_t shaderxlat[] = +{ + {"Flat", SHADER_FLOOR}, + {"WallTexture", SHADER_WALL}, + {"Sprite", SHADER_SPRITE}, + {"Model", SHADER_MODEL}, + {"ModelLighting", SHADER_MODEL_LIGHTING}, + {"WaterRipple", SHADER_WATER}, + {"Fog", SHADER_FOG}, + {"Sky", SHADER_SKY}, + {NULL, 0}, +}; + +void HWR_LoadAllCustomShaders(void) +{ + INT32 i; + + // read every custom shader + for (i = 0; i < numwadfiles; i++) + HWR_LoadCustomShadersFromFile(i, (wadfiles[i]->type == RET_PK3)); +} + +void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3) +{ + UINT16 lump; + char *shaderdef, *line; + char *stoken; + char *value; + size_t size; + int linenum = 1; + int shadertype = 0; + int i; + + lump = HWR_FindShaderDefs(wadnum); + if (lump == INT16_MAX) + return; + + shaderdef = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE); + size = W_LumpLengthPwad(wadnum, lump); + + line = Z_Malloc(size+1, PU_STATIC, NULL); + memcpy(line, shaderdef, size); + line[size] = '\0'; + + stoken = strtok(line, "\r\n "); + while (stoken) + { + if ((stoken[0] == '/' && stoken[1] == '/') + || (stoken[0] == '#'))// skip comments + { + stoken = strtok(NULL, "\r\n"); + goto skip_field; + } + + if (!stricmp(stoken, "GLSL")) + { + value = strtok(NULL, "\r\n "); + if (!value) + { + CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + stoken = strtok(NULL, "\r\n"); // skip end of line + goto skip_lump; + } + + if (!stricmp(value, "VERTEX")) + shadertype = 1; + else if (!stricmp(value, "FRAGMENT")) + shadertype = 2; + +skip_lump: + stoken = strtok(NULL, "\r\n "); + linenum++; + } + else + { + value = strtok(NULL, "\r\n= "); + if (!value) + { + CONS_Alert(CONS_WARNING, "HWR_LoadCustomShadersFromFile: Missing shader target (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + stoken = strtok(NULL, "\r\n"); // skip end of line + goto skip_field; + } + + if (!shadertype) + { + CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + Z_Free(line); + return; + } + + for (i = 0; shaderxlat[i].type; i++) + { + if (!stricmp(shaderxlat[i].type, stoken)) + { + size_t shader_size; + char *shader_source; + char *shader_lumpname; + UINT16 shader_lumpnum; + + if (PK3) + { + shader_lumpname = Z_Malloc(strlen(value) + 12, PU_STATIC, NULL); + strcpy(shader_lumpname, "Shaders/sh_"); + strcat(shader_lumpname, value); + shader_lumpnum = W_CheckNumForFullNamePK3(shader_lumpname, wadnum, 0); + } + else + { + shader_lumpname = Z_Malloc(strlen(value) + 4, PU_STATIC, NULL); + strcpy(shader_lumpname, "SH_"); + strcat(shader_lumpname, value); + shader_lumpnum = W_CheckNumForNamePwad(shader_lumpname, wadnum, 0); + } + + if (shader_lumpnum == INT16_MAX) + { + CONS_Alert(CONS_ERROR, "HWR_LoadCustomShadersFromFile: Missing shader source %s (file %s, line %d)\n", shader_lumpname, wadfiles[wadnum]->filename, linenum); + Z_Free(shader_lumpname); + continue; + } + + shader_size = W_LumpLengthPwad(wadnum, shader_lumpnum); + shader_source = Z_Malloc(shader_size, PU_STATIC, NULL); + W_ReadLumpPwad(wadnum, shader_lumpnum, shader_source); + + HWD.pfnLoadCustomShader(shaderxlat[i].id, shader_source, shader_size, (shadertype == 2)); + + Z_Free(shader_source); + Z_Free(shader_lumpname); + } + } + +skip_field: + stoken = strtok(NULL, "\r\n= "); + linenum++; + } + } + + Z_Free(line); + return; +} + +const char *HWR_GetShaderName(INT32 shader) +{ + INT32 i; + + if (shader) + { + for (i = 0; shaderxlat[i].type; i++) + { + if (shaderxlat[i].id == shader) + return shaderxlat[i].type; + } + + return "Unknown"; + } + + return "Default"; } #endif // HWRENDER diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index f60ec4a33..d73e161c9 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -70,7 +70,6 @@ void HWR_MakeScreenFinalTexture(void); void HWR_DrawScreenFinalTexture(int width, int height); // This stuff is put here so models can use them -boolean HWR_UseShader(void); boolean HWR_OverrideObjectLightLevel(mobj_t *thing, INT32 *lightlevel); void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap, const boolean directional); UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work @@ -80,7 +79,13 @@ FBITFIELD HWR_GetBlendModeFlag(INT32 ast); FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf); FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf); -boolean HWR_ShouldUsePaletteRendering(void); +boolean HWR_CompileShaders(void); + +void HWR_LoadAllCustomShaders(void); +void HWR_LoadCustomShadersFromFile(UINT16 wadnum, boolean PK3); +const char *HWR_GetShaderName(INT32 shader); + +extern customshaderxlat_t shaderxlat[]; extern CV_PossibleValue_t glanisotropicmode_cons_t[]; @@ -115,8 +120,6 @@ extern consvar_t cv_glspritebillboarding; extern consvar_t cv_glskydome; extern consvar_t cv_glbatching; -extern consvar_t cv_glpaletterendering; -extern consvar_t cv_glpalettedepth; extern float gl_viewwidth, gl_viewheight, gl_baseviewwindowy; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 8ba786970..f80f6bf86 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -391,6 +391,8 @@ static void md2_loadTexture(md2_t *model) if (!grPatch->mipmap->downloaded && !grPatch->mipmap->data) { int w = 0, h = 0; + UINT32 size; + RGBA_t *image; #ifdef HAVE_PNG grPatch->mipmap->format = PNG_Load(filename, &w, &h, grPatch); @@ -411,19 +413,13 @@ static void md2_loadTexture(md2_t *model) grPatch->mipmap->width = (UINT16)w; grPatch->mipmap->height = (UINT16)h; - // for palette rendering, color cube is applied in post-processing instead of here - if (!HWR_ShouldUsePaletteRendering()) + // Lactozilla: Apply colour cube + image = grPatch->mipmap->data; + size = w*h; + while (size--) { - UINT32 size; - RGBA_t *image; - // Lactozilla: Apply colour cube - image = grPatch->mipmap->data; - size = w*h; - while (size--) - { - V_CubeApply(&image->s.red, &image->s.green, &image->s.blue); - image++; - } + V_CubeApply(&image->s.red, &image->s.green, &image->s.blue); + image++; } } @@ -1718,8 +1714,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) p.flip = atransform.flip; p.mirror = atransform.mirror; - if (HWR_UseShader()) - HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_MODEL)); + HWD.pfnSetShader(SHADER_MODEL); // model shader { float this_scale = FIXED_TO_FLOAT(interp.scale); fixed_t floorClip = spr->mobj->terrain ? spr->mobj->terrain->floorClip : 0; diff --git a/src/hardware/hw_shaders.h b/src/hardware/hw_shaders.h deleted file mode 100644 index f86ec2857..000000000 --- a/src/hardware/hw_shaders.h +++ /dev/null @@ -1,425 +0,0 @@ -// SONIC ROBO BLAST 2 -//----------------------------------------------------------------------------- -// Copyright (C) 2021 by Sonic Team Junior. -// -// This program is free software distributed under the -// terms of the GNU General Public License, version 2. -// See the 'LICENSE' file for more details. -//----------------------------------------------------------------------------- -/// \file hw_shaders.h -/// \brief Handles the shaders used by the game. - -#ifndef _HW_SHADERS_H_ -#define _HW_SHADERS_H_ - -#include "../doomtype.h" - -// ================ -// Vertex shaders -// ================ - -// -// Generic vertex shader -// - -#define GLSL_DEFAULT_VERTEX_SHADER \ - "void main()\n" \ - "{\n" \ - "gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \ - "gl_FrontColor = gl_Color;\n" \ - "gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \ - "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ - "}\0" - -// reinterpretation of sprite lighting for models -// it's a combination of how it works for normal sprites & papersprites -#define GLSL_MODEL_LIGHTING_VERTEX_SHADER \ - "uniform float lighting;\n" \ - "uniform vec3 light_dir;\n" \ - "uniform float light_contrast;\n" \ - "uniform float light_backlight;\n" \ - "void main()\n" \ - "{\n" \ - "gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \ - "float light = lighting;\n" \ - "if (length(light_dir) > 0.000001) {\n" \ - "mat4 m4 = gl_ProjectionMatrix * gl_ModelViewMatrix;\n" \ - "mat3 m3 = mat3( m4[0].xyz, m4[1].xyz, m4[2].xyz );\n" \ - "float extralight = -dot(normalize(gl_Normal * m3), normalize(light_dir));\n" \ - "extralight *= light_contrast - light_backlight;\n" \ - "extralight *= lighting / 255.0;\n" \ - "light += extralight * 2.5;\n" \ - "}\n" \ - "light = clamp(light / 255.0, 0.0, 1.0);\n" \ - "gl_FrontColor = vec4(light, light, light, 1.0);\n" \ - "gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \ - "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ - "}\0" - -// ================== -// Fragment shaders -// ================== - -// -// Generic fragment shader -// - -#define GLSL_DEFAULT_FRAGMENT_SHADER \ - "uniform sampler2D tex;\n" \ - "uniform vec4 poly_color;\n" \ - "void main(void) {\n" \ - "gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * poly_color;\n" \ - "}\0" - -// -// Software fragment shader -// - -// Include GLSL_FLOOR_FUDGES or GLSL_WALL_FUDGES or define the fudges in shaders that use this macro. -#define GLSL_DOOM_COLORMAP \ - "float R_DoomColormap(float light, float z)\n" \ - "{\n" \ - "float lightnum = clamp(light / 17.0, 0.0, 15.0);\n" \ - "float lightz = clamp(z / 16.0, 0.0, 127.0);\n" \ - "float startmap = (15.0 - lightnum) * 4.0;\n" \ - "float scale = 160.0 / (lightz + 1.0);\n" \ - "return startmap - scale * 0.5;\n" \ - "}\n" -// lighting cap adjustment: -// first num (155.0), increase to make it start to go dark sooner -// second num (0.26), increase to make it go dark faster - -#define GLSL_DOOM_LIGHT_EQUATION \ - "float R_DoomLightingEquation(float light)\n" \ - "{\n" \ - "float z = gl_FragCoord.z / gl_FragCoord.w;\n" \ - "float colormap = floor(R_DoomColormap(light, z)) + 0.5;\n" \ - "return clamp(colormap, 0.0, 31.0) / 32.0;\n" \ - "}\n" - -#define GLSL_SOFTWARE_TINT_EQUATION \ - "if (mix(tint_color.a, 0.0, brightmap_mix) > 0.0) {\n" \ - "float color_bright = sqrt((base_color.r * base_color.r) + (base_color.g * base_color.g) + (base_color.b * base_color.b));\n" \ - "float strength = sqrt(9.0 * mix(tint_color.a, 0.0, brightmap_mix));\n" \ - "final_color.r = clamp((color_bright * (tint_color.r * strength)) + (base_color.r * (1.0 - strength)), 0.0, 1.0);\n" \ - "final_color.g = clamp((color_bright * (tint_color.g * strength)) + (base_color.g * (1.0 - strength)), 0.0, 1.0);\n" \ - "final_color.b = clamp((color_bright * (tint_color.b * strength)) + (base_color.b * (1.0 - strength)), 0.0, 1.0);\n" \ - "}\n" - -#define GLSL_SOFTWARE_FADE_EQUATION \ - "float darkness = R_DoomLightingEquation(final_lighting);\n" \ - "if (fade_start > 0.0 || fade_end < 31.0) {\n" \ - "float fs = fade_start / 31.0;\n" \ - "float fe = fade_end / 31.0;\n" \ - "float fd = fe - fs;\n" \ - "darkness = clamp((darkness - fs) * (1.0 / fd), 0.0, 1.0);\n" \ - "}\n" \ - "float colorBrightness = sqrt((final_color.r * final_color.r) + (final_color.g * final_color.g) + (final_color.b * final_color.b));\n" \ - "float fogBrightness = sqrt((fade_color.r * fade_color.r) + (fade_color.g * fade_color.g) + (fade_color.b * fade_color.b));\n" \ - "float colorIntensity = 0.0;\n" \ - "if (colorBrightness < fogBrightness) {\n" \ - "colorIntensity = 1.0 - min(final_color.r, min(final_color.g, final_color.b));\n" \ - "colorIntensity = abs(colorIntensity - (1.0 - max(fade_color.r, max(fade_color.g, fade_color.b))));\n" \ - "} else {\n" \ - "colorIntensity = max(final_color.r, max(final_color.g, final_color.b));\n" \ - "colorIntensity = abs(colorIntensity - min(fade_color.r, min(fade_color.g, fade_color.b)));\n" \ - "}\n" \ - "colorIntensity *= darkness;\n" \ - "colorIntensity *= fade_color.a * 10.0;\n" \ - "if (abs(final_color.r - fade_color.r) <= colorIntensity) {\n" \ - " final_color.r = fade_color.r;\n" \ - "} else if (final_color.r < fade_color.r) {\n" \ - "final_color.r += colorIntensity;\n" \ - "} else {\n" \ - "final_color.r -= colorIntensity;\n" \ - "}\n" \ - "if (abs(final_color.g - fade_color.g) <= colorIntensity) {\n" \ - "final_color.g = fade_color.g;\n" \ - "} else if (final_color.g < fade_color.g) {\n" \ - "final_color.g += colorIntensity;\n" \ - "} else {\n" \ - "final_color.g -= colorIntensity;\n" \ - "}\n" \ - "if (abs(final_color.b - fade_color.b) <= colorIntensity) {\n" \ - "final_color.b = fade_color.b;\n" \ - "} else if (final_color.b < fade_color.b) {\n" \ - "final_color.b += colorIntensity;\n" \ - "} else {\n" \ - "final_color.b -= colorIntensity;\n" \ - "}\n" - -#define GLSL_PALETTE_RENDERING \ - "float tex_pal_idx = texture3D(palette_lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0;\n" \ - "float z = gl_FragCoord.z / gl_FragCoord.w;\n" \ - "float light_y = clamp(floor(R_DoomColormap(lighting, z)), 0.0, 31.0);\n" \ - "vec2 lighttable_coord = vec2((tex_pal_idx + 0.5) / 256.0, (light_y + 0.5) / 32.0);\n" \ - "vec4 final_color = texture2D(lighttable_tex, lighttable_coord);\n" \ - "final_color.a = texel.a * poly_color.a;\n" \ - "float brightmap_mix = floor(texture2D(brightmap, gl_TexCoord[0].st).r);\n" \ - "float light_gain = (255.0 - lighting) * brightmap_mix;\n" \ - "float final_lighting = lighting + light_gain;\n" \ - "gl_FragColor = final_color;\n" \ - -#define GLSL_SOFTWARE_FRAGMENT_SHADER \ - "#ifdef SRB2_PALETTE_RENDERING\n" \ - "uniform sampler2D tex;\n" \ - "uniform sampler2D brightmap;\n" \ - "uniform sampler3D palette_lookup_tex;\n" \ - "uniform sampler2D lighttable_tex;\n" \ - "uniform vec4 poly_color;\n" \ - "uniform float lighting;\n" \ - GLSL_DOOM_COLORMAP \ - "void main(void) {\n" \ - "vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \ - GLSL_PALETTE_RENDERING \ - "}\n" \ - "#else\n" \ - "uniform sampler2D tex;\n" \ - "uniform sampler2D brightmap;\n" \ - "uniform vec4 poly_color;\n" \ - "uniform vec4 tint_color;\n" \ - "uniform vec4 fade_color;\n" \ - "uniform float lighting;\n" \ - "uniform float fade_start;\n" \ - "uniform float fade_end;\n" \ - GLSL_DOOM_COLORMAP \ - GLSL_DOOM_LIGHT_EQUATION \ - "void main(void) {\n" \ - "vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \ - "vec4 base_color = texel * poly_color;\n" \ - "vec4 final_color = base_color;\n" \ - "float brightmap_mix = floor(texture2D(brightmap, gl_TexCoord[0].st).r);\n" \ - "float light_gain = (255.0 - lighting) * brightmap_mix;\n" \ - "float final_lighting = lighting + light_gain;\n" \ - GLSL_SOFTWARE_TINT_EQUATION \ - GLSL_SOFTWARE_FADE_EQUATION \ - "final_color.a = texel.a * poly_color.a;\n" \ - "gl_FragColor = final_color;\n" \ - "}\n" \ - "#endif\0" - -// hand tuned adjustments for light level calculation -#define GLSL_FLOOR_FUDGES \ - "#define STARTMAP_FUDGE 1.06\n" \ - "#define SCALE_FUDGE 1.15\n" - -#define GLSL_WALL_FUDGES \ - "#define STARTMAP_FUDGE 1.05\n" \ - "#define SCALE_FUDGE 2.2\n" - -#define GLSL_FLOOR_FRAGMENT_SHADER \ - "#version 120\n" \ - GLSL_FLOOR_FUDGES \ - GLSL_SOFTWARE_FRAGMENT_SHADER - -#define GLSL_WALL_FRAGMENT_SHADER \ - "#version 120\n" \ - GLSL_WALL_FUDGES \ - GLSL_SOFTWARE_FRAGMENT_SHADER - -// same as above but multiplies results with the lighting value from the -// accompanying vertex shader (stored in gl_Color) -#define GLSL_SOFTWARE_MODEL_LIGHTING_FRAGMENT_SHADER \ - GLSL_WALL_FUDGES \ - "#ifdef SRB2_PALETTE_RENDERING\n" \ - "uniform sampler2D tex;\n" \ - "uniform sampler2D brightmap;\n" \ - "uniform sampler3D palette_lookup_tex;\n" \ - "uniform sampler2D lighttable_tex;\n" \ - "uniform vec4 poly_color;\n" \ - "uniform float lighting;\n" \ - GLSL_DOOM_COLORMAP \ - "void main(void) {\n" \ - " vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \ - "#ifdef SRB2_MODEL_LIGHTING\n" \ - "texel *= gl_Color;\n" \ - "#endif\n" \ - GLSL_PALETTE_RENDERING \ - "}\n" \ - "#else\n" \ - "uniform sampler2D tex;\n" \ - "uniform sampler2D brightmap;\n" \ - "uniform vec4 poly_color;\n" \ - "uniform vec4 tint_color;\n" \ - "uniform vec4 fade_color;\n" \ - "uniform float fade_start;\n" \ - "uniform float fade_end;\n" \ - GLSL_DOOM_COLORMAP \ - GLSL_DOOM_LIGHT_EQUATION \ - "void main(void) {\n" \ - "vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \ - "vec4 base_color = texel * poly_color;\n" \ - "vec4 final_color = base_color;\n" \ - "float final_lighting = gl_Color.r * 255.0;\n" \ - "float brightmap_mix = floor(texture2D(brightmap, gl_TexCoord[0].st).r);\n" \ - "float light_gain = (255.0 - final_lighting) * brightmap_mix;\n" \ - "final_lighting += light_gain;\n" \ - GLSL_SOFTWARE_TINT_EQUATION \ - GLSL_SOFTWARE_FADE_EQUATION \ - "final_color.a = texel.a * poly_color.a;\n" \ - "gl_FragColor = final_color;\n" \ - "}\n" \ - "#endif\0" - -// -// Water surface shader -// -// Mostly guesstimated, rather than the rest being built off Software science. -// Still needs to distort things underneath/around the water... -// - -#define GLSL_WATER_TEXEL \ - "float water_z = (gl_FragCoord.z / gl_FragCoord.w) / 2.0;\n" \ - "float a = -pi * (water_z * freq) + (leveltime * speed);\n" \ - "float sdistort = sin(a) * amp;\n" \ - "float cdistort = cos(a) * amp;\n" \ - "vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n" - -#define GLSL_WATER_FRAGMENT_SHADER \ - "#version 120\n" \ - GLSL_FLOOR_FUDGES \ - "const float freq = 0.025;\n" \ - "const float amp = 0.025;\n" \ - "const float speed = 2.0;\n" \ - "const float pi = 3.14159;\n" \ - "#ifdef SRB2_PALETTE_RENDERING\n" \ - "uniform sampler2D tex;\n" \ - "uniform sampler2D brightmap;\n" \ - "uniform sampler3D palette_lookup_tex;\n" \ - "uniform sampler2D lighttable_tex;\n" \ - "uniform vec4 poly_color;\n" \ - "uniform float lighting;\n" \ - "uniform float leveltime;\n" \ - GLSL_DOOM_COLORMAP \ - "void main(void) {\n" \ - GLSL_WATER_TEXEL \ - GLSL_PALETTE_RENDERING \ - "}\n" \ - "#else\n" \ - "uniform sampler2D tex;\n" \ - "uniform sampler2D brightmap;\n" \ - "uniform vec4 poly_color;\n" \ - "uniform vec4 tint_color;\n" \ - "uniform vec4 fade_color;\n" \ - "uniform float lighting;\n" \ - "uniform float fade_start;\n" \ - "uniform float fade_end;\n" \ - "uniform float leveltime;\n" \ - GLSL_DOOM_COLORMAP \ - GLSL_DOOM_LIGHT_EQUATION \ - "void main(void) {\n" \ - GLSL_WATER_TEXEL \ - "vec4 base_color = texel * poly_color;\n" \ - "vec4 final_color = base_color;\n" \ - "float brightmap_mix = floor(texture2D(brightmap, gl_TexCoord[0].st).r);\n" \ - "float light_gain = (255.0 - lighting) * brightmap_mix;\n" \ - "float final_lighting = lighting + light_gain;\n" \ - GLSL_SOFTWARE_TINT_EQUATION \ - GLSL_SOFTWARE_FADE_EQUATION \ - "final_color.a = texel.a * poly_color.a;\n" \ - "gl_FragColor = final_color;\n" \ - "}\n" \ - "#endif\0" - -// -// Fog block shader -// -// Alpha of the planes themselves are still slightly off -- see HWR_FogBlockAlpha -// - -// The floor fudges are used, but should the wall fudges be used instead? or something inbetween? -// or separate values for floors and walls? (need to change more than this shader for that) -#define GLSL_FOG_FRAGMENT_SHADER \ - "#version 120\n" \ - GLSL_FLOOR_FUDGES \ - "uniform vec4 tint_color;\n" \ - "uniform vec4 fade_color;\n" \ - "uniform float lighting;\n" \ - "uniform float fade_start;\n" \ - "uniform float fade_end;\n" \ - GLSL_DOOM_COLORMAP \ - GLSL_DOOM_LIGHT_EQUATION \ - "void main(void) {\n" \ - "vec4 base_color = gl_Color;\n" \ - "vec4 final_color = base_color;\n" \ - "float brightmap_mix = 0.0;\n" \ - "float light_gain = 0.0;\n" \ - "float final_lighting = lighting + light_gain;\n" \ - GLSL_SOFTWARE_TINT_EQUATION \ - GLSL_SOFTWARE_FADE_EQUATION \ - "gl_FragColor = final_color;\n" \ - "}\0" - -// -// Sky fragment shader -// Modulates poly_color with gl_Color -// -#define GLSL_SKY_FRAGMENT_SHADER \ - "uniform sampler2D tex;\n" \ - "uniform vec4 poly_color;\n" \ - "void main(void) {\n" \ - "gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * gl_Color * poly_color;\n" \ - "}\0" - -// Shader for the palette rendering postprocess step -#define GLSL_PALETTE_POSTPROCESS_FRAGMENT_SHADER \ - "uniform sampler2D tex;\n" \ - "uniform sampler3D palette_lookup_tex;\n" \ - "uniform sampler1D palette_tex;\n" \ - "void main(void) {\n" \ - "vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \ - "float tex_pal_idx = texture3D(palette_lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0;\n" \ - "float palette_coord = (tex_pal_idx + 0.5) / 256.0;\n" \ - "vec4 final_color = texture1D(palette_tex, palette_coord);\n" \ - "gl_FragColor = final_color;\n" \ - "}\0" - -// Applies a palettized colormap fade to tex -#define GLSL_UI_COLORMAP_FADE_FRAGMENT_SHADER \ - "uniform sampler2D tex;\n" \ - "uniform float lighting;\n" \ - "uniform sampler3D palette_lookup_tex;\n" \ - "uniform sampler2D lighttable_tex;\n" \ - "void main(void) {\n" \ - "vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \ - "float tex_pal_idx = texture3D(palette_lookup_tex, vec3((texel * 63.0 + 0.5) / 64.0))[0] * 255.0;\n" \ - "vec2 lighttable_coord = vec2((tex_pal_idx + 0.5) / 256.0, (lighting + 0.5) / 32.0);\n" \ - "gl_FragColor = texture2D(lighttable_tex, lighttable_coord);\n" \ - "}\0" - -// -// Generic vertex shader -// - -#define GLSL_FALLBACK_VERTEX_SHADER \ - "void main()\n" \ - "{\n" \ - "gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \ - "gl_FrontColor = gl_Color;\n" \ - "gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \ - "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ - "}\0" - -// -// Generic fragment shader -// - -#define GLSL_FALLBACK_FRAGMENT_SHADER \ - "uniform sampler2D tex;\n" \ - "uniform vec4 poly_color;\n" \ - "void main(void) {\n" \ - "gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * poly_color;\n" \ - "}\0" - -// -// Sky fragment shader -// Modulates poly_color with gl_Color -// -#define GLSL_SKY_FRAGMENT_SHADER \ - "uniform sampler2D tex;\n" \ - "uniform vec4 poly_color;\n" \ - "void main(void) {\n" \ - "gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * gl_Color * poly_color;\n" \ - "}\0" - -#endif diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 4e9de5dc1..31aa0e120 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -24,14 +24,12 @@ #include "../../r_fps.h" // For R_GetTimeFrac, used for the leveltime shader uniform #include "r_opengl.h" #include "r_vbo.h" -#include "../hw_clip.h" -#include "../hw_shaders.h" - -#if defined (HWRENDER) && !defined (NOROPENGL) // requires GL 4.3 //#define GLDEBUGMESSAGE +#if defined (HWRENDER) && !defined (NOROPENGL) + struct GLRGBAFloat { GLfloat red; @@ -40,21 +38,12 @@ struct GLRGBAFloat GLfloat alpha; }; typedef struct GLRGBAFloat GLRGBAFloat; - -// lighttable list item -struct LTListItem -{ - UINT32 id; - struct LTListItem *next; -}; -typedef struct LTListItem LTListItem; +static const GLubyte white[4] = { 255, 255, 255, 255 }; // ========================================================================== // CONSTANTS // ========================================================================== -static const GLubyte white[4] = { 255, 255, 255, 255 }; - // With OpenGL 1.1+, the first texture should be 1 static GLuint NOTEXTURE_NUM = 0; @@ -70,7 +59,6 @@ static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE; static GLuint tex_downloaded = 0; -static GLuint lt_downloaded = 0; // currently bound lighttable texture static GLfloat fov = 90.0f; static FBITFIELD CurrentPolyFlags; @@ -81,15 +69,8 @@ static FTextureInfo *TexCacheHead = NULL; static RGBA_t *textureBuffer = NULL; static size_t textureBufferSize = 0; -// Linked list of all lighttables. -static LTListItem *LightTablesTail = NULL; -static LTListItem *LightTablesHead = NULL; - -static RGBA_t screenPalette[256] = {0}; // the palette for the postprocessing step in palette rendering -static GLuint screenPaletteTex = 0; // 1D texture containing the screen palette -static GLuint paletteLookupTex = 0; // 3D texture containing RGB -> palette index lookup table -RGBA_t myPaletteData[256]; // the palette for converting textures to RGBA -GLint screen_width = 0; // used by Draw2DLine() +RGBA_t myPaletteData[256]; +GLint screen_width = 0; // used by Draw2DLine() GLint screen_height = 0; GLint texsize = 512; // Power-of-two screen texture render resolution GLbyte screen_depth = 0; @@ -115,7 +96,11 @@ static GLint viewport[4]; // flush all of the stored textures, leaving them unavailable at times such as between levels // These need to start at 0 and be set to their number, and be reset to 0 when deleted so that intel GPUs // can know when the textures aren't there, as textures are always considered resident in their virtual memory -static GLuint screenTextures[NUMSCREENTEXTURES] = {0}; +static GLuint screentexture = 0; +static GLuint intermissionbg = 0; +static GLuint startScreenWipe = 0; +static GLuint endScreenWipe = 0; +static GLuint finalScreenTexture = 0; // shortcut for ((float)1/i) static const GLfloat byte2float[256] = { @@ -401,14 +386,10 @@ typedef void (APIENTRY * PFNglTexEnvi) (GLenum target, GLenum pname, GLint param static PFNglTexEnvi pglTexEnvi; typedef void (APIENTRY * PFNglTexParameteri) (GLenum target, GLenum pname, GLint param); static PFNglTexParameteri pglTexParameteri; -typedef void (APIENTRY * PFNglTexImage1D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -static PFNglTexImage1D pglTexImage1D; typedef void (APIENTRY * PFNglTexImage2D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); static PFNglTexImage2D pglTexImage2D; typedef void (APIENTRY * PFNglTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); static PFNglTexSubImage2D pglTexSubImage2D; -typedef void (APIENTRY * PFNglGetTexImage) (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); -static PFNglGetTexImage pglGetTexImage; /* 1.1 functions */ /* texture objects */ //GL_EXT_texture_object @@ -425,10 +406,6 @@ typedef void (APIENTRY * PFNglCopyTexSubImage2D) (GLenum target, GLint level, GL static PFNglCopyTexSubImage2D pglCopyTexSubImage2D; #endif -/* 1.2 functions for 3D textures */ -typedef void (APIENTRY * PFNglTexImage3D) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -static PFNglTexImage3D pglTexImage3D; - /* 1.3 functions for multitexturing */ typedef void (APIENTRY *PFNglActiveTexture) (GLenum); static PFNglActiveTexture pglActiveTexture; @@ -478,9 +455,6 @@ static PFNglDebugMessageCallback pglDebugMessageCallback; #ifndef GL_TEXTURE1 #define GL_TEXTURE1 0x84C1 #endif -#ifndef GL_TEXTURE2 -#define GL_TEXTURE2 0x84C2 -#endif /* 1.5 Parms */ #ifndef GL_ARRAY_BUFFER @@ -552,10 +526,8 @@ boolean SetupGLfunc(void) GETOPENGLFUNC(pglTexEnvi, glTexEnvi) GETOPENGLFUNC(pglTexParameteri, glTexParameteri) - GETOPENGLFUNC(pglTexImage1D, glTexImage1D) GETOPENGLFUNC(pglTexImage2D, glTexImage2D) GETOPENGLFUNC(pglTexSubImage2D, glTexSubImage2D) - GETOPENGLFUNC(pglGetTexImage, glGetTexImage) GETOPENGLFUNC(pglGenTextures, glGenTextures) GETOPENGLFUNC(pglDeleteTextures, glDeleteTextures) @@ -571,7 +543,7 @@ boolean SetupGLfunc(void) } static boolean gl_shadersenabled = false; -static INT32 gl_allowshaders = 0; +static hwdshaderoption_t gl_allowshaders = HWD_SHADEROPTION_OFF; #ifdef GL_SHADERS typedef GLuint (APIENTRY *PFNglCreateShader) (GLenum); @@ -637,12 +609,7 @@ typedef enum gluniform_light_contrast, gluniform_light_backlight, - // palette rendering - gluniform_palette_tex, // 1d texture containing a palette - gluniform_palette_lookup_tex, // 3d texture containing the rgb->index lookup table - gluniform_lighttable_tex, // 2d texture containing a light table - - // misc. + // misc. (custom shaders) gluniform_leveltime, gluniform_max, @@ -650,15 +617,14 @@ typedef enum typedef struct gl_shader_s { - char *vertex_shader; - char *fragment_shader; GLuint program; GLint uniforms[gluniform_max+1]; + boolean custom; } gl_shader_t; static gl_shader_t gl_shaders[HWR_MAXSHADERS]; - -static gl_shader_t gl_fallback_shader; +static gl_shader_t gl_usershaders[HWR_MAXSHADERS]; +static shadersource_t gl_customshaders[HWR_MAXSHADERS]; // 09102020 typedef struct gl_shaderstate_s @@ -679,18 +645,319 @@ static INT32 shader_light_contrast = 0; static INT32 shader_light_backlight = 0; // Lactozilla: Shader functions -static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i); +static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i, const GLchar *vert_shader, const GLchar *frag_shader); static void Shader_CompileError(const char *message, GLuint program, INT32 shadernum); static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade); static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f}; + +#define GLSL_DOOM_COLORMAP \ + "float R_DoomColormap(float light, float z)\n" \ + "{\n" \ + "float lightnum = clamp(light / 17.0, 0.0, 15.0);\n" \ + "float lightz = clamp(z / 16.0, 0.0, 127.0);\n" \ + "float startmap = (15.0 - lightnum) * 4.0;\n" \ + "float scale = 160.0 / (lightz + 1.0);\n" \ + "return startmap - scale * 0.5;\n" \ + "}\n" + +#define GLSL_DOOM_LIGHT_EQUATION \ + "float R_DoomLightingEquation(float light)\n" \ + "{\n" \ + "float z = gl_FragCoord.z / gl_FragCoord.w;\n" \ + "float colormap = floor(R_DoomColormap(light, z)) + 0.5;\n" \ + "return clamp(colormap, 0.0, 31.0) / 32.0;\n" \ + "}\n" + +#define GLSL_SOFTWARE_TINT_EQUATION \ + "if (mix(tint_color.a, 0.0, brightmap_mix) > 0.0) {\n" \ + "float color_bright = sqrt((base_color.r * base_color.r) + (base_color.g * base_color.g) + (base_color.b * base_color.b));\n" \ + "float strength = sqrt(9.0 * mix(tint_color.a, 0.0, brightmap_mix));\n" \ + "final_color.r = clamp((color_bright * (tint_color.r * strength)) + (base_color.r * (1.0 - strength)), 0.0, 1.0);\n" \ + "final_color.g = clamp((color_bright * (tint_color.g * strength)) + (base_color.g * (1.0 - strength)), 0.0, 1.0);\n" \ + "final_color.b = clamp((color_bright * (tint_color.b * strength)) + (base_color.b * (1.0 - strength)), 0.0, 1.0);\n" \ + "}\n" + +#define GLSL_SOFTWARE_FADE_EQUATION \ + "float darkness = R_DoomLightingEquation(final_lighting);\n" \ + "if (fade_start > 0.0 || fade_end < 31.0) {\n" \ + "float fs = fade_start / 31.0;\n" \ + "float fe = fade_end / 31.0;\n" \ + "float fd = fe - fs;\n" \ + "darkness = clamp((darkness - fs) * (1.0 / fd), 0.0, 1.0);\n" \ + "}\n" \ + "if (newfade)\n" \ + "{\n" \ + "float colorBrightness = sqrt((final_color.r * final_color.r) + (final_color.g * final_color.g) + (final_color.b * final_color.b));\n" \ + "float fogBrightness = sqrt((fade_color.r * fade_color.r) + (fade_color.g * fade_color.g) + (fade_color.b * fade_color.b));\n" \ + "float colorIntensity = 0.0;\n" \ + "if (colorBrightness < fogBrightness) {\n" \ + "colorIntensity = 1.0 - min(final_color.r, min(final_color.g, final_color.b));\n" \ + "colorIntensity = abs(colorIntensity - (1.0 - max(fade_color.r, max(fade_color.g, fade_color.b))));\n" \ + "} else {\n" \ + "colorIntensity = max(final_color.r, max(final_color.g, final_color.b));\n" \ + "colorIntensity = abs(colorIntensity - min(fade_color.r, min(fade_color.g, fade_color.b)));\n" \ + "}\n" \ + "colorIntensity *= darkness;\n" \ + "colorIntensity *= fade_color.a * 10.0;\n" \ + "if (abs(final_color.r - fade_color.r) <= colorIntensity) {\n" \ + "final_color.r = fade_color.r;\n" \ + "} else if (final_color.r < fade_color.r) {\n" \ + "final_color.r += colorIntensity;\n" \ + "} else {\n" \ + "final_color.r -= colorIntensity;\n" \ + "}\n" \ + "if (abs(final_color.g - fade_color.g) <= colorIntensity) {\n" \ + "final_color.g = fade_color.g;\n" \ + "} else if (final_color.g < fade_color.g) {\n" \ + "final_color.g += colorIntensity;\n" \ + "} else {\n" \ + "final_color.g -= colorIntensity;\n" \ + "}\n" \ + "if (abs(final_color.b - fade_color.b) <= colorIntensity) {\n" \ + "final_color.b = fade_color.b;\n" \ + "} else if (final_color.b < fade_color.b) {\n" \ + "final_color.b += colorIntensity;\n" \ + "} else {\n" \ + "final_color.b -= colorIntensity;\n" \ + "}\n" \ + "} else {\n" \ + "final_color = mix(final_color, fade_color, darkness);\n" \ + "}\n" + +// ================ +// Vertex shaders +// ================ + +// +// Generic vertex shader +// + +#define GLSL_DEFAULT_VERTEX_SHADER \ + "void main()\n" \ + "{\n" \ + "gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \ + "gl_FrontColor = gl_Color;\n" \ + "gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \ + "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ + "}\0" + +// reinterpretation of sprite lighting for models +// it's a combination of how it works for normal sprites & papersprites +#define GLSL_MODEL_LIGHTING_VERTEX_SHADER \ + "uniform float lighting;\n" \ + "uniform vec3 light_dir;\n" \ + "uniform float light_contrast;\n" \ + "uniform float light_backlight;\n" \ + "void main()\n" \ + "{\n" \ + "gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \ + "float light = lighting;\n" \ + "if (length(light_dir) > 0.000001) {\n" \ + "mat4 m4 = gl_ProjectionMatrix * gl_ModelViewMatrix;\n" \ + "mat3 m3 = mat3( m4[0].xyz, m4[1].xyz, m4[2].xyz );\n" \ + "float extralight = -dot(normalize(gl_Normal * m3), normalize(light_dir));\n" \ + "extralight *= light_contrast - light_backlight;\n" \ + "extralight *= lighting / 255.0;\n" \ + "light += extralight * 2.5;\n" \ + "}\n" \ + "light = clamp(light / 255.0, 0.0, 1.0);\n" \ + "gl_FrontColor = vec4(light, light, light, 1.0);\n" \ + "gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \ + "gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \ + "}\0" + +// ================== +// Fragment shaders +// ================== + +// +// Generic fragment shader +// + +#define GLSL_DEFAULT_FRAGMENT_SHADER \ + "uniform sampler2D tex;\n" \ + "uniform vec4 poly_color;\n" \ + "void main(void) {\n" \ + "gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * poly_color;\n" \ + "}\0" + +// +// Software fragment shader +// + +#define GLSL_SOFTWARE_FRAGMENT_SHADER \ + "uniform sampler2D tex;\n" \ + "uniform sampler2D brightmap;\n" \ + "uniform vec4 poly_color;\n" \ + "uniform vec4 tint_color;\n" \ + "uniform vec4 fade_color;\n" \ + "uniform float lighting;\n" \ + "uniform float fade_start;\n" \ + "uniform float fade_end;\n" \ + "uniform bool newfade;\n" \ + GLSL_DOOM_COLORMAP \ + GLSL_DOOM_LIGHT_EQUATION \ + "void main(void) {\n" \ + "vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \ + "vec4 base_color = texel * poly_color;\n" \ + "vec4 final_color = base_color;\n" \ + "float brightmap_mix = floor(texture2D(brightmap, gl_TexCoord[0].st).r);\n" \ + "float light_gain = (255.0 - lighting) * brightmap_mix;\n" \ + "float final_lighting = lighting + light_gain;\n" \ + GLSL_SOFTWARE_TINT_EQUATION \ + GLSL_SOFTWARE_FADE_EQUATION \ + "final_color.a = texel.a * poly_color.a;\n" \ + "gl_FragColor = final_color;\n" \ + "}\0" + +// same as above but multiplies results with the lighting value from the +// accompanying vertex shader (stored in gl_Color) +#define GLSL_SOFTWARE_MODEL_LIGHTING_FRAGMENT_SHADER \ + "uniform sampler2D tex;\n" \ + "uniform sampler2D brightmap;\n" \ + "uniform vec4 poly_color;\n" \ + "uniform vec4 tint_color;\n" \ + "uniform vec4 fade_color;\n" \ + "uniform float fade_start;\n" \ + "uniform float fade_end;\n" \ + "uniform bool newfade;\n" \ + GLSL_DOOM_COLORMAP \ + GLSL_DOOM_LIGHT_EQUATION \ + "void main(void) {\n" \ + "vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \ + "vec4 base_color = texel * poly_color;\n" \ + "vec4 final_color = base_color;\n" \ + "float final_lighting = gl_Color.r * 255.0;\n" \ + "float brightmap_mix = floor(texture2D(brightmap, gl_TexCoord[0].st).r);\n" \ + "float light_gain = (255.0 - final_lighting) * brightmap_mix;\n" \ + "final_lighting += light_gain;\n" \ + GLSL_SOFTWARE_TINT_EQUATION \ + GLSL_SOFTWARE_FADE_EQUATION \ + "final_color.a = texel.a * poly_color.a;\n" \ + "gl_FragColor = final_color;\n" \ + "}\0" + +// +// Water surface shader +// +// Mostly guesstimated, rather than the rest being built off Software science. +// Still needs to distort things underneath/around the water... +// + +#define GLSL_WATER_FRAGMENT_SHADER \ + "uniform sampler2D tex;\n" \ + "uniform sampler2D brightmap;\n" \ + "uniform vec4 poly_color;\n" \ + "uniform vec4 tint_color;\n" \ + "uniform vec4 fade_color;\n" \ + "uniform float lighting;\n" \ + "uniform float fade_start;\n" \ + "uniform float fade_end;\n" \ + "uniform bool newfade;\n" \ + "uniform float leveltime;\n" \ + "const float freq = 0.025;\n" \ + "const float amp = 0.025;\n" \ + "const float speed = 2.0;\n" \ + "const float pi = 3.14159;\n" \ + GLSL_DOOM_COLORMAP \ + GLSL_DOOM_LIGHT_EQUATION \ + "void main(void) {\n" \ + "float water_z = (gl_FragCoord.z / gl_FragCoord.w) / 2.0;\n" \ + "float a = -pi * (water_z * freq) + (leveltime * speed);\n" \ + "float sdistort = sin(a) * amp;\n" \ + "float cdistort = cos(a) * amp;\n" \ + "vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n" \ + "vec4 base_color = texel * poly_color;\n" \ + "vec4 final_color = base_color;\n" \ + "float brightmap_mix = floor(texture2D(brightmap, gl_TexCoord[0].st).r);\n" \ + "float light_gain = (255.0 - lighting) * brightmap_mix;\n" \ + "float final_lighting = lighting + light_gain;\n" \ + GLSL_SOFTWARE_TINT_EQUATION \ + GLSL_SOFTWARE_FADE_EQUATION \ + "final_color.a = texel.a * poly_color.a;\n" \ + "gl_FragColor = final_color;\n" \ + "}\0" + +// +// Fog block shader +// +// Alpha of the planes themselves are still slightly off -- see HWR_FogBlockAlpha +// + +#define GLSL_FOG_FRAGMENT_SHADER \ + "uniform vec4 tint_color;\n" \ + "uniform vec4 fade_color;\n" \ + "uniform float lighting;\n" \ + "uniform float fade_start;\n" \ + "uniform float fade_end;\n" \ + "uniform bool newfade;\n" \ + GLSL_DOOM_COLORMAP \ + GLSL_DOOM_LIGHT_EQUATION \ + "void main(void) {\n" \ + "vec4 base_color = gl_Color;\n" \ + "vec4 final_color = base_color;\n" \ + "float brightmap_mix = 0.0;\n" \ + "float light_gain = 0.0;\n" \ + "float final_lighting = lighting + light_gain;\n" \ + GLSL_SOFTWARE_TINT_EQUATION \ + GLSL_SOFTWARE_FADE_EQUATION \ + "gl_FragColor = final_color;\n" \ + "}\0" + +// +// Sky fragment shader +// Modulates poly_color with gl_Color +// +#define GLSL_SKY_FRAGMENT_SHADER \ + "uniform sampler2D tex;\n" \ + "uniform vec4 poly_color;\n" \ + "void main(void) {\n" \ + "gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * gl_Color * poly_color;\n" \ + "}\0" + +// ================ +// Shader sources +// ================ + +static struct { + const char *vertex; + const char *fragment; +} const gl_shadersources[] = { + // Default shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_DEFAULT_FRAGMENT_SHADER}, + + // Floor shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER}, + + // Wall shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER}, + + // Sprite shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER}, + + // Model shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER}, + + // Model shader + diffuse lighting from above + {GLSL_MODEL_LIGHTING_VERTEX_SHADER, GLSL_SOFTWARE_MODEL_LIGHTING_FRAGMENT_SHADER}, + + // Water shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WATER_FRAGMENT_SHADER}, + + // Fog shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_FOG_FRAGMENT_SHADER}, + + // Sky shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_SKY_FRAGMENT_SHADER}, + + {NULL, NULL}, +}; + #endif // GL_SHADERS void SetupGLFunc4(void) { - /* 1.2 funcs */ - *(void**)&pglTexImage3D = GetGLFunc("glTexImage3D"); - /* 1.3 funcs */ *(void**)&pglActiveTexture = GetGLFunc("glActiveTexture"); *(void**)&pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f"); *(void**)&pglClientActiveTexture = GetGLFunc("glClientActiveTexture"); @@ -734,20 +1001,55 @@ void SetupGLFunc4(void) #endif } -EXPORT boolean HWRAPI(InitShaders) (void) +EXPORT boolean HWRAPI(CompileShaders) (void) { #ifdef GL_SHADERS + GLint i; if (!pglUseProgram) return false; - gl_fallback_shader.vertex_shader = Z_StrDup(GLSL_FALLBACK_VERTEX_SHADER); - gl_fallback_shader.fragment_shader = Z_StrDup(GLSL_FALLBACK_FRAGMENT_SHADER); + gl_customshaders[SHADER_DEFAULT].vertex = NULL; + gl_customshaders[SHADER_DEFAULT].fragment = NULL; - if (!Shader_CompileProgram(&gl_fallback_shader, -1)) + for (i = 0; gl_shadersources[i].vertex && gl_shadersources[i].fragment; i++) { - GL_MSG_Error("Failed to compile the fallback shader program!\n"); - return false; + gl_shader_t *shader, *usershader; + const GLchar *vert_shader = gl_shadersources[i].vertex; + const GLchar *frag_shader = gl_shadersources[i].fragment; + + if (i >= HWR_MAXSHADERS) + break; + + shader = &gl_shaders[i]; + usershader = &gl_usershaders[i]; + + if (shader->program) + pglDeleteProgram(shader->program); + if (usershader->program) + pglDeleteProgram(usershader->program); + + shader->program = 0; + usershader->program = 0; + + if (!Shader_CompileProgram(shader, i, vert_shader, frag_shader)) + shader->program = 0; + + // Compile custom shader + if ((i == SHADER_DEFAULT) || !(gl_customshaders[i].vertex || gl_customshaders[i].fragment)) + continue; + + // 18032019 + if (gl_customshaders[i].vertex) + vert_shader = gl_customshaders[i].vertex; + if (gl_customshaders[i].fragment) + frag_shader = gl_customshaders[i].fragment; + + if (!Shader_CompileProgram(usershader, i, vert_shader, frag_shader)) + { + GL_MSG_Warning("CompileShaders: Could not compile custom shader program for %s\n", HWR_GetShaderName(i)); + usershader->program = 0; + } } return true; @@ -756,59 +1058,6 @@ EXPORT boolean HWRAPI(InitShaders) (void) #endif } -EXPORT void HWRAPI(LoadShader) (int slot, char *code, hwdshaderstage_t stage) -{ -#ifdef GL_SHADERS - gl_shader_t *shader; - - if (slot < 0 || slot >= HWR_MAXSHADERS) - I_Error("LoadShader: Invalid slot %d", slot); - - shader = &gl_shaders[slot]; - -#define LOADSHADER(source) { \ - if (shader->source) \ - Z_Free(shader->source); \ - shader->source = code; \ - } - - if (stage == HWD_SHADERSTAGE_VERTEX) - LOADSHADER(vertex_shader) - else if (stage == HWD_SHADERSTAGE_FRAGMENT) - LOADSHADER(fragment_shader) - else - I_Error("LoadShader: invalid shader stage"); - -#undef LOADSHADER -#else - (void)slot; - (void)code; - (void)stage; -#endif -} - - -EXPORT boolean HWRAPI(CompileShader) (int slot) -{ -#ifdef GL_SHADERS - if (slot < 0 || slot >= HWR_MAXSHADERS) - I_Error("CompileShader: Invalid slot %d", slot); - - if (Shader_CompileProgram(&gl_shaders[slot], slot)) - { - return true; - } - else - { - gl_shaders[slot].program = 0; - return false; - } -#else - (void)slot; - return false; -#endif -} - // // Shader info // Those are given to the uniforms. @@ -846,36 +1095,90 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value) #endif } -EXPORT void HWRAPI(SetShader) (int slot) +// +// Custom shader loading +// +EXPORT void HWRAPI(LoadCustomShader) (int number, char *code, size_t size, boolean isfragment) { #ifdef GL_SHADERS - if (slot == SHADER_NONE) + shadersource_t *shader; + + if (!pglUseProgram) + return; + + if (number < 1 || number > HWR_MAXSHADERS) + I_Error("LoadCustomShader: cannot load shader %d (min 1, max %d)", number, HWR_MAXSHADERS); + else if (code == NULL) + I_Error("LoadCustomShader: empty shader"); + + shader = &gl_customshaders[number]; + +#define COPYSHADER(source) { \ + if (shader->source) \ + free(shader->source); \ + shader->source = malloc(size+1); \ + strncpy(shader->source, code, size); \ + shader->source[size] = 0; \ + } + + if (isfragment) + COPYSHADER(fragment) + else + COPYSHADER(vertex) + +#else + (void)number; + (void)shader; + (void)size; + (void)fragment; +#endif +} + +EXPORT void HWRAPI(SetShader) (int type) +{ +#ifdef GL_SHADERS + if (type == SHADER_NONE) { UnSetShader(); return; } - if (gl_allowshaders) + if (gl_allowshaders != HWD_SHADEROPTION_OFF) { - gl_shader_t *next_shader = &gl_shaders[slot]; // the gl_shader_t we are going to switch to + gl_shader_t *shader = gl_shaderstate.current; - if (!next_shader->program) - next_shader = &gl_fallback_shader; // unusable shader, use fallback instead + // If using model lighting, set the appropriate shader. + // However don't override a custom shader. + if (type == SHADER_MODEL && model_lighting + && !(gl_shaders[SHADER_MODEL].custom && !gl_shaders[SHADER_MODEL_LIGHTING].custom)) + type = SHADER_MODEL_LIGHTING; - // update gl_shaderstate if an actual shader switch is needed - if (gl_shaderstate.current != next_shader) + if ((shader == NULL) || (GLuint)type != gl_shaderstate.type) { - gl_shaderstate.current = next_shader; - gl_shaderstate.program = next_shader->program; - gl_shaderstate.type = slot; + gl_shader_t *baseshader = &gl_shaders[type]; + gl_shader_t *usershader = &gl_usershaders[type]; + + if (usershader->program) + shader = (gl_allowshaders == HWD_SHADEROPTION_NOCUSTOM) ? baseshader : usershader; + else + shader = baseshader; + + gl_shaderstate.current = shader; + gl_shaderstate.type = type; gl_shaderstate.changed = true; } - gl_shadersenabled = true; + if (gl_shaderstate.program != shader->program) + { + gl_shaderstate.program = shader->program; + gl_shaderstate.changed = true; + } + + gl_shadersenabled = (shader->program != 0); return; } #else - (void)slot; + (void)type; #endif gl_shadersenabled = false; } @@ -883,20 +1186,36 @@ EXPORT void HWRAPI(SetShader) (int slot) EXPORT void HWRAPI(UnSetShader) (void) { #ifdef GL_SHADERS - if (gl_shadersenabled) // don't repeatedly call glUseProgram if not needed - { - gl_shaderstate.current = NULL; - gl_shaderstate.type = 0; - gl_shaderstate.program = 0; + gl_shaderstate.current = NULL; + gl_shaderstate.type = 0; + gl_shaderstate.program = 0; - if (pglUseProgram) - pglUseProgram(0); - } + if (pglUseProgram) + pglUseProgram(0); #endif gl_shadersenabled = false; } +EXPORT void HWRAPI(CleanShaders) (void) +{ + INT32 i; + + for (i = 1; i < HWR_MAXSHADERS; i++) + { + shadersource_t *shader = &gl_customshaders[i]; + + if (shader->vertex) + free(shader->vertex); + + if (shader->fragment) + free(shader->fragment); + + shader->vertex = NULL; + shader->fragment = NULL; + } +} + // -----------------+ // SetNoTexture : Disable texture // -----------------+ @@ -1261,29 +1580,20 @@ EXPORT void HWRAPI(ClearMipMapCache) (void) Flush(); } -// Writes screen texture tex into dst_data. -// Pixel format is 24-bit RGB. Row order is top to bottom. -// Dimensions are screen_width * screen_height. -EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT8 *restrict dest, INT32 scale) +// -----------------------+ +// ReadScreenFinalTexture : Reads out the final screen texture +// Returns : 24bit RGB pixel array stored in dest +// -----------------------+ +EXPORT void HWRAPI(ReadScreenFinalTexture) (UINT8 * restrict dest, INT32 scale) { const INT32 stride = (screen_width/scale)*3; INT32 scanlines = screen_height; GLubyte * restrict image; - // at the time this function is called, generic2 can be found drawn on the framebuffer - // if some other screen texture is needed, draw it to the framebuffer - // and draw generic2 back after reading the framebuffer. - // this hack is for some reason **much** faster than the simple solution of using glGetTexImage. - if (tex != HWD_SCREENTEXTURE_GENERIC2) - DrawScreenTexture(tex, NULL, 0); - image = malloc(screen_width*screen_height*3); pglPixelStorei(GL_PACK_ALIGNMENT, 1); pglReadPixels(0, 0, screen_width, screen_height, GL_RGB, GL_UNSIGNED_BYTE, image); - if (tex != HWD_SCREENTEXTURE_GENERIC2) - DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2, NULL, 0); - // TODO the downscaling happens in the screen capture code now, // yet we're still doing this on the CPU? sheesh... // this is where actual knowledge of OpenGL would've come in handy @@ -1302,7 +1612,6 @@ EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT8 *restrict dest, INT32 scal free(image - ((screen_height % scale) * screen_width*3)); } - // -----------------+ // GClipRect : Defines the 2D hardware clipping window // -----------------+ @@ -1920,91 +2229,69 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF #endif } -static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i) +static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i, const GLchar *vert_shader, const GLchar *frag_shader) { - GLuint gl_vertShader = 0; - GLuint gl_fragShader = 0; + GLuint gl_vertShader, gl_fragShader; GLint result; - const GLchar *vert_shader = shader->vertex_shader; - const GLchar *frag_shader = shader->fragment_shader; - if (shader->program) - pglDeleteProgram(shader->program); - - if (!vert_shader && !frag_shader) + // + // Load and compile vertex shader + // + gl_vertShader = pglCreateShader(GL_VERTEX_SHADER); + if (!gl_vertShader) { - GL_MSG_Error("Shader_CompileProgram: Missing shaders for shader program %s\n", HWR_GetShaderName(i)); + GL_MSG_Error("Shader_CompileProgram: Error creating vertex shader %s\n", HWR_GetShaderName(i)); return false; } - if (vert_shader) + pglShaderSource(gl_vertShader, 1, &vert_shader, NULL); + pglCompileShader(gl_vertShader); + + // check for compile errors + pglGetShaderiv(gl_vertShader, GL_COMPILE_STATUS, &result); + if (result == GL_FALSE) { - // - // Load and compile vertex shader - // - gl_vertShader = pglCreateShader(GL_VERTEX_SHADER); - if (!gl_vertShader) - { - GL_MSG_Error("Shader_CompileProgram: Error creating vertex shader %s\n", HWR_GetShaderName(i)); - return false; - } - - pglShaderSource(gl_vertShader, 1, &vert_shader, NULL); - pglCompileShader(gl_vertShader); - - // check for compile errors - pglGetShaderiv(gl_vertShader, GL_COMPILE_STATUS, &result); - if (result == GL_FALSE) - { - Shader_CompileError("Error compiling vertex shader", gl_vertShader, i); - pglDeleteShader(gl_vertShader); - return false; - } + Shader_CompileError("Error compiling vertex shader", gl_vertShader, i); + pglDeleteShader(gl_vertShader); + return false; } - if (frag_shader) + // + // Load and compile fragment shader + // + gl_fragShader = pglCreateShader(GL_FRAGMENT_SHADER); + if (!gl_fragShader) { - // - // Load and compile fragment shader - // - gl_fragShader = pglCreateShader(GL_FRAGMENT_SHADER); - if (!gl_fragShader) - { - GL_MSG_Error("Shader_CompileProgram: Error creating fragment shader %s\n", HWR_GetShaderName(i)); - pglDeleteShader(gl_vertShader); - pglDeleteShader(gl_fragShader); - return false; - } + GL_MSG_Error("Shader_CompileProgram: Error creating fragment shader %s\n", HWR_GetShaderName(i)); + pglDeleteShader(gl_vertShader); + pglDeleteShader(gl_fragShader); + return false; + } - pglShaderSource(gl_fragShader, 1, &frag_shader, NULL); - pglCompileShader(gl_fragShader); + pglShaderSource(gl_fragShader, 1, &frag_shader, NULL); + pglCompileShader(gl_fragShader); - // check for compile errors - pglGetShaderiv(gl_fragShader, GL_COMPILE_STATUS, &result); - if (result == GL_FALSE) - { - Shader_CompileError("Error compiling fragment shader", gl_fragShader, i); - pglDeleteShader(gl_vertShader); - pglDeleteShader(gl_fragShader); - return false; - } + // check for compile errors + pglGetShaderiv(gl_fragShader, GL_COMPILE_STATUS, &result); + if (result == GL_FALSE) + { + Shader_CompileError("Error compiling fragment shader", gl_fragShader, i); + pglDeleteShader(gl_vertShader); + pglDeleteShader(gl_fragShader); + return false; } shader->program = pglCreateProgram(); - if (vert_shader) - pglAttachShader(shader->program, gl_vertShader); - if (frag_shader) - pglAttachShader(shader->program, gl_fragShader); + pglAttachShader(shader->program, gl_vertShader); + pglAttachShader(shader->program, gl_fragShader); pglLinkProgram(shader->program); // check link status pglGetProgramiv(shader->program, GL_LINK_STATUS, &result); // delete the shader objects - if (vert_shader) - pglDeleteShader(gl_vertShader); - if (frag_shader) - pglDeleteShader(gl_fragShader); + pglDeleteShader(gl_vertShader); + pglDeleteShader(gl_fragShader); // couldn't link? if (result != GL_TRUE) @@ -2033,32 +2320,11 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i) shader->uniforms[gluniform_light_contrast] = GETUNI("light_contrast"); shader->uniforms[gluniform_light_backlight] = GETUNI("light_backlight"); - // palette rendering - shader->uniforms[gluniform_palette_tex] = GETUNI("palette_tex"); - shader->uniforms[gluniform_palette_lookup_tex] = GETUNI("palette_lookup_tex"); - shader->uniforms[gluniform_lighttable_tex] = GETUNI("lighttable_tex"); - // misc. (custom shaders) shader->uniforms[gluniform_leveltime] = GETUNI("leveltime"); #undef GETUNI - // set permanent uniform values -#define UNIFORM_1(uniform, a, function) \ - if (uniform != -1) \ - function (uniform, a); - - pglUseProgram(shader->program); - - // texture unit numbers for the samplers used for palette rendering - UNIFORM_1(shader->uniforms[gluniform_palette_tex], 2, pglUniform1i); - UNIFORM_1(shader->uniforms[gluniform_palette_lookup_tex], 1, pglUniform1i); - UNIFORM_1(shader->uniforms[gluniform_lighttable_tex], 2, pglUniform1i); - - // restore gl shader state - pglUseProgram(gl_shaderstate.program); - #undef UNIFORM_1 - return true; } @@ -2121,14 +2387,6 @@ static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD fade.green = byte2float[pSurf->FadeColor.s.green]; fade.blue = byte2float[pSurf->FadeColor.s.blue]; fade.alpha = byte2float[pSurf->FadeColor.s.alpha]; - - if (pSurf->LightTableId && pSurf->LightTableId != lt_downloaded) - { - pglActiveTexture(GL_TEXTURE2); - pglBindTexture(GL_TEXTURE_2D, pSurf->LightTableId); - pglActiveTexture(GL_TEXTURE0); - lt_downloaded = pSurf->LightTableId; - } } } @@ -2311,6 +2569,9 @@ EXPORT void HWRAPI(RenderSkyDome) (gl_sky_t *sky) pglDisableClientState(GL_COLOR_ARRAY); } +// ========================================================================== +// +// ========================================================================== EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) { switch (IdState) @@ -2320,7 +2581,7 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) break; case HWD_SET_SHADERS: - gl_allowshaders = Value; + gl_allowshaders = (hwdshaderoption_t)Value; break; case HWD_SET_TEXTUREFILTERMODE: @@ -2668,14 +2929,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float else if (Surface->PolyColor.s.alpha == 0xFF) flags |= (PF_Occlude | PF_Masked); - if (Surface->LightTableId && Surface->LightTableId != lt_downloaded) - { - pglActiveTexture(GL_TEXTURE2); - pglBindTexture(GL_TEXTURE_2D, Surface->LightTableId); - pglActiveTexture(GL_TEXTURE0); - lt_downloaded = Surface->LightTableId; - } - SetBlend(flags); Shader_SetUniforms(Surface, &poly, &tint, &fade); @@ -3043,18 +3296,64 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]) pglEnable(GL_BLEND); } - // Sryder: This needs to be called whenever the screen changes resolution in order to reset the screen textures to use // a new size EXPORT void HWRAPI(FlushScreenTextures) (void) { - int i; - pglDeleteTextures(NUMSCREENTEXTURES, screenTextures); - for (i = 0; i < NUMSCREENTEXTURES; i++) - screenTextures[i] = 0; + pglDeleteTextures(1, &screentexture); + pglDeleteTextures(1, &intermissionbg); + pglDeleteTextures(1, &startScreenWipe); + pglDeleteTextures(1, &endScreenWipe); + pglDeleteTextures(1, &finalScreenTexture); + screentexture = 0; + intermissionbg = 0; + startScreenWipe = 0; + endScreenWipe = 0; + finalScreenTexture = 0; } -EXPORT void HWRAPI(DrawScreenTexture)(int tex, FSurfaceInfo *surf, FBITFIELD polyflags) +static void GetScreenTexture(GLuint *texnum) +{ + boolean firstTime = (*texnum == 0); + + // Create screen texture + if (firstTime) + pglGenTextures(1, texnum); + pglBindTexture(GL_TEXTURE_2D, *texnum); + + if (firstTime) + { + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + Clamp2D(GL_TEXTURE_WRAP_S); + Clamp2D(GL_TEXTURE_WRAP_T); + pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); + } + else + pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize); + + tex_downloaded = *texnum; +} + +// Create Screen to fade from +EXPORT void HWRAPI(StartScreenWipe) (void) +{ + GetScreenTexture(&startScreenWipe); +} + +// Create Screen to fade to +EXPORT void HWRAPI(EndScreenWipe)(void) +{ + GetScreenTexture(&endScreenWipe); +} + +EXPORT void HWRAPI(MakeIntermissionBG) (void) +{ + GetScreenTexture(&intermissionbg); +} + +// Draw the last scene under the intermission +EXPORT void HWRAPI(DrawIntermissionBG)(void) { float xfix, yfix; @@ -3085,22 +3384,18 @@ EXPORT void HWRAPI(DrawScreenTexture)(int tex, FSurfaceInfo *surf, FBITFIELD pol pglClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); - pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]); - if (surf) - PreparePolygon(surf, NULL, polyflags); - else - Shader_SetUniforms(NULL, NULL, NULL, NULL); // prepare shader, if it is enabled + pglBindTexture(GL_TEXTURE_2D, intermissionbg); pglColor4ubv(white); pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglVertexPointer(3, GL_FLOAT, 0, screenVerts); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); - tex_downloaded = screenTextures[tex]; + tex_downloaded = intermissionbg; } // Do screen fades! -EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd) +EXPORT void HWRAPI(DoScreenWipe)(void) { float xfix, yfix; @@ -3127,6 +3422,9 @@ EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd) xfix = 1/((float)(texsize)/((float)((screen_width)))); yfix = 1/((float)(texsize)/((float)((screen_height)))); + // const float screenVerts[12] + + // float fix[8]; fix[0] = 0.0f; fix[1] = 0.0f; fix[2] = 0.0f; @@ -3142,7 +3440,7 @@ EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd) pglEnable(GL_TEXTURE_2D); // Draw the original screen - pglBindTexture(GL_TEXTURE_2D, screenTextures[wipeStart]); + pglBindTexture(GL_TEXTURE_2D, startScreenWipe); pglColor4ubv(white); pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglVertexPointer(3, GL_FLOAT, 0, screenVerts); @@ -3153,7 +3451,7 @@ EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd) // Draw the end screen that fades in pglActiveTexture(GL_TEXTURE0); pglEnable(GL_TEXTURE_2D); - pglBindTexture(GL_TEXTURE_2D, screenTextures[wipeEnd]); + pglBindTexture(GL_TEXTURE_2D, endScreenWipe); pglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); pglActiveTexture(GL_TEXTURE1); @@ -3175,129 +3473,88 @@ EXPORT void HWRAPI(DoScreenWipe)(int wipeStart, int wipeEnd) pglActiveTexture(GL_TEXTURE0); pglClientActiveTexture(GL_TEXTURE0); - tex_downloaded = screenTextures[wipeEnd]; + tex_downloaded = endScreenWipe; } // Create a texture from the screen. -EXPORT void HWRAPI(MakeScreenTexture) (int tex) +EXPORT void HWRAPI(MakeScreenTexture) (void) { - boolean firstTime = (screenTextures[tex] == 0); - - // Create screen texture - if (firstTime) - pglGenTextures(1, &screenTextures[tex]); - pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]); - - if (firstTime) - { - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - Clamp2D(GL_TEXTURE_WRAP_S); - Clamp2D(GL_TEXTURE_WRAP_T); - pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); - } - else - pglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize); - - tex_downloaded = screenTextures[tex]; + GetScreenTexture(&screentexture); } EXPORT void HWRAPI(RenderVhsEffect) (INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize) { float xfix, yfix; float fix[8]; - float i; - GLubyte color[4] = {255, 255, 255, 255}; - + float i; float screenVerts[12] = { -1.0f, -1.0f, 1.0f, - -1.0f, 1.0f, 1.0f, - 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f }; - + // look for power of two that is large enough for the screen + while (texsize < screen_width || texsize < screen_height) + texsize <<= 1; xfix = 1/((float)(texsize)/((float)((screen_width)))); yfix = 1/((float)(texsize)/((float)((screen_height)))); - - const GLfloat scrwf = (float)screen_width; - const GLfloat scrwh = (float)screen_height; - // Slight fuzziness - MakeScreenTexture(HWD_SCREENTEXTURE_VHS); + MakeScreenTexture(); SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest); - pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]); - - const float stride = 2.f/scrwh; - - for (i = 0; i < 1; i += stride) + pglBindTexture(GL_TEXTURE_2D, screentexture); + for (i = 0; i < 1; i += 2.f/vid.height) { - fix[2] = (float)(rand() % 128) / -22000.f * xfix; + fix[2] = (float)(rand() % 128) / -22000 * xfix; fix[0] = fix[2]; fix[6] = fix[0] + xfix; fix[4] = fix[2] + xfix; fix[1] = fix[7] = i*yfix; - fix[3] = fix[5] = (i+0.015f)*yfix; - + fix[3] = fix[5] = (i+0.015)*yfix; screenVerts[1] = screenVerts[10] = 2*i - 1.0f; - screenVerts[4] = screenVerts[7] = screenVerts[1] + 0.03f; - + screenVerts[4] = screenVerts[7] = screenVerts[1] + 0.03; pglColor4ubv(color); - pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglVertexPointer(3, GL_FLOAT, 0, screenVerts); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); } - // Upward bar - //GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS); - //pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]); - + MakeScreenTexture(); + pglBindTexture(GL_TEXTURE_2D, screentexture); color[0] = color[1] = color[2] = 190; color[3] = 250; pglColor4ubv(color); - fix[0] = 0.0f; fix[6] = xfix; - fix[2] = (float)updistort / scrwf * xfix; + fix[2] = (float)updistort / screen_width * xfix; fix[4] = fix[2] + fix[6]; - - screenVerts[1] = screenVerts[10] = 2.0f*upbary/scrwh - 1.0f; - screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/scrwh; - - fix[1] = fix[7] = (float)upbary/scrwh * yfix; - fix[3] = fix[5] = fix[1] + (float)barsize/2/scrwh * yfix; - + screenVerts[1] = screenVerts[10] = 2.0f*upbary/screen_height - 1.0f; + screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/screen_height; + fix[1] = fix[7] = (float)upbary/screen_height * yfix; + fix[3] = fix[5] = fix[1] + (float)barsize/2/screen_height * yfix; pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglVertexPointer(3, GL_FLOAT, 0, screenVerts); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); - fix[1] = fix[7] += (fix[3] - fix[7])*2; screenVerts[1] = screenVerts[10] += (screenVerts[4] - screenVerts[1])*2; pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglVertexPointer(3, GL_FLOAT, 0, screenVerts); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); - // Downward bar - //GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS); - //pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]); - + MakeScreenTexture(); + pglBindTexture(GL_TEXTURE_2D, screentexture); fix[0] = 0.0f; fix[6] = xfix; - fix[2] = (float)downdistort / scrwf * -xfix; + fix[2] = (float)downdistort / screen_width * -xfix; fix[4] = fix[2] + fix[6]; - - screenVerts[1] = screenVerts[10] = 2.0f*downbary/scrwh - 1.0f; - screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/scrwh; - - fix[1] = fix[7] = (float)downbary/scrwh * yfix; - fix[3] = fix[5] = fix[1] + (float)barsize/2/scrwh * yfix; - + screenVerts[1] = screenVerts[10] = 2.0f*downbary/screen_height - 1.0f; + screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/screen_height; + fix[1] = fix[7] = (float)downbary/screen_height * yfix; + fix[3] = fix[5] = fix[1] + (float)barsize/2/screen_height * yfix; pglTexCoordPointer(2, GL_FLOAT, 0, fix); pglVertexPointer(3, GL_FLOAT, 0, screenVerts); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); - fix[1] = fix[7] += (fix[3] - fix[7])*2; screenVerts[1] = screenVerts[10] += (screenVerts[4] - screenVerts[1])*2; pglTexCoordPointer(2, GL_FLOAT, 0, fix); @@ -3305,7 +3562,12 @@ EXPORT void HWRAPI(RenderVhsEffect) (INT16 upbary, INT16 downbary, UINT8 updisto pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); } -EXPORT void HWRAPI(DrawScreenFinalTexture)(int tex, int width, int height) +EXPORT void HWRAPI(MakeScreenFinalTexture) (void) +{ + GetScreenTexture(&finalScreenTexture); +} + +EXPORT void HWRAPI(DrawScreenFinalTexture)(int width, int height) { float xfix, yfix; float origaspect, newaspect; @@ -3360,7 +3622,7 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int tex, int width, int height) clearColour.red = clearColour.green = clearColour.blue = 0; clearColour.alpha = 1; ClearBuffer(true, false, &clearColour); - pglBindTexture(GL_TEXTURE_2D, screenTextures[tex]); + pglBindTexture(GL_TEXTURE_2D, finalScreenTexture); pglColor4ubv(white); @@ -3368,92 +3630,7 @@ EXPORT void HWRAPI(DrawScreenFinalTexture)(int tex, int width, int height) pglVertexPointer(3, GL_FLOAT, 0, off); pglDrawArrays(GL_TRIANGLE_FAN, 0, 4); - tex_downloaded = screenTextures[tex]; -} - -EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut) -{ - GLenum internalFormat; - if (gl_version[0] == '1' || gl_version[0] == '2') - { - // if the OpenGL version is below 3.0, then the GL_R8 format may not be available. - // so use GL_LUMINANCE8 instead to get a single component 8-bit format - // (it is possible to have access to shaders even in some OpenGL 1.x systems, - // so palette rendering can still possibly be achieved there) - internalFormat = GL_LUMINANCE8; - } - else - { - internalFormat = GL_R8; - } - if (!paletteLookupTex) - pglGenTextures(1, &paletteLookupTex); - pglActiveTexture(GL_TEXTURE1); - pglBindTexture(GL_TEXTURE_3D, paletteLookupTex); - pglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexImage3D(GL_TEXTURE_3D, 0, internalFormat, HWR_PALETTE_LUT_SIZE, HWR_PALETTE_LUT_SIZE, HWR_PALETTE_LUT_SIZE, - 0, GL_RED, GL_UNSIGNED_BYTE, lut); - pglActiveTexture(GL_TEXTURE0); -} - -EXPORT UINT32 HWRAPI(CreateLightTable)(RGBA_t *hw_lighttable) -{ - LTListItem *item = malloc(sizeof(LTListItem)); - if (!LightTablesTail) - { - LightTablesHead = LightTablesTail = item; - } - else - { - LightTablesTail->next = item; - LightTablesTail = item; - } - item->next = NULL; - pglGenTextures(1, &item->id); - pglBindTexture(GL_TEXTURE_2D, item->id); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, hw_lighttable); - - // restore previously bound texture - pglBindTexture(GL_TEXTURE_2D, tex_downloaded); - - return item->id; -} - -// Delete light table textures, ids given before become invalid and must not be used. -EXPORT void HWRAPI(ClearLightTables)(void) -{ - while (LightTablesHead) - { - LTListItem *item = LightTablesHead; - pglDeleteTextures(1, (GLuint *)&item->id); - LightTablesHead = item->next; - free(item); - } - - LightTablesTail = NULL; - - // we no longer have a bound light table (if we had one), we just deleted it! - lt_downloaded = 0; -} - -// This palette is used for the palette rendering postprocessing step. -EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette) -{ - if (memcmp(screenPalette, palette, sizeof(screenPalette))) - { - memcpy(screenPalette, palette, sizeof(screenPalette)); - if (!screenPaletteTex) - pglGenTextures(1, &screenPaletteTex); - pglActiveTexture(GL_TEXTURE2); - pglBindTexture(GL_TEXTURE_1D, screenPaletteTex); - pglTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - pglTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - pglTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, palette); - pglActiveTexture(GL_TEXTURE0); - } + tex_downloaded = finalScreenTexture; } #endif //HWRENDER diff --git a/src/hardware/r_opengl/r_opengl.h b/src/hardware/r_opengl/r_opengl.h index 0281122ee..f09d0bbeb 100644 --- a/src/hardware/r_opengl/r_opengl.h +++ b/src/hardware/r_opengl/r_opengl.h @@ -37,7 +37,6 @@ #define _CREATE_DLL_ // necessary for Unix AND Windows #include "../../doomdef.h" #include "../hw_drv.h" -#include "../../z_zone.h" #ifdef __cplusplus extern "C" { @@ -54,10 +53,10 @@ extern "C" { #define DEBUG_TO_FILE // output debugging msgs to ogllog.txt // todo: find some way of getting SDL to log to ogllog.txt, without -// interfering with r_opengl.dll r_opengl.dll is gone since over a decade lol -//#ifdef HAVE_SDL -//#undef DEBUG_TO_FILE -//#endif +// interfering with r_opengl.dll +#ifdef HAVE_SDL +#undef DEBUG_TO_FILE +#endif //#if defined(HAVE_SDL) && !defined(_DEBUG) //#undef DEBUG_TO_FILE //#endif diff --git a/src/r_data.c b/src/r_data.c index 247cea619..59ecb0717 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -32,7 +32,7 @@ #include "dehacked.h" #ifdef HWRENDER -#include "hardware/hw_glob.h" // HWR_ClearLightTables +#include "hardware/hw_glob.h" #endif // DRRR @@ -374,9 +374,6 @@ void R_ClearColormaps(void) { // Purged by PU_LEVEL, just overwrite the pointer extra_colormaps = R_CreateDefaultColormap(true); -#ifdef HWRENDER - HWR_ClearLightTables(); -#endif } // diff --git a/src/r_defs.h b/src/r_defs.h index da3f547c8..44c3bf56d 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -76,11 +76,6 @@ struct extracolormap_t lighttable_t *colormap; -#ifdef HWRENDER - // The id of the hardware lighttable. Zero means it does not exist yet. - UINT32 gl_lighttable_id; -#endif - #ifdef EXTRACOLORMAPLUMPS lumpnum_t lump; // for colormap lump matching, init to LUMPERROR char lumpname[9]; // for netsyncing diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index e5a8d504d..c854e7174 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -66,7 +66,7 @@ void *hwSym(const char *funcName,void *handle) { void *funcPointer = NULL; #ifdef HWRENDER - if (fastcmp("SetTexturePalette", funcName)) + if (fastcmp("SetPalette", funcName)) funcPointer = FUNCPTRCAST(&OglSdlSetPalette); GETFUNC(Init); @@ -79,7 +79,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(SetTexture); GETFUNC(UpdateTexture); GETFUNC(DeleteTexture); - GETFUNC(ReadScreenTexture); + GETFUNC(ReadScreenFinalTexture); GETFUNC(GClipRect); GETFUNC(ClearMipMapCache); GETFUNC(SetSpecialState); @@ -89,24 +89,23 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(SetTransform); GETFUNC(PostImgRedraw); GETFUNC(FlushScreenTextures); + GETFUNC(StartScreenWipe); + GETFUNC(EndScreenWipe); GETFUNC(DoScreenWipe); - GETFUNC(RenderVhsEffect); - GETFUNC(DrawScreenTexture); + GETFUNC(MakeIntermissionBG); + GETFUNC(DrawIntermissionBG); GETFUNC(MakeScreenTexture); + GETFUNC(RenderVhsEffect); + GETFUNC(MakeScreenFinalTexture); GETFUNC(DrawScreenFinalTexture); - GETFUNC(InitShaders); - GETFUNC(LoadShader); - GETFUNC(CompileShader); + GETFUNC(CompileShaders); + GETFUNC(CleanShaders); GETFUNC(SetShader); GETFUNC(UnSetShader); GETFUNC(SetShaderInfo); - - GETFUNC(SetPaletteLookup); - GETFUNC(CreateLightTable); - GETFUNC(ClearLightTables); - GETFUNC(SetScreenPalette); + GETFUNC(LoadCustomShader); #else //HWRENDER if (fastcmp("FinishUpdate", funcName)) diff --git a/src/sdl/i_video.cpp b/src/sdl/i_video.cpp index 3b7caafa4..aebdf8435 100644 --- a/src/sdl/i_video.cpp +++ b/src/sdl/i_video.cpp @@ -1318,17 +1318,7 @@ void I_FinishUpdate(void) } #ifdef HWRENDER else if (rendermode == render_opengl) - { - // Final postprocess step of palette rendering, after everything else has been drawn. - if (HWR_ShouldUsePaletteRendering()) - { - HWD.pfnMakeScreenTexture(HWD_SCREENTEXTURE_GENERIC2); - HWD.pfnSetShader(HWR_GetShaderFromTarget(SHADER_PALETTE_POSTPROCESS)); - HWD.pfnDrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2, NULL, 0); - HWD.pfnUnSetShader(); - } OglSdlFinishUpdate(cv_vidwait.value); - } #endif } @@ -1767,34 +1757,34 @@ static void Impl_InitOpenGL(void) *(void**)&HWD.pfnSetTexture = hwSym("SetTexture",NULL); *(void**)&HWD.pfnUpdateTexture = hwSym("UpdateTexture",NULL); *(void**)&HWD.pfnDeleteTexture = hwSym("DeleteTexture",NULL); - *(void**)&HWD.pfnReadScreenTexture= hwSym("ReadScreenTexture",NULL); + *(void**)&HWD.pfnReadScreenFinalTexture=hwSym("ReadScreenFinalTexture",NULL); *(void**)&HWD.pfnGClipRect = hwSym("GClipRect",NULL); *(void**)&HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); *(void**)&HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); - *(void**)&HWD.pfnSetTexturePalette= hwSym("SetTexturePalette",NULL); + *(void**)&HWD.pfnSetPalette = hwSym("SetPalette",NULL); *(void**)&HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); *(void**)&HWD.pfnDrawModel = hwSym("DrawModel",NULL); *(void**)&HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL); *(void**)&HWD.pfnSetTransform = hwSym("SetTransform",NULL); *(void**)&HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); *(void**)&HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); + *(void**)&HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); + *(void**)&HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); *(void**)&HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); - *(void**)&HWD.pfnDrawScreenTexture= hwSym("DrawScreenTexture",NULL); + *(void**)&HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); + *(void**)&HWD.pfnMakeIntermissionBG=hwSym("MakeIntermissionBG",NULL); *(void**)&HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); *(void**)&HWD.pfnRenderVhsEffect = hwSym("RenderVhsEffect",NULL); + *(void**)&HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); *(void**)&HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); - *(void**)&HWD.pfnInitShaders = hwSym("InitShaders",NULL); - *(void**)&HWD.pfnLoadShader = hwSym("LoadShader",NULL); - *(void**)&HWD.pfnCompileShader = hwSym("CompileShader",NULL); + *(void**)&HWD.pfnCompileShaders = hwSym("CompileShaders",NULL); + *(void**)&HWD.pfnCleanShaders = hwSym("CleanShaders",NULL); *(void**)&HWD.pfnSetShader = hwSym("SetShader",NULL); *(void**)&HWD.pfnUnSetShader = hwSym("UnSetShader",NULL); *(void**)&HWD.pfnSetShaderInfo = hwSym("SetShaderInfo",NULL); - *(void**)&HWD.pfnSetPaletteLookup = hwSym("SetPaletteLookup",NULL); - *(void**)&HWD.pfnCreateLightTable = hwSym("CreateLightTable",NULL); - *(void**)&HWD.pfnClearLightTables = hwSym("ClearLightTables",NULL); - *(void**)&HWD.pfnSetScreenPalette = hwSym("SetScreenPalette",NULL); + *(void**)&HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL); if (HWD.pfnInit()) vid.glstate = VID_GL_LIBRARY_LOADED; @@ -1803,7 +1793,6 @@ static void Impl_InitOpenGL(void) vid.glstate = VID_GL_LIBRARY_ERROR; CV_StealthSet(&cv_renderer, "Software"); - rendermode = render_soft; if (setrenderneeded) diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index 27ffd06c2..b2c6b4363 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -192,9 +192,7 @@ void OglSdlFinishUpdate(boolean waitvbl) // Sryder: We need to draw the final screen texture again into the other buffer in the original position so that // effects that want to take the old screen can do so after this - // Generic2 has the screen image without palette rendering brightness adjustments. - // Using that here will prevent brightness adjustments being applied twice. - DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC2, NULL, 0); + HWR_DrawScreenFinalTexture(realwidth, realheight); } EXPORT void HWRAPI(OglSdlSetPalette) (RGBA_t *palette) diff --git a/src/st_stuff.c b/src/st_stuff.c index 383d978e1..976a93e7e 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -145,8 +145,8 @@ void ST_doPaletteStuff(void) palette = 0; #ifdef HWRENDER - if (rendermode == render_opengl && !HWR_ShouldUsePaletteRendering()) - palette = 0; // Don't set the palette to a flashpal in OpenGL's truecolor mode + if (rendermode == render_opengl) + palette = 0; // No flashpals here in OpenGL #endif if (palette != st_palette) @@ -970,7 +970,7 @@ void ST_Drawer(void) //25/08/99: Hurdler: palette changes is done for all players, // not only player1! That's why this part // of code is moved somewhere else. - if (rendermode == render_soft || HWR_ShouldUsePaletteRendering()) + if (rendermode == render_soft) #endif if (rendermode != render_none) ST_doPaletteStuff(); diff --git a/src/w_wad.cpp b/src/w_wad.cpp index fb5955974..6ea718573 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -1075,7 +1075,10 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup, boole #ifdef HWRENDER // Read shaders from file if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED)) + { HWR_LoadCustomShadersFromFile(numwadfiles - 1, (type == RET_PK3)); + HWR_CompileShaders(); + } #endif // HWRENDER // check if compatmode is needed diff --git a/src/y_inter.c b/src/y_inter.c index 760bbb134..269501584 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -381,7 +381,7 @@ void Y_ConsiderScreenBuffer(void) else if (rendermode == render_opengl) { y_screenbuffer = Z_Malloc(0, PU_STATIC, NULL); - HWR_DrawIntermissionBG(); + HWR_MakeIntermissionBG(); } #endif }