Merge branch 'slight-shader-cleanup' into 'next'

Shader code cleanup

See merge request STJr/SRB2!1103
This commit is contained in:
James R 2020-10-12 18:22:08 -04:00
commit d73fbd8616
9 changed files with 286 additions and 238 deletions

View File

@ -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
typedef struct vbo_vertex_s
{
float x, y, z;

View File

@ -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;

View File

@ -565,11 +565,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);
@ -766,7 +766,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);
}
}
@ -803,7 +803,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)
@ -2843,7 +2843,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)
@ -3655,7 +3655,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
@ -3929,7 +3929,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);
@ -3958,7 +3958,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);
@ -4118,7 +4118,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);
@ -4220,7 +4220,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
@ -4563,7 +4563,7 @@ static void HWR_CreateDrawNodes(void)
// Okay! Let's draw it all! Woo!
HWD.pfnSetTransform(&atransform);
HWD.pfnSetShader(0);
HWD.pfnSetShader(SHADER_DEFAULT);
for (i = 0; i < p; i++)
{
@ -5383,7 +5383,7 @@ static void HWR_DrawSkyBackground(player_t *player)
HWR_BuildSkyDome();
}
HWD.pfnSetShader(7); // sky shader
HWD.pfnSetShader(SHADER_SKY); // sky shader
HWD.pfnSetTransform(&dometransform);
HWD.pfnRenderSkyDome(&gl_sky);
}
@ -5470,7 +5470,7 @@ static void HWR_DrawSkyBackground(player_t *player)
HWD.pfnDrawPolygon(NULL, v, 4, 0);
}
HWD.pfnSetShader(0);
HWD.pfnSetShader(SHADER_DEFAULT);
}
@ -5674,7 +5674,7 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
// Reset the shader state.
HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_glshaders.value);
HWD.pfnSetShader(0);
HWD.pfnSetShader(SHADER_DEFAULT);
validcount++;
@ -5887,7 +5887,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
// Reset the shader state.
HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_glshaders.value);
HWD.pfnSetShader(0);
HWD.pfnSetShader(SHADER_DEFAULT);
rs_numbspcalls = 0;
rs_numpolyobjects = 0;
@ -6090,7 +6090,6 @@ void HWR_Startup(void)
// do this once
if (!startupdone)
{
INT32 i;
CONS_Printf("HWR_Startup()...\n");
HWR_InitPolyPool();
@ -6101,10 +6100,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;
}
@ -6196,7 +6193,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
@ -6204,7 +6201,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
@ -6389,13 +6386,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;
@ -6408,12 +6399,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;
@ -6424,19 +6437,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;
@ -6462,7 +6463,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;
}
@ -6481,19 +6482,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))
{
@ -6519,7 +6520,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;
}
@ -6545,4 +6546,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

View File

@ -70,8 +70,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[];

View File

@ -1572,7 +1572,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);
}

View File

@ -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);
static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
@ -578,15 +579,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
{
@ -610,17 +608,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 \
@ -761,22 +801,10 @@ static INT32 shader_leveltime = 0;
"gl_FragColor = final_color;\n" \
"}\0"
//
// GLSL 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"
//
// Sky fragment shader
// Modulates poly_color with gl_Color
//
#define GLSL_SKY_FRAGMENT_SHADER \
"uniform sampler2D tex;\n" \
"uniform vec4 poly_color;\n" \
@ -784,97 +812,42 @@ static INT32 shader_leveltime = 0;
"gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * gl_Color * poly_color;\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
GLSL_SKY_FRAGMENT_SHADER,
// 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
@ -920,7 +893,7 @@ void SetupGLFunc4(void)
}
// jimita
EXPORT boolean HWRAPI(LoadShaders) (void)
EXPORT boolean HWRAPI(CompileShaders) (void)
{
#ifdef GL_SHADERS
GLuint gl_vertShader, gl_fragShader;
@ -928,25 +901,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];
@ -959,7 +930,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;
}
@ -970,15 +941,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;
}
@ -988,7 +951,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;
}
@ -999,15 +962,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;
}
@ -1028,7 +983,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;
}
@ -1048,8 +1003,10 @@ EXPORT boolean HWRAPI(LoadShaders) (void)
#undef GETUNI
}
#endif
return true;
#else
return false;
#endif
}
//
@ -1077,25 +1034,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;
@ -1104,14 +1070,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
@ -1119,9 +1077,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;
@ -1146,9 +1104,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;
}
}
// -----------------+
@ -2017,6 +1989,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)

View File

@ -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))

View File

@ -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

View File

@ -849,8 +849,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