From 74dfa9f700326497d3fa1922d582a32a5f702cd2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 7 Aug 2020 18:17:05 -0300 Subject: [PATCH] Shader code cleanup --- src/hardware/hw_defs.h | 37 ++++ src/hardware/hw_drv.h | 12 +- src/hardware/hw_main.c | 113 ++++++----- src/hardware/hw_main.h | 9 +- src/hardware/hw_md2.c | 2 +- src/hardware/r_opengl/r_opengl.c | 325 +++++++++++++++---------------- src/sdl/hwsym_sdl.c | 5 +- src/sdl/i_video.c | 9 +- src/w_wad.c | 4 +- 9 files changed, 286 insertions(+), 230 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 715c45ef3..5a5b23f2f 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -132,6 +132,43 @@ typedef struct FLOAT t; // t texture ordinate (t over w) } FOutVector; +#ifdef GL_SHADERS +// Predefined shader types +enum +{ + SHADER_DEFAULT = 0, + + SHADER_FLOOR, + SHADER_WALL, + SHADER_SPRITE, + SHADER_MODEL, SHADER_MODEL_LIGHTING, + SHADER_WATER, + SHADER_FOG, + SHADER_SKY, + + NUMBASESHADERS, +}; + +// 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 +{ + const char *type; + INT32 id; +} customshaderxlat_t; + +#endif + // ========================================================================== // RENDER MODES diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 6f039cc3a..62eea9280 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -68,14 +68,13 @@ EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height); EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]); // jimita -EXPORT boolean HWRAPI(LoadShaders) (void); -EXPORT void HWRAPI(KillShaders) (void); +EXPORT boolean HWRAPI(CompileShaders) (void); +EXPORT void HWRAPI(CleanShaders) (void); EXPORT void HWRAPI(SetShader) (int shader); EXPORT void HWRAPI(UnSetShader) (void); EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value); -EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment); -EXPORT boolean HWRAPI(InitCustomShaders) (void); +EXPORT void HWRAPI(LoadCustomShader) (int number, char *code, size_t size, boolean isfragment); // ========================================================================== // HWR DRIVER OBJECT, FOR CLIENT PROGRAM @@ -120,14 +119,13 @@ struct hwdriver_s MakeScreenFinalTexture pfnMakeScreenFinalTexture; DrawScreenFinalTexture pfnDrawScreenFinalTexture; - LoadShaders pfnLoadShaders; - KillShaders pfnKillShaders; + CompileShaders pfnCompileShaders; + CleanShaders pfnCleanShaders; SetShader pfnSetShader; UnSetShader pfnUnSetShader; SetShaderInfo pfnSetShaderInfo; LoadCustomShader pfnLoadCustomShader; - InitCustomShaders pfnInitCustomShaders; }; extern struct hwdriver_s hwdriver; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index ddc935f0d..ca9fc36f3 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -560,11 +560,11 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool PolyFlags |= PF_Masked|PF_Modulated; if (PolyFlags & PF_Fog) - shader = 6; // fog shader + shader = SHADER_FOG; // fog shader else if (PolyFlags & PF_Ripple) - shader = 5; // water shader + shader = SHADER_WATER; // water shader else - shader = 1; // floor shader + shader = SHADER_FLOOR; // floor shader HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags, shader, false); @@ -761,7 +761,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) break; } - HWD.pfnSetShader(2); // wall shader + HWD.pfnSetShader(SHADER_WALL); // wall shader HWD.pfnDrawPolygon(&pSurf, wallVerts, 4, i|PF_Modulated|PF_Decal); } } @@ -798,7 +798,7 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL { HWR_Lighting(pSurf, lightlevel, wallcolormap); - HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode|PF_Modulated|PF_Occlude, 2, false); // wall shader + HWR_ProcessPolygon(pSurf, wallVerts, 4, blendmode|PF_Modulated|PF_Occlude, SHADER_WALL, false); // wall shader #ifdef WALLSPLATS if (gl_curline->linedef->splats && cv_splats.value) @@ -2833,7 +2833,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, else blendmode |= PF_Masked|PF_Modulated|PF_Clip; - HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, 1, false); // floor shader + HWR_ProcessPolygon(&Surf, planeVerts, nrPlaneVerts, blendmode, SHADER_FLOOR, false); // floor shader } static void HWR_AddPolyObjectPlanes(void) @@ -3645,7 +3645,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) HWR_Lighting(&sSurf, 0, colormap); sSurf.PolyColor.s.alpha = alpha; - HWR_ProcessPolygon(&sSurf, shadowVerts, 4, PF_Translucent|PF_Modulated|PF_Clip, 3, false); // sprite shader + HWR_ProcessPolygon(&sSurf, shadowVerts, 4, PF_Translucent|PF_Modulated|PF_Clip, SHADER_SPRITE, false); // sprite shader } // This is expecting a pointer to an array containing 4 wallVerts for a sprite @@ -3919,7 +3919,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) Surf.PolyColor.s.alpha = alpha; - HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader + HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, SHADER_SPRITE, false); // sprite shader if (use_linkdraw_hack) HWR_LinkDrawHackAdd(wallVerts, spr); @@ -3948,7 +3948,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr) Surf.PolyColor.s.alpha = alpha; - HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader + HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, SHADER_SPRITE, false); // sprite shader if (use_linkdraw_hack) HWR_LinkDrawHackAdd(wallVerts, spr); @@ -4108,7 +4108,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr) if (!occlusion) use_linkdraw_hack = true; } - HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader + HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, SHADER_SPRITE, false); // sprite shader if (use_linkdraw_hack) HWR_LinkDrawHackAdd(wallVerts, spr); @@ -4210,7 +4210,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr) blend = PF_Translucent|PF_Occlude; } - HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, 3, false); // sprite shader + HWR_ProcessPolygon(&Surf, wallVerts, 4, blend|PF_Modulated|PF_Clip, SHADER_SPRITE, false); // sprite shader } #endif @@ -5302,7 +5302,7 @@ static void HWR_DrawSkyBackground(player_t *player) v[0].t = v[1].t -= ((float) angle / angleturn); } - HWD.pfnSetShader(7); // sky shader + HWD.pfnSetShader(SHADER_SKY); // sky shader HWD.pfnDrawPolygon(NULL, v, 4, 0); HWD.pfnSetShader(0); } @@ -5927,7 +5927,6 @@ void HWR_Startup(void) // do this once if (!startupdone) { - INT32 i; CONS_Printf("HWR_Startup()...\n"); HWR_InitPolyPool(); @@ -5938,10 +5937,8 @@ void HWR_Startup(void) HWR_InitLight(); #endif - // read every custom shader - for (i = 0; i < numwadfiles; i++) - HWR_ReadShaders(i, (wadfiles[i]->type == RET_PK3)); - if (!HWR_LoadShaders()) + HWR_LoadAllCustomShaders(); + if (!HWR_CompileShaders()) gl_shadersavailable = false; } @@ -6033,7 +6030,7 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, pSurf->PolyColor.s.alpha = alpha; // put the alpha back after lighting - shader = 2; // wall shader + shader = SHADER_WALL; // wall shader if (blend & PF_Environment) blendmode |= PF_Occlude; // PF_Occlude must be used for solid objects @@ -6041,7 +6038,7 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, if (fogwall) { blendmode |= PF_Fog; - shader = 6; // fog shader + shader = SHADER_FOG; // fog shader } blendmode |= PF_Modulated; // No PF_Occlude means overlapping (incorrect) transparency @@ -6226,13 +6223,7 @@ void HWR_DrawScreenFinalTexture(int width, int height) } // jimita 18032019 -typedef struct -{ - char type[16]; - INT32 id; -} shaderxlat_t; - -static inline UINT16 HWR_CheckShader(UINT16 wadnum) +static inline UINT16 HWR_FindShaderDefs(UINT16 wadnum) { UINT16 i; lumpinfo_t *lump_p; @@ -6245,12 +6236,34 @@ static inline UINT16 HWR_CheckShader(UINT16 wadnum) return INT16_MAX; } -boolean HWR_LoadShaders(void) +boolean HWR_CompileShaders(void) { - return HWD.pfnInitCustomShaders(); + return HWD.pfnCompileShaders(); } -void HWR_ReadShaders(UINT16 wadnum, boolean PK3) +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; @@ -6261,19 +6274,7 @@ void HWR_ReadShaders(UINT16 wadnum, boolean PK3) int shadertype = 0; int i; - #define SHADER_TYPES 7 - shaderxlat_t shaderxlat[SHADER_TYPES] = - { - {"Flat", 1}, - {"WallTexture", 2}, - {"Sprite", 3}, - {"Model", 4}, - {"WaterRipple", 5}, - {"Fog", 6}, - {"Sky", 7}, - }; - - lump = HWR_CheckShader(wadnum); + lump = HWR_FindShaderDefs(wadnum); if (lump == INT16_MAX) return; @@ -6299,7 +6300,7 @@ void HWR_ReadShaders(UINT16 wadnum, boolean PK3) value = strtok(NULL, "\r\n "); if (!value) { - CONS_Alert(CONS_WARNING, "HWR_ReadShaders: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + 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; } @@ -6318,19 +6319,19 @@ skip_lump: value = strtok(NULL, "\r\n= "); if (!value) { - CONS_Alert(CONS_WARNING, "HWR_ReadShaders: Missing shader target (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + 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_ReadShaders: Missing shader type (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + 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; i < SHADER_TYPES; i++) + for (i = 0; shaderxlat[i].type; i++) { if (!stricmp(shaderxlat[i].type, stoken)) { @@ -6356,7 +6357,7 @@ skip_lump: if (shader_lumpnum == INT16_MAX) { - CONS_Alert(CONS_ERROR, "HWR_ReadShaders: Missing shader source %s (file %s, line %d)\n", shader_lumpname, wadfiles[wadnum]->filename, linenum); + 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; } @@ -6382,4 +6383,22 @@ skip_field: 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 ddb3696b6..c1b55340f 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -68,8 +68,13 @@ void HWR_DrawScreenFinalTexture(int width, int height); void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap); UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work -void HWR_ReadShaders(UINT16 wadnum, boolean PK3); -boolean HWR_LoadShaders(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 granisotropicmode_cons_t[]; diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index fa5156758..b25041448 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1549,7 +1549,7 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) p.mirror = atransform.mirror; // from Kart #endif - HWD.pfnSetShader(4); // model shader + HWD.pfnSetShader(SHADER_MODEL); // model shader HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf); } diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 461966224..1686bc0b5 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -91,9 +91,10 @@ static GLuint startScreenWipe = 0; static GLuint endScreenWipe = 0; static GLuint finalScreenTexture = 0; -// Lactozilla: Set shader programs and uniforms +// Lactozilla: Shader functions static void *Shader_Load(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade); static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade); +static void Shader_CompileError(const char *message, GLuint program, INT32 shadernum); // shortcut for ((float)1/i) static const GLfloat byte2float[256] = { @@ -576,15 +577,12 @@ static PFNglUniform2fv pglUniform2fv; static PFNglUniform3fv pglUniform3fv; static PFNglGetUniformLocation pglGetUniformLocation; -#define MAXSHADERS 16 -#define MAXSHADERPROGRAMS 16 - // 18032019 -static char *gl_customvertexshaders[MAXSHADERS]; -static char *gl_customfragmentshaders[MAXSHADERS]; static GLuint gl_currentshaderprogram = 0; static boolean gl_shaderprogramchanged = true; +static shadersource_t gl_customshaders[HWR_MAXSHADERS]; + // 13062019 typedef enum { @@ -608,17 +606,59 @@ typedef struct gl_shaderprogram_s boolean custom; GLint uniforms[gluniform_max+1]; } gl_shaderprogram_t; -static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS]; +static gl_shaderprogram_t gl_shaderprograms[HWR_MAXSHADERS]; // Shader info static INT32 shader_leveltime = 0; -// ======================== -// Fragment shader macros -// ======================== +// ================ +// Vertex shaders +// ================ // -// GLSL Software fragment shader +// 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" + +// replicates the way fixed function lighting is used by the model lighting option, +// stores the lighting result to gl_Color +// (ambient lighting of 0.75 and diffuse lighting from above) +#define GLSL_MODEL_LIGHTING_VERTEX_SHADER \ + "void main()\n" \ + "{\n" \ + "float nDotVP = dot(gl_Normal, vec3(0, 1, 0));\n" \ + "float light = 0.75 + max(nDotVP, 0.0);\n" \ + "gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\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_DOOM_COLORMAP \ @@ -760,110 +800,51 @@ static INT32 shader_leveltime = 0; "}\0" // -// GLSL generic fragment shader +// Sky fragment shader // -#define GLSL_DEFAULT_FRAGMENT_SHADER \ +#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) * poly_color;\n" \ - "}\0" + "gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n" \ + "}\0" \ -static const char *fragment_shaders[] = { - // Default fragment shader - GLSL_DEFAULT_FRAGMENT_SHADER, +// ================ +// Shader sources +// ================ - // Floor fragment shader - GLSL_SOFTWARE_FRAGMENT_SHADER, +static struct { + const char *vertex; + const char *fragment; +} const gl_shadersources[] = { + // Default shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_DEFAULT_FRAGMENT_SHADER}, - // Wall fragment shader - GLSL_SOFTWARE_FRAGMENT_SHADER, + // Floor shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER}, - // Sprite fragment shader - GLSL_SOFTWARE_FRAGMENT_SHADER, + // Wall shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER}, - // Model fragment shader - GLSL_SOFTWARE_FRAGMENT_SHADER, + // Sprite shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER}, - // Water fragment shader - GLSL_WATER_FRAGMENT_SHADER, + // Model shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_SOFTWARE_FRAGMENT_SHADER}, - // Fog fragment shader - GLSL_FOG_FRAGMENT_SHADER, + // Model shader + diffuse lighting from above + {GLSL_MODEL_LIGHTING_VERTEX_SHADER, GLSL_SOFTWARE_MODEL_LIGHTING_FRAGMENT_SHADER}, - // Sky fragment shader - "uniform sampler2D tex;\n" - "void main(void) {\n" - "gl_FragColor = texture2D(tex, gl_TexCoord[0].st);\n" - "}\0", + // Water shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_WATER_FRAGMENT_SHADER}, - // Model fragment shader + diffuse lighting from above - GLSL_SOFTWARE_MODEL_LIGHTING_FRAGMENT_SHADER, + // Fog shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_FOG_FRAGMENT_SHADER}, - NULL, -}; + // Sky shader + {GLSL_DEFAULT_VERTEX_SHADER, GLSL_SKY_FRAGMENT_SHADER}, -// ====================== -// Vertex shader macros -// ====================== - -// -// GLSL 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" - -// replicates the way fixed function lighting is used by the model lighting option, -// stores the lighting result to gl_Color -// (ambient lighting of 0.75 and diffuse lighting from above) -#define GLSL_MODEL_LIGHTING_VERTEX_SHADER \ - "void main()\n" \ - "{\n" \ - "float nDotVP = dot(gl_Normal, vec3(0, 1, 0));\n" \ - "float light = 0.75 + max(nDotVP, 0.0);\n" \ - "gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\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" - -static const char *vertex_shaders[] = { - // Default vertex shader - GLSL_DEFAULT_VERTEX_SHADER, - - // Floor vertex shader - GLSL_DEFAULT_VERTEX_SHADER, - - // Wall vertex shader - GLSL_DEFAULT_VERTEX_SHADER, - - // Sprite vertex shader - GLSL_DEFAULT_VERTEX_SHADER, - - // Model vertex shader - GLSL_DEFAULT_VERTEX_SHADER, - - // Water vertex shader - GLSL_DEFAULT_VERTEX_SHADER, - - // Fog vertex shader - GLSL_DEFAULT_VERTEX_SHADER, - - // Sky vertex shader - GLSL_DEFAULT_VERTEX_SHADER, - - // Model vertex shader + diffuse lighting from above - GLSL_MODEL_LIGHTING_VERTEX_SHADER, - - NULL, + {NULL, NULL}, }; #endif // GL_SHADERS @@ -909,7 +890,7 @@ void SetupGLFunc4(void) } // jimita -EXPORT boolean HWRAPI(LoadShaders) (void) +EXPORT boolean HWRAPI(CompileShaders) (void) { #ifdef GL_SHADERS GLuint gl_vertShader, gl_fragShader; @@ -917,25 +898,23 @@ EXPORT boolean HWRAPI(LoadShaders) (void) if (!pglUseProgram) return false; - gl_customvertexshaders[0] = NULL; - gl_customfragmentshaders[0] = NULL; + gl_customshaders[0].vertex = NULL; + gl_customshaders[0].fragment = NULL; - for (i = 0; vertex_shaders[i] && fragment_shaders[i]; i++) + for (i = 0; gl_shadersources[i].vertex && gl_shadersources[i].fragment; i++) { gl_shaderprogram_t *shader; - const GLchar* vert_shader = vertex_shaders[i]; - const GLchar* frag_shader = fragment_shaders[i]; - boolean custom = ((gl_customvertexshaders[i] || gl_customfragmentshaders[i]) && (i > 0)); + const GLchar *vert_shader = gl_shadersources[i].vertex; + const GLchar *frag_shader = gl_shadersources[i].fragment; + boolean custom = ((gl_customshaders[i].vertex || gl_customshaders[i].fragment) && (i > 0)); // 18032019 - if (gl_customvertexshaders[i]) - vert_shader = gl_customvertexshaders[i]; - if (gl_customfragmentshaders[i]) - frag_shader = gl_customfragmentshaders[i]; + if (gl_customshaders[i].vertex) + vert_shader = gl_customshaders[i].vertex; + if (gl_customshaders[i].fragment) + frag_shader = gl_customshaders[i].fragment; - if (i >= MAXSHADERS) - break; - if (i >= MAXSHADERPROGRAMS) + if (i >= HWR_MAXSHADERS) break; shader = &gl_shaderprograms[i]; @@ -948,7 +927,7 @@ EXPORT boolean HWRAPI(LoadShaders) (void) gl_vertShader = pglCreateShader(GL_VERTEX_SHADER); if (!gl_vertShader) { - GL_MSG_Error("LoadShaders: Error creating vertex shader %d\n", i); + GL_MSG_Error("CompileShaders: Error creating vertex shader %s\n", HWR_GetShaderName(i)); continue; } @@ -959,15 +938,7 @@ EXPORT boolean HWRAPI(LoadShaders) (void) pglGetShaderiv(gl_vertShader, GL_COMPILE_STATUS, &result); if (result == GL_FALSE) { - GLchar* infoLog; - GLint logLength; - - pglGetShaderiv(gl_vertShader, GL_INFO_LOG_LENGTH, &logLength); - - infoLog = malloc(logLength); - pglGetShaderInfoLog(gl_vertShader, logLength, NULL, infoLog); - - GL_MSG_Error("LoadShaders: Error compiling vertex shader %d\n%s", i, infoLog); + Shader_CompileError("Error compiling vertex shader", gl_vertShader, i); continue; } @@ -977,7 +948,7 @@ EXPORT boolean HWRAPI(LoadShaders) (void) gl_fragShader = pglCreateShader(GL_FRAGMENT_SHADER); if (!gl_fragShader) { - GL_MSG_Error("LoadShaders: Error creating fragment shader %d\n", i); + GL_MSG_Error("CompileShaders: Error creating fragment shader %s\n", HWR_GetShaderName(i)); continue; } @@ -988,15 +959,7 @@ EXPORT boolean HWRAPI(LoadShaders) (void) pglGetShaderiv(gl_fragShader, GL_COMPILE_STATUS, &result); if (result == GL_FALSE) { - GLchar* infoLog; - GLint logLength; - - pglGetShaderiv(gl_fragShader, GL_INFO_LOG_LENGTH, &logLength); - - infoLog = malloc(logLength); - pglGetShaderInfoLog(gl_fragShader, logLength, NULL, infoLog); - - GL_MSG_Error("LoadShaders: Error compiling fragment shader %d\n%s", i, infoLog); + Shader_CompileError("Error compiling fragment shader", gl_fragShader, i); continue; } @@ -1017,7 +980,7 @@ EXPORT boolean HWRAPI(LoadShaders) (void) { shader->program = 0; shader->custom = false; - GL_MSG_Error("LoadShaders: Error linking shader program %d\n", i); + GL_MSG_Error("CompileShaders: Error linking shader program %s\n", HWR_GetShaderName(i)); continue; } @@ -1037,8 +1000,10 @@ EXPORT boolean HWRAPI(LoadShaders) (void) #undef GETUNI } -#endif return true; +#else + return false; +#endif } // @@ -1066,25 +1031,34 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value) // // Custom shader loading // -EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment) +EXPORT void HWRAPI(LoadCustomShader) (int number, char *code, size_t size, boolean isfragment) { #ifdef GL_SHADERS - if (!pglUseProgram) return; - if (number < 1 || number > MAXSHADERS) - I_Error("LoadCustomShader(): cannot load shader %d (max %d)", number, MAXSHADERS); + shadersource_t *shader; - if (fragment) - { - gl_customfragmentshaders[number] = malloc(size+1); - strncpy(gl_customfragmentshaders[number], shader, size); - gl_customfragmentshaders[number][size] = 0; + 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 - { - gl_customvertexshaders[number] = malloc(size+1); - strncpy(gl_customvertexshaders[number], shader, size); - gl_customvertexshaders[number][size] = 0; - } + COPYSHADER(vertex) + #else (void)number; (void)shader; @@ -1093,14 +1067,6 @@ EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boo #endif } -EXPORT boolean HWRAPI(InitCustomShaders) (void) -{ -#ifdef GL_SHADERS - KillShaders(); - return LoadShaders(); -#endif -} - EXPORT void HWRAPI(SetShader) (int shader) { #ifdef GL_SHADERS @@ -1108,9 +1074,9 @@ EXPORT void HWRAPI(SetShader) (int shader) { // If using model lighting, set the appropriate shader. // However don't override a custom shader. - // Should use an enum or something... - if (shader == 4 && model_lighting && !gl_shaderprograms[4].custom) - shader = 8; + if (shader == SHADER_MODEL && model_lighting + && !(gl_shaderprograms[SHADER_MODEL].custom && !gl_shaderprograms[SHADER_MODEL_LIGHTING].custom)) + shader = SHADER_MODEL_LIGHTING; if ((GLuint)shader != gl_currentshaderprogram) { gl_currentshaderprogram = shader; @@ -1135,9 +1101,23 @@ EXPORT void HWRAPI(UnSetShader) (void) #endif } -EXPORT void HWRAPI(KillShaders) (void) +EXPORT void HWRAPI(CleanShaders) (void) { - // unused......................... + 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; + } } // -----------------+ @@ -1996,6 +1976,25 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF #endif } +static void Shader_CompileError(const char *message, GLuint program, INT32 shadernum) +{ + GLchar *infoLog = NULL; + GLint logLength; + + pglGetShaderiv(program, GL_INFO_LOG_LENGTH, &logLength); + + if (logLength) + { + infoLog = malloc(logLength); + pglGetShaderInfoLog(program, logLength, NULL, infoLog); + } + + GL_MSG_Error("CompileShaders: %s (%s)\n%s", message, HWR_GetShaderName(shadernum), (infoLog ? infoLog : "")); + + if (infoLog) + free(infoLog); +} + // code that is common between DrawPolygon and DrawIndexedTriangles // the corona thing is there too, i have no idea if that stuff works with DrawIndexedTriangles and batching static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD PolyFlags) diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 416c8d2f5..e545bbb63 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -104,14 +104,13 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(MakeScreenFinalTexture); GETFUNC(DrawScreenFinalTexture); - GETFUNC(LoadShaders); - GETFUNC(KillShaders); + GETFUNC(CompileShaders); + GETFUNC(CleanShaders); GETFUNC(SetShader); GETFUNC(UnSetShader); GETFUNC(SetShaderInfo); GETFUNC(LoadCustomShader); - GETFUNC(InitCustomShaders); #else //HWRENDER if (0 == strcmp("FinishUpdate", funcName)) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 01194a02f..fb6cbea74 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1660,7 +1660,7 @@ static void Impl_SetWindowName(const char *title) static void Impl_SetWindowIcon(void) { if (window && icoSurface) - SDL_SetWindowIcon(window, icoSurface); + SDL_SetWindowIcon(window, icoSurface); } static void Impl_VideoSetupSDLBuffer(void) @@ -1770,7 +1770,7 @@ void I_StartupGraphics(void) // Window icon #ifdef HAVE_IMAGE icoSurface = IMG_ReadXPMFromArray(SDL_icon_xpm); -#endif +#endif // Fury: we do window initialization after GL setup to allow // SDL_GL_LoadLibrary to work well on Windows @@ -1855,14 +1855,13 @@ void VID_StartupOpenGL(void) HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); - HWD.pfnLoadShaders = hwSym("LoadShaders",NULL); - HWD.pfnKillShaders = hwSym("KillShaders",NULL); + HWD.pfnCompileShaders = hwSym("CompileShaders",NULL); + HWD.pfnCleanShaders = hwSym("CleanShaders",NULL); HWD.pfnSetShader = hwSym("SetShader",NULL); HWD.pfnUnSetShader = hwSym("UnSetShader",NULL); HWD.pfnSetShaderInfo = hwSym("SetShaderInfo",NULL); HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL); - HWD.pfnInitCustomShaders= hwSym("InitCustomShaders",NULL); vid_opengl_state = HWD.pfnInit() ? 1 : -1; // let load the OpenGL library diff --git a/src/w_wad.c b/src/w_wad.c index e4a19f30e..a54075121 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -852,8 +852,8 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup) // Read shaders from file if (rendermode == render_opengl && (vid_opengl_state == 1)) { - HWR_ReadShaders(numwadfiles - 1, (type == RET_PK3)); - HWR_LoadShaders(); + HWR_LoadCustomShadersFromFile(numwadfiles - 1, (type == RET_PK3)); + HWR_CompileShaders(); } #endif // HWRENDER