From f714cba3102d73a428a79e7abf10e622808ca519 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 19 Mar 2019 17:37:04 -0300 Subject: [PATCH] Improve custom shader support --- src/hardware/hw_drv.h | 2 + src/hardware/hw_main.c | 134 ++++++++++++++++++++++++++++++- src/hardware/hw_main.h | 2 +- src/hardware/r_opengl/r_opengl.c | 5 ++ src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.c | 1 + src/w_wad.c | 55 ++----------- 7 files changed, 148 insertions(+), 52 deletions(-) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 28e0e934..0b927bd0 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -77,6 +77,7 @@ EXPORT void HWRAPI(SetShader) (int shader); EXPORT void HWRAPI(UnSetShader) (void); EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment); +EXPORT void HWRAPI(InitCustomShaders) (void); // ========================================================================== // HWR DRIVER OBJECT, FOR CLIENT PROGRAM @@ -126,6 +127,7 @@ struct hwdriver_s UnSetShader pfnUnSetShader; LoadCustomShader pfnLoadCustomShader; + InitCustomShaders pfnInitCustomShaders; }; extern struct hwdriver_s hwdriver; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index f841e84d..190ee0a6 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5937,9 +5937,139 @@ void HWR_DrawScreenFinalTexture(int width, int height) } // jimita 18032019 -void HWR_LoadShader(int number, char *shader, size_t size, boolean fragment) +typedef struct { - HWD.pfnLoadCustomShader(number, shader, size, fragment); + char type[16]; + INT32 id; +} shaderxlat_t; + +static inline UINT16 HWR_CheckShader(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; +} + +void HWR_LoadShaders(UINT16 wadnum) +{ + UINT16 lump; + char *shaderdef, *line; + char *stoken; + char *value; + size_t size; + int linenum = 1; + int shadertype = 0; + int i; + + #define SHADER_TYPES 6 + shaderxlat_t shaderxlat[SHADER_TYPES] = + { + {"Flat", 1}, + {"WallTexture", 2}, + {"Sprite", 3}, + {"Model", 4}, + {"WaterRipple", 5}, + {"Sky", 6}, + }; + + lump = HWR_CheckShader(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); + if (!line) + I_Error("HWR_LoadShaders: No more free memory\n"); + + M_Memcpy(line, shaderdef, size); + line[size] = '\0'; + + stoken = strtok(line, "\r\n "); + while (stoken) + { + if (!stricmp(stoken, "GLSL")) + { + value = strtok(NULL, "\r\n "); + if (!value) + { + CONS_Alert(CONS_WARNING, "HWR_LoadShaders: 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_LoadShaders: Missing shader source (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_LoadShaders: Missing shader target (file %s, line %d)\n", wadfiles[wadnum]->filename, linenum); + Z_Free(line); + return; + } + + for (i = 0; i < SHADER_TYPES; i++) + { + if (!stricmp(shaderxlat[i].type, stoken)) + { + size_t shader_size; + char *shader_source; + char shader_lumpname[9]; + UINT16 shader_lumpnum; + + 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_LoadShaders: Missing shader source %s (file %s, line %d)\n", shader_lumpname, wadfiles[wadnum]->filename, linenum); + break; + } + + 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); + } + } + +skip_field: + stoken = strtok(NULL, "\r\n= "); + linenum++; + } + } + + HWD.pfnInitCustomShaders(); + + Z_Free(line); + return; } #endif // HWRENDER diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 9ca7eb4d..3a2969ac 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -65,7 +65,7 @@ void HWR_DrawIntermissionBG(void); void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum); void HWR_MakeScreenFinalTexture(void); void HWR_DrawScreenFinalTexture(int width, int height); -void HWR_LoadShader(int number, char *shader, size_t size, boolean fragment); +void HWR_LoadShaders(UINT16 wadnum); // This stuff is put here so MD2's can use them void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, UINT32 mixcolor, UINT32 fadecolor); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 6ad231d4..d094ba7c 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -823,7 +823,12 @@ EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boo strncpy(gl_customvertexshaders[number], shader, size); gl_customvertexshaders[number][size] = 0; } +#endif +} +EXPORT void HWRAPI(InitCustomShaders) (void) +{ +#ifdef USE_SHADERS KillShaders(); LoadShaders(); #endif diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 2bb4f117..0774bc73 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -109,6 +109,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(UnSetShader); 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 ac1ac505..b967e7a6 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1506,6 +1506,7 @@ void I_StartupGraphics(void) HWD.pfnUnSetShader = hwSym("UnSetShader",NULL); HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL); + HWD.pfnInitCustomShaders = hwSym("InitCustomShaders",NULL); // check gl renderer lib if (HWD.pfnGetRenderVersion() != VERSION) diff --git a/src/w_wad.c b/src/w_wad.c index 74cae20f..26224c2f 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -181,24 +181,6 @@ FILE *W_OpenWadFile(const char **filename, boolean useerrors) return handle; } -static inline void W_LoadShader(UINT16 wadnum, UINT16 lump, char *name, boolean fragment) -{ - size_t shader_size; - char *shader_string; - char shader_number[2]; - - shader_size = W_LumpLengthPwad(wadnum, lump); - shader_string = Z_Malloc(shader_size, PU_STATIC, NULL); - W_ReadLumpPwad(wadnum, lump, shader_string); - - shader_number[0] = name[6]; - shader_number[1] = name[7]; - - HWR_LoadShader(atoi(shader_number), shader_string, shader_size, fragment); - - Z_Free(shader_string); -} - // Look for all DEHACKED and Lua scripts inside a PK3 archive. static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum) { @@ -231,21 +213,6 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum) free(name); } } - - // jimita 18032019 -#ifdef HWRENDER - posStart = W_CheckNumForFolderStartPK3("Shaders/", wadnum, 0); - if (posStart != INT16_MAX) - { - posEnd = W_CheckNumForFolderEndPK3("Shaders/", wadnum, posStart); - posStart++; - for (; posStart < posEnd; posStart++) - { - lumpinfo_t *lump_p = &wadfiles[wadnum]->lumpinfo[posStart]; - W_LoadShader(wadnum, posStart, lump_p->name2, !(memcmp(lump_p->name2,"FRGSHD",6))); - } - } -#endif } // search for all DEHACKED lump in all wads and load it @@ -289,20 +256,6 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum) } } - // jimita 18032019 -#ifdef HWRENDER - { - lumpinfo_t *lump_p = wadfiles[wadnum]->lumpinfo; - for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++) - { - boolean vertex = (!(memcmp(lump_p->name,"VRTSHD",6))); - boolean fragment = (!(memcmp(lump_p->name,"FRGSHD",6))); - if (vertex || fragment) - W_LoadShader(wadnum, lump, lump_p->name, fragment); - } - } -#endif - #ifdef SCANTHINGS // Scan maps for emblems 'n shit { @@ -828,6 +781,11 @@ UINT16 W_InitFile(const char *filename) wadfiles[numwadfiles] = wadfile; numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded +#ifdef HWRENDER + if (rendermode == render_opengl) + HWR_LoadShaders(numwadfiles - 1); +#endif + // TODO: HACK ALERT - Load Lua & SOC stuff right here. I feel like this should be out of this place, but... Let's stick with this for now. switch (wadfile->type) { @@ -1741,8 +1699,7 @@ int W_VerifyNMUSlumps(const char *filename) {"PAL", 3}, {"CLM", 3}, {"TRANS", 5}, - {"VRTSHD", 6}, - {"FRGSHD", 6}, + {"SH_", 3}, {NULL, 0}, }; return W_VerifyFile(filename, NMUSlist, false);