Shader code cleanup

This commit is contained in:
Jaime Passos 2020-08-07 18:17:05 -03:00
parent cc677d2d50
commit 74dfa9f700
9 changed files with 286 additions and 230 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
// ==========================================================================
// RENDER MODES

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

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

View File

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

View File

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

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);
// 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)

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

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