diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 9cefff68..28e0e934 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -76,6 +76,8 @@ EXPORT void HWRAPI(KillShaders) (void); EXPORT void HWRAPI(SetShader) (int shader); EXPORT void HWRAPI(UnSetShader) (void); +EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment); + // ========================================================================== // HWR DRIVER OBJECT, FOR CLIENT PROGRAM // ========================================================================== @@ -122,6 +124,8 @@ struct hwdriver_s KillShaders pfnKillShaders; SetShader pfnSetShader; UnSetShader pfnUnSetShader; + + LoadCustomShader pfnLoadCustomShader; }; extern struct hwdriver_s hwdriver; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e47b1f58..f841e84d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -353,12 +353,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is if (nrPlaneVerts < 3) //not even a triangle ? return; - if (nrPlaneVerts > UINT16_MAX) // FIXME: exceeds plVerts size - { - CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, UINT16_MAX); - return; - } - // Allocate plane-vertex buffer if we need to if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts) { @@ -505,7 +499,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is HWD.pfnSetShader(1); // jimita: floor shader if (PolyFlags & PF_Ripple) - HWD.pfnSetShader(4); // jimita: water shader + HWD.pfnSetShader(5); // jimita: water shader HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags); } @@ -5206,7 +5200,7 @@ static void HWR_DrawSkyBackground(void) v[0].tow = v[1].tow -= ((float) angle / angleturn); } - HWD.pfnSetShader(5); // jimita: sky shader + HWD.pfnSetShader(6); // jimita: sky shader HWD.pfnDrawPolygon(NULL, v, 4, 0); HWD.pfnSetShader(0); // jimita } @@ -5942,4 +5936,10 @@ void HWR_DrawScreenFinalTexture(int width, int height) HWD.pfnDrawScreenFinalTexture(width, height); } +// jimita 18032019 +void HWR_LoadShader(int number, char *shader, size_t size, boolean fragment) +{ + HWD.pfnLoadCustomShader(number, shader, size, fragment); +} + #endif // HWRENDER diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index ba0c1c84..9ca7eb4d 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -65,6 +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); // 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/hw_md2.c b/src/hardware/hw_md2.c index 708ac4a3..000efc2f 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -860,7 +860,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, con // -----------------+ // HWR_DrawMD2 : Draw MD2 -// : (monsters, bonuses, weapons, lights, ...) +// : // Returns : // -----------------+ @@ -1096,6 +1096,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) p.mirror = atransform.mirror; // from Kart #endif + HWD.pfnSetShader(4); // jimita: model shader HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, &Surf); } } diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 857df2b0..c28d880f 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -514,10 +514,15 @@ static boolean gl_shadersenabled = false; static GLuint gl_currentshaderprogram = 0; static GLuint gl_shaderprograms[MAXSHADERPROGRAMS]; +// 18032019 +static char *gl_customvertexshaders[MAXSHADERS]; +static char *gl_customfragmentshaders[MAXSHADERS]; + typedef GLuint (APIENTRY *PFNglCreateShader) (GLenum); typedef void (APIENTRY *PFNglShaderSource) (GLuint, GLsizei, const GLchar**, GLint*); typedef void (APIENTRY *PFNglCompileShader) (GLuint); typedef void (APIENTRY *PFNglGetShaderiv) (GLuint, GLenum, GLint*); +typedef void (APIENTRY *PFNglGetShaderInfoLog) (GLuint, GLsizei, GLsizei*, GLchar*); typedef void (APIENTRY *PFNglDeleteShader) (GLuint); typedef GLuint (APIENTRY *PFNglCreateProgram) (void); typedef void (APIENTRY *PFNglAttachShader) (GLuint, GLuint); @@ -538,6 +543,7 @@ static PFNglCreateShader pglCreateShader; static PFNglShaderSource pglShaderSource; static PFNglCompileShader pglCompileShader; static PFNglGetShaderiv pglGetShaderiv; +static PFNglGetShaderInfoLog pglGetShaderInfoLog; static PFNglDeleteShader pglDeleteShader; static PFNglCreateProgram pglCreateProgram; static PFNglAttachShader pglAttachShader; @@ -603,7 +609,7 @@ static PFNglGetUniformLocation pglGetUniformLocation; "}\0" static const char *fragment_shaders[] = { - // Default shader + // Default fragment shader "uniform sampler2D tex;\n" "uniform vec4 mix_color;\n" "void main(void) {\n" @@ -612,48 +618,27 @@ static const char *fragment_shaders[] = { "gl_FragColor = mixed_color;\n" "}\0", - // Floor shader + // Floor fragment shader SHARED_FRAGMENT_SHADER, - // Wall shader + // Wall fragment shader SHARED_FRAGMENT_SHADER, - // Sprite shader + // Sprite fragment shader SHARED_FRAGMENT_SHADER, - // Water shader - "uniform sampler2D tex;\n" - "uniform vec4 mix_color;\n" - "uniform vec4 fade_color;\n" - "uniform float lighting;\n" - "uniform int fog_mode;\n" - "uniform int fog_density;\n" - "uniform float leveltime;\n" + // Model fragment shader + SHARED_FRAGMENT_SHADER, - GLSL_SHARED_FOG_FUNCTION + // Water fragment shader + SHARED_FRAGMENT_SHADER, - "void main(void) {\n" - "float texU = gl_TexCoord[0].s;\n" - "float texV = gl_TexCoord[0].t;\n" - "float wtofs = leveltime/16;\n" - "float pi = 3.14159265358979323846;\n" - "texU += cos(pi * 2.0 * (texV/4 + wtofs * 0.125)) * 0.3;\n" - "texV += sin(pi * 2.0 * (texV/6 + wtofs * 0.125)) * 0.4;\n" - "vec4 color = texture2D(tex, vec2(texU, texV));\n" - - GLSL_SHARED_FOG_MIX - - "gl_FragColor = final_color;\n" - "}\0", - - // Sky shader + // Sky fragment shader "uniform sampler2D tex;\n" "uniform vec2 resolution;\n" "void main(void) {\n" "float texU = gl_TexCoord[0].s;\n" "float texV = gl_TexCoord[0].t;\n" - //"float scale = abs(gl_FragCoord.x - (resolution.x/2.0));\n" - //"scale /= resolution.x;\n" "gl_FragColor = texture2D(tex, vec2(texU, texV));\n" "}\0", }; @@ -663,7 +648,7 @@ static const char *fragment_shaders[] = { // // Macro to reduce boilerplate code -#define SHARED_VERTEX_SHADER \ +#define DEFAULT_VERTEX_SHADER \ "void main()\n" \ "{\n" \ "gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \ @@ -673,23 +658,26 @@ static const char *fragment_shaders[] = { "}\0" static const char *vertex_shaders[] = { - // Default shader - SHARED_VERTEX_SHADER, + // Default vertex shader + DEFAULT_VERTEX_SHADER, - // Floor shader - SHARED_VERTEX_SHADER, + // Floor vertex shader + DEFAULT_VERTEX_SHADER, - // Wall shader - SHARED_VERTEX_SHADER, + // Wall vertex shader + DEFAULT_VERTEX_SHADER, - // Sprite shader - SHARED_VERTEX_SHADER, + // Sprite vertex shader + DEFAULT_VERTEX_SHADER, - // Water shader - SHARED_VERTEX_SHADER, + // Model vertex shader + DEFAULT_VERTEX_SHADER, - // Sky shader - SHARED_VERTEX_SHADER, + // Water vertex shader + DEFAULT_VERTEX_SHADER, + + // Sky vertex shader + DEFAULT_VERTEX_SHADER, }; #endif // USE_SHADERS @@ -710,6 +698,7 @@ void SetupGLFunc4(void) pglShaderSource = GetGLFunc("glShaderSource"); pglCompileShader = GetGLFunc("glCompileShader"); pglGetShaderiv = GetGLFunc("glGetShaderiv"); + pglGetShaderInfoLog = GetGLFunc("glGetShaderInfoLog"); pglDeleteShader = GetGLFunc("glDeleteShader"); pglCreateProgram = GetGLFunc("glCreateProgram"); pglAttachShader = GetGLFunc("glAttachShader"); @@ -742,6 +731,14 @@ EXPORT void HWRAPI(LoadShaders) (void) { const GLchar* vert_shader = vertex_shaders[i]; const GLchar* frag_shader = fragment_shaders[i]; + + // 18032019 + if (gl_customvertexshaders[i]) + vert_shader = gl_customvertexshaders[i]; + + if (gl_customfragmentshaders[i]) + frag_shader = gl_customfragmentshaders[i]; + if (i >= MAXSHADERS || i >= MAXSHADERPROGRAMS) break; @@ -758,7 +755,17 @@ EXPORT void HWRAPI(LoadShaders) (void) // check for compile errors pglGetShaderiv(gl_vertShader, GL_COMPILE_STATUS, &result); if (result == GL_FALSE) - I_Error("Hardware driver: Error compiling vertex shader %d", i); + { + GLchar* infoLog; + GLint logLength; + + pglGetShaderiv(gl_vertShader, GL_INFO_LOG_LENGTH, &logLength); + + infoLog = malloc(logLength); + pglGetShaderInfoLog(gl_vertShader, logLength, NULL, infoLog); + + I_Error("Hardware driver: Error compiling vertex shader %d\n%s", i, infoLog); + } // // Load and compile fragment shader @@ -773,7 +780,17 @@ EXPORT void HWRAPI(LoadShaders) (void) // check for compile errors pglGetShaderiv(gl_fragShader, GL_COMPILE_STATUS, &result); if (result == GL_FALSE) - I_Error("Hardware driver: Error compiling fragment shader %d", i); + { + GLchar* infoLog; + GLint logLength; + + pglGetShaderiv(gl_fragShader, GL_INFO_LOG_LENGTH, &logLength); + + infoLog = malloc(logLength); + pglGetShaderInfoLog(gl_fragShader, logLength, NULL, infoLog); + + I_Error("Hardware driver: Error compiling fragment shader %d\n%s", i, infoLog); + } gl_shaderprograms[i] = pglCreateProgram(); pglAttachShader(gl_shaderprograms[i], gl_vertShader); @@ -788,6 +805,33 @@ EXPORT void HWRAPI(LoadShaders) (void) #endif } +EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment) +{ +#ifdef USE_SHADERS + (void)shader; + (void)size; + (void)fragment; + if (number < 1 || number > MAXSHADERS) + I_Error("LoadCustomShader(): cannot load shader %d (max %d)", number, MAXSHADERS); + + if (fragment) + { + gl_customfragmentshaders[number] = malloc(size+1); + strncpy(gl_customfragmentshaders[number], shader, size); + gl_customfragmentshaders[number][size] = 0; + } + else + { + gl_customvertexshaders[number] = malloc(size+1); + strncpy(gl_customvertexshaders[number], shader, size); + gl_customvertexshaders[number][size] = 0; + } + + KillShaders(); + LoadShaders(); +#endif +} + EXPORT void HWRAPI(SetShader) (int shader) { #ifdef USE_SHADERS diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 22faeb8d..2bb4f117 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -108,6 +108,8 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(SetShader); GETFUNC(UnSetShader); + GETFUNC(LoadCustomShader); + #else //HWRENDER if (0 == strcmp("FinishUpdate", funcName)) return funcPointer; //&FinishUpdate; diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index caf02049..ac1ac505 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1505,6 +1505,8 @@ void I_StartupGraphics(void) HWD.pfnSetShader = hwSym("SetShader",NULL); HWD.pfnUnSetShader = hwSym("UnSetShader",NULL); + HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL); + // check gl renderer lib if (HWD.pfnGetRenderVersion() != VERSION) I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); diff --git a/src/w_wad.c b/src/w_wad.c index 1279c23e..74cae20f 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -181,6 +181,24 @@ 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) { @@ -195,6 +213,7 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum) LUA_LoadLump(wadnum, posStart); } #endif + posStart = W_CheckNumForFolderStartPK3("SOC/", wadnum, 0); if (posStart != INT16_MAX) { @@ -211,8 +230,22 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum) DEH_LoadDehackedLumpPwad(wadnum, posStart); 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 @@ -256,6 +289,20 @@ 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 { @@ -1694,6 +1741,8 @@ int W_VerifyNMUSlumps(const char *filename) {"PAL", 3}, {"CLM", 3}, {"TRANS", 5}, + {"VRTSHD", 6}, + {"FRGSHD", 6}, {NULL, 0}, }; return W_VerifyFile(filename, NMUSlist, false);