Merge branch 'allowshaders' into 'next'

Let the server or an admin toggle clients' custom shaders

See merge request STJr/SRB2!1181
This commit is contained in:
James R 2020-11-08 21:09:56 -05:00
commit 876aeb6a31
7 changed files with 250 additions and 182 deletions

View File

@ -295,6 +295,16 @@ enum hwdsetspecialstate
typedef enum hwdsetspecialstate hwdspecialstate_t; typedef enum hwdsetspecialstate hwdspecialstate_t;
// Lactozilla: Shader options
enum hwdshaderoption
{
HWD_SHADEROPTION_OFF,
HWD_SHADEROPTION_ON,
HWD_SHADEROPTION_NOCUSTOM,
};
typedef enum hwdshaderoption hwdshaderoption_t;
// Lactozilla: Shader info // Lactozilla: Shader info
// Generally set at the start of the frame. // Generally set at the start of the frame.
enum hwdshaderinfo enum hwdshaderinfo

View File

@ -70,7 +70,7 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
// jimita // jimita
EXPORT boolean HWRAPI(CompileShaders) (void); EXPORT boolean HWRAPI(CompileShaders) (void);
EXPORT void HWRAPI(CleanShaders) (void); EXPORT void HWRAPI(CleanShaders) (void);
EXPORT void HWRAPI(SetShader) (int shader); EXPORT void HWRAPI(SetShader) (int type);
EXPORT void HWRAPI(UnSetShader) (void); EXPORT void HWRAPI(UnSetShader) (void);
EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value); EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value);

View File

@ -5556,6 +5556,20 @@ static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean
trans->anglex = (float)(gl_aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); trans->anglex = (float)(gl_aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
} }
//
// Sets the shader state.
//
static void HWR_SetShaderState(void)
{
hwdshaderoption_t state = cv_glshaders.value;
if (!cv_glallowshaders.value)
state = (cv_glshaders.value == HWD_SHADEROPTION_ON ? HWD_SHADEROPTION_NOCUSTOM : cv_glshaders.value);
HWD.pfnSetSpecialState(HWD_SET_SHADERS, (INT32)state);
HWD.pfnSetShader(SHADER_DEFAULT);
}
// ========================================================================== // ==========================================================================
// Same as rendering the player view, but from the skybox object // Same as rendering the player view, but from the skybox object
// ========================================================================== // ==========================================================================
@ -5674,8 +5688,7 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
HWD.pfnSetTransform(&atransform); HWD.pfnSetTransform(&atransform);
// Reset the shader state. // Reset the shader state.
HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_glshaders.value); HWR_SetShaderState();
HWD.pfnSetShader(SHADER_DEFAULT);
validcount++; validcount++;
@ -5889,8 +5902,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
HWD.pfnSetTransform(&atransform); HWD.pfnSetTransform(&atransform);
// Reset the shader state. // Reset the shader state.
HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_glshaders.value); HWR_SetShaderState();
HWD.pfnSetShader(SHADER_DEFAULT);
ps_numbspcalls = 0; ps_numbspcalls = 0;
ps_numpolyobjects = 0; ps_numpolyobjects = 0;
@ -5985,9 +5997,10 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
// 3D ENGINE COMMANDS // 3D ENGINE COMMANDS
// ========================================================================== // ==========================================================================
static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; static CV_PossibleValue_t glshaders_cons_t[] = {{HWD_SHADEROPTION_OFF, "Off"}, {HWD_SHADEROPTION_ON, "On"}, {HWD_SHADEROPTION_NOCUSTOM, "Ignore custom shaders"}, {0, NULL}};
static CV_PossibleValue_t grfakecontrast_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}}; static CV_PossibleValue_t glmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}};
static CV_PossibleValue_t grshearing_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Third-person"}, {0, NULL}}; static CV_PossibleValue_t glfakecontrast_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}};
static CV_PossibleValue_t glshearing_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Third-person"}, {0, NULL}};
static void CV_glfiltermode_OnChange(void); static void CV_glfiltermode_OnChange(void);
static void CV_glanisotropic_OnChange(void); static void CV_glanisotropic_OnChange(void);
@ -5998,9 +6011,10 @@ static CV_PossibleValue_t glfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSA
{HWD_SET_TEXTUREFILTER_MIXED2, "Nearest_Linear"}, {HWD_SET_TEXTUREFILTER_MIXED2, "Nearest_Linear"},
{HWD_SET_TEXTUREFILTER_MIXED3, "Nearest_Mipmap"}, {HWD_SET_TEXTUREFILTER_MIXED3, "Nearest_Mipmap"},
{0, NULL}}; {0, NULL}};
CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}}; CV_PossibleValue_t glanisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}};
consvar_t cv_glshaders = CVAR_INIT ("gr_shaders", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_glshaders = CVAR_INIT ("gr_shaders", "On", CV_SAVE, glshaders_cons_t, NULL);
consvar_t cv_glallowshaders = CVAR_INIT ("gr_allowclientshaders", "On", CV_NETVAR, CV_OnOff, NULL);
consvar_t cv_fovchange = CVAR_INIT ("gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL); consvar_t cv_fovchange = CVAR_INIT ("gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL);
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING
@ -6011,17 +6025,17 @@ consvar_t cv_glcoronasize = CVAR_INIT ("gr_coronasize", "1", CV_SAVE|CV_FLOAT, 0
#endif #endif
consvar_t cv_glmodels = CVAR_INIT ("gr_models", "Off", CV_SAVE, CV_OnOff, NULL); consvar_t cv_glmodels = CVAR_INIT ("gr_models", "Off", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_glmodelinterpolation = CVAR_INIT ("gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL); consvar_t cv_glmodelinterpolation = CVAR_INIT ("gr_modelinterpolation", "Sometimes", CV_SAVE, glmodelinterpolation_cons_t, NULL);
consvar_t cv_glmodellighting = CVAR_INIT ("gr_modellighting", "Off", CV_SAVE, CV_OnOff, NULL); consvar_t cv_glmodellighting = CVAR_INIT ("gr_modellighting", "Off", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_glshearing = CVAR_INIT ("gr_shearing", "Off", CV_SAVE, grshearing_cons_t, NULL); consvar_t cv_glshearing = CVAR_INIT ("gr_shearing", "Off", CV_SAVE, glshearing_cons_t, NULL);
consvar_t cv_glspritebillboarding = CVAR_INIT ("gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL); consvar_t cv_glspritebillboarding = CVAR_INIT ("gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_glskydome = CVAR_INIT ("gr_skydome", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_glskydome = CVAR_INIT ("gr_skydome", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_glfakecontrast = CVAR_INIT ("gr_fakecontrast", "Smooth", CV_SAVE, grfakecontrast_cons_t, NULL); consvar_t cv_glfakecontrast = CVAR_INIT ("gr_fakecontrast", "Smooth", CV_SAVE, glfakecontrast_cons_t, NULL);
consvar_t cv_glslopecontrast = CVAR_INIT ("gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NULL); consvar_t cv_glslopecontrast = CVAR_INIT ("gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_glfiltermode = CVAR_INIT ("gr_filtermode", "Nearest", CV_SAVE|CV_CALL, glfiltermode_cons_t, CV_glfiltermode_OnChange); consvar_t cv_glfiltermode = CVAR_INIT ("gr_filtermode", "Nearest", CV_SAVE|CV_CALL, glfiltermode_cons_t, CV_glfiltermode_OnChange);
consvar_t cv_glanisotropicmode = CVAR_INIT ("gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t, CV_glanisotropic_OnChange); consvar_t cv_glanisotropicmode = CVAR_INIT ("gr_anisotropicmode", "1", CV_CALL, glanisotropicmode_cons_t, CV_glanisotropic_OnChange);
consvar_t cv_glsolvetjoin = CVAR_INIT ("gr_solvetjoin", "On", 0, CV_OnOff, NULL); consvar_t cv_glsolvetjoin = CVAR_INIT ("gr_solvetjoin", "On", 0, CV_OnOff, NULL);
@ -6060,6 +6074,7 @@ void HWR_AddCommands(void)
CV_RegisterVar(&cv_glfakecontrast); CV_RegisterVar(&cv_glfakecontrast);
CV_RegisterVar(&cv_glshearing); CV_RegisterVar(&cv_glshearing);
CV_RegisterVar(&cv_glshaders); CV_RegisterVar(&cv_glshaders);
CV_RegisterVar(&cv_glallowshaders);
CV_RegisterVar(&cv_glfiltermode); CV_RegisterVar(&cv_glfiltermode);
CV_RegisterVar(&cv_glsolvetjoin); CV_RegisterVar(&cv_glsolvetjoin);

View File

@ -78,7 +78,7 @@ const char *HWR_GetShaderName(INT32 shader);
extern customshaderxlat_t shaderxlat[]; extern customshaderxlat_t shaderxlat[];
extern CV_PossibleValue_t granisotropicmode_cons_t[]; extern CV_PossibleValue_t glanisotropicmode_cons_t[];
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING
extern consvar_t cv_gldynamiclighting; extern consvar_t cv_gldynamiclighting;
@ -87,7 +87,7 @@ extern consvar_t cv_glcoronas;
extern consvar_t cv_glcoronasize; extern consvar_t cv_glcoronasize;
#endif #endif
extern consvar_t cv_glshaders; extern consvar_t cv_glshaders, cv_glallowshaders;
extern consvar_t cv_glmodels; extern consvar_t cv_glmodels;
extern consvar_t cv_glmodelinterpolation; extern consvar_t cv_glmodelinterpolation;
extern consvar_t cv_glmodellighting; extern consvar_t cv_glmodellighting;

View File

@ -91,13 +91,6 @@ static GLuint startScreenWipe = 0;
static GLuint endScreenWipe = 0; static GLuint endScreenWipe = 0;
static GLuint finalScreenTexture = 0; static GLuint finalScreenTexture = 0;
// 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};
// shortcut for ((float)1/i) // shortcut for ((float)1/i)
static const GLfloat byte2float[256] = { static const GLfloat byte2float[256] = {
0.000000f, 0.003922f, 0.007843f, 0.011765f, 0.015686f, 0.019608f, 0.023529f, 0.027451f, 0.000000f, 0.003922f, 0.007843f, 0.011765f, 0.015686f, 0.019608f, 0.023529f, 0.027451f,
@ -533,8 +526,8 @@ boolean SetupGLfunc(void)
return true; return true;
} }
static boolean gl_allowshaders = false;
static boolean gl_shadersenabled = false; static boolean gl_shadersenabled = false;
static hwdshaderoption_t gl_allowshaders = HWD_SHADEROPTION_OFF;
#ifdef GL_SHADERS #ifdef GL_SHADERS
typedef GLuint (APIENTRY *PFNglCreateShader) (GLenum); typedef GLuint (APIENTRY *PFNglCreateShader) (GLenum);
@ -544,6 +537,7 @@ typedef void (APIENTRY *PFNglGetShaderiv) (GLuint, GLenum, GLint*);
typedef void (APIENTRY *PFNglGetShaderInfoLog) (GLuint, GLsizei, GLsizei*, GLchar*); typedef void (APIENTRY *PFNglGetShaderInfoLog) (GLuint, GLsizei, GLsizei*, GLchar*);
typedef void (APIENTRY *PFNglDeleteShader) (GLuint); typedef void (APIENTRY *PFNglDeleteShader) (GLuint);
typedef GLuint (APIENTRY *PFNglCreateProgram) (void); typedef GLuint (APIENTRY *PFNglCreateProgram) (void);
typedef void (APIENTRY *PFNglDeleteProgram) (GLuint);
typedef void (APIENTRY *PFNglAttachShader) (GLuint, GLuint); typedef void (APIENTRY *PFNglAttachShader) (GLuint, GLuint);
typedef void (APIENTRY *PFNglLinkProgram) (GLuint); typedef void (APIENTRY *PFNglLinkProgram) (GLuint);
typedef void (APIENTRY *PFNglGetProgramiv) (GLuint, GLenum, GLint*); typedef void (APIENTRY *PFNglGetProgramiv) (GLuint, GLenum, GLint*);
@ -565,6 +559,7 @@ static PFNglGetShaderiv pglGetShaderiv;
static PFNglGetShaderInfoLog pglGetShaderInfoLog; static PFNglGetShaderInfoLog pglGetShaderInfoLog;
static PFNglDeleteShader pglDeleteShader; static PFNglDeleteShader pglDeleteShader;
static PFNglCreateProgram pglCreateProgram; static PFNglCreateProgram pglCreateProgram;
static PFNglDeleteProgram pglDeleteProgram;
static PFNglAttachShader pglAttachShader; static PFNglAttachShader pglAttachShader;
static PFNglLinkProgram pglLinkProgram; static PFNglLinkProgram pglLinkProgram;
static PFNglGetProgramiv pglGetProgramiv; static PFNglGetProgramiv pglGetProgramiv;
@ -579,12 +574,6 @@ static PFNglUniform2fv pglUniform2fv;
static PFNglUniform3fv pglUniform3fv; static PFNglUniform3fv pglUniform3fv;
static PFNglGetUniformLocation pglGetUniformLocation; static PFNglGetUniformLocation pglGetUniformLocation;
// 18032019
static GLuint gl_currentshaderprogram = 0;
static boolean gl_shaderprogramchanged = true;
static shadersource_t gl_customshaders[HWR_MAXSHADERS];
// 13062019 // 13062019
typedef enum typedef enum
{ {
@ -602,17 +591,37 @@ typedef enum
gluniform_max, gluniform_max,
} gluniform_t; } gluniform_t;
typedef struct gl_shaderprogram_s typedef struct gl_shader_s
{ {
GLuint program; GLuint program;
boolean custom;
GLint uniforms[gluniform_max+1]; GLint uniforms[gluniform_max+1];
} gl_shaderprogram_t; boolean custom;
static gl_shaderprogram_t gl_shaderprograms[HWR_MAXSHADERS]; } gl_shader_t;
static gl_shader_t gl_shaders[HWR_MAXSHADERS];
static gl_shader_t gl_usershaders[HWR_MAXSHADERS];
static shadersource_t gl_customshaders[HWR_MAXSHADERS];
// 09102020
typedef struct gl_shaderstate_s
{
gl_shader_t *current;
GLuint type;
GLuint program;
boolean changed;
} gl_shaderstate_t;
static gl_shaderstate_t gl_shaderstate;
// Shader info // Shader info
static INT32 shader_leveltime = 0; static INT32 shader_leveltime = 0;
// Lactozilla: Shader functions
static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i, const GLchar *vert_shader, const GLchar *frag_shader);
static void Shader_CompileError(const char *message, GLuint program, INT32 shadernum);
static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade);
static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
// ================ // ================
// Vertex shaders // Vertex shaders
// ================ // ================
@ -873,6 +882,7 @@ void SetupGLFunc4(void)
pglGetShaderInfoLog = GetGLFunc("glGetShaderInfoLog"); pglGetShaderInfoLog = GetGLFunc("glGetShaderInfoLog");
pglDeleteShader = GetGLFunc("glDeleteShader"); pglDeleteShader = GetGLFunc("glDeleteShader");
pglCreateProgram = GetGLFunc("glCreateProgram"); pglCreateProgram = GetGLFunc("glCreateProgram");
pglDeleteProgram = GetGLFunc("glDeleteProgram");
pglAttachShader = GetGLFunc("glAttachShader"); pglAttachShader = GetGLFunc("glAttachShader");
pglLinkProgram = GetGLFunc("glLinkProgram"); pglLinkProgram = GetGLFunc("glLinkProgram");
pglGetProgramiv = GetGLFunc("glGetProgramiv"); pglGetProgramiv = GetGLFunc("glGetProgramiv");
@ -896,20 +906,40 @@ void SetupGLFunc4(void)
EXPORT boolean HWRAPI(CompileShaders) (void) EXPORT boolean HWRAPI(CompileShaders) (void)
{ {
#ifdef GL_SHADERS #ifdef GL_SHADERS
GLuint gl_vertShader, gl_fragShader; GLint i;
GLint i, result;
if (!pglUseProgram) return false; if (!pglUseProgram)
return false;
gl_customshaders[0].vertex = NULL; gl_customshaders[SHADER_DEFAULT].vertex = NULL;
gl_customshaders[0].fragment = NULL; gl_customshaders[SHADER_DEFAULT].fragment = NULL;
for (i = 0; gl_shadersources[i].vertex && gl_shadersources[i].fragment; i++) for (i = 0; gl_shadersources[i].vertex && gl_shadersources[i].fragment; i++)
{ {
gl_shaderprogram_t *shader; gl_shader_t *shader, *usershader;
const GLchar *vert_shader = gl_shadersources[i].vertex; const GLchar *vert_shader = gl_shadersources[i].vertex;
const GLchar *frag_shader = gl_shadersources[i].fragment; const GLchar *frag_shader = gl_shadersources[i].fragment;
boolean custom = ((gl_customshaders[i].vertex || gl_customshaders[i].fragment) && (i > 0));
if (i >= HWR_MAXSHADERS)
break;
shader = &gl_shaders[i];
usershader = &gl_usershaders[i];
if (shader->program)
pglDeleteProgram(shader->program);
if (usershader->program)
pglDeleteProgram(usershader->program);
shader->program = 0;
usershader->program = 0;
if (!Shader_CompileProgram(shader, i, vert_shader, frag_shader))
shader->program = 0;
// Compile custom shader
if ((i == SHADER_DEFAULT) || !(gl_customshaders[i].vertex || gl_customshaders[i].fragment))
continue;
// 18032019 // 18032019
if (gl_customshaders[i].vertex) if (gl_customshaders[i].vertex)
@ -917,92 +947,15 @@ EXPORT boolean HWRAPI(CompileShaders) (void)
if (gl_customshaders[i].fragment) if (gl_customshaders[i].fragment)
frag_shader = gl_customshaders[i].fragment; frag_shader = gl_customshaders[i].fragment;
if (i >= HWR_MAXSHADERS) if (!Shader_CompileProgram(usershader, i, vert_shader, frag_shader))
break;
shader = &gl_shaderprograms[i];
shader->program = 0;
shader->custom = custom;
//
// Load and compile vertex shader
//
gl_vertShader = pglCreateShader(GL_VERTEX_SHADER);
if (!gl_vertShader)
{ {
GL_MSG_Error("CompileShaders: Error creating vertex shader %s\n", HWR_GetShaderName(i)); GL_MSG_Warning("CompileShaders: Could not compile custom shader program for %s\n", HWR_GetShaderName(i));
continue; usershader->program = 0;
} }
pglShaderSource(gl_vertShader, 1, &vert_shader, NULL);
pglCompileShader(gl_vertShader);
// check for compile errors
pglGetShaderiv(gl_vertShader, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE)
{
Shader_CompileError("Error compiling vertex shader", gl_vertShader, i);
continue;
}
//
// Load and compile fragment shader
//
gl_fragShader = pglCreateShader(GL_FRAGMENT_SHADER);
if (!gl_fragShader)
{
GL_MSG_Error("CompileShaders: Error creating fragment shader %s\n", HWR_GetShaderName(i));
continue;
}
pglShaderSource(gl_fragShader, 1, &frag_shader, NULL);
pglCompileShader(gl_fragShader);
// check for compile errors
pglGetShaderiv(gl_fragShader, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE)
{
Shader_CompileError("Error compiling fragment shader", gl_fragShader, i);
continue;
}
shader->program = pglCreateProgram();
pglAttachShader(shader->program, gl_vertShader);
pglAttachShader(shader->program, gl_fragShader);
pglLinkProgram(shader->program);
// check link status
pglGetProgramiv(shader->program, GL_LINK_STATUS, &result);
// delete the shader objects
pglDeleteShader(gl_vertShader);
pglDeleteShader(gl_fragShader);
// couldn't link?
if (result != GL_TRUE)
{
shader->program = 0;
shader->custom = false;
GL_MSG_Error("CompileShaders: Error linking shader program %s\n", HWR_GetShaderName(i));
continue;
}
// 13062019
#define GETUNI(uniform) pglGetUniformLocation(shader->program, uniform);
// lighting
shader->uniforms[gluniform_poly_color] = GETUNI("poly_color");
shader->uniforms[gluniform_tint_color] = GETUNI("tint_color");
shader->uniforms[gluniform_fade_color] = GETUNI("fade_color");
shader->uniforms[gluniform_lighting] = GETUNI("lighting");
shader->uniforms[gluniform_fade_start] = GETUNI("fade_start");
shader->uniforms[gluniform_fade_end] = GETUNI("fade_end");
// misc. (custom shaders)
shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
#undef GETUNI
} }
SetShader(SHADER_DEFAULT);
return true; return true;
#else #else
return false; return false;
@ -1070,26 +1023,45 @@ EXPORT void HWRAPI(LoadCustomShader) (int number, char *code, size_t size, boole
#endif #endif
} }
EXPORT void HWRAPI(SetShader) (int shader) EXPORT void HWRAPI(SetShader) (int type)
{ {
#ifdef GL_SHADERS #ifdef GL_SHADERS
if (gl_allowshaders) if (gl_allowshaders != HWD_SHADEROPTION_OFF)
{ {
gl_shader_t *shader = gl_shaderstate.current;
// If using model lighting, set the appropriate shader. // If using model lighting, set the appropriate shader.
// However don't override a custom shader. // However don't override a custom shader.
if (shader == SHADER_MODEL && model_lighting if (type == SHADER_MODEL && model_lighting
&& !(gl_shaderprograms[SHADER_MODEL].custom && !gl_shaderprograms[SHADER_MODEL_LIGHTING].custom)) && !(gl_shaders[SHADER_MODEL].custom && !gl_shaders[SHADER_MODEL_LIGHTING].custom))
shader = SHADER_MODEL_LIGHTING; type = SHADER_MODEL_LIGHTING;
if ((GLuint)shader != gl_currentshaderprogram)
if ((shader == NULL) || (GLuint)type != gl_shaderstate.type)
{ {
gl_currentshaderprogram = shader; gl_shader_t *baseshader = &gl_shaders[type];
gl_shaderprogramchanged = true; gl_shader_t *usershader = &gl_usershaders[type];
if (usershader->program)
shader = (gl_allowshaders == HWD_SHADEROPTION_NOCUSTOM) ? baseshader : usershader;
else
shader = baseshader;
gl_shaderstate.current = shader;
gl_shaderstate.type = type;
gl_shaderstate.changed = true;
} }
gl_shadersenabled = true;
if (gl_shaderstate.program != shader->program)
{
gl_shaderstate.program = shader->program;
gl_shaderstate.changed = true;
}
gl_shadersenabled = (shader->program != 0);
return; return;
} }
#else #else
(void)shader; (void)type;
#endif #endif
gl_shadersenabled = false; gl_shadersenabled = false;
} }
@ -1097,11 +1069,15 @@ EXPORT void HWRAPI(SetShader) (int shader)
EXPORT void HWRAPI(UnSetShader) (void) EXPORT void HWRAPI(UnSetShader) (void)
{ {
#ifdef GL_SHADERS #ifdef GL_SHADERS
gl_shadersenabled = false; gl_shaderstate.current = NULL;
gl_currentshaderprogram = 0; gl_shaderstate.type = 0;
if (!pglUseProgram) return; gl_shaderstate.program = 0;
pglUseProgram(0);
if (pglUseProgram)
pglUseProgram(0);
#endif #endif
gl_shadersenabled = false;
} }
EXPORT void HWRAPI(CleanShaders) (void) EXPORT void HWRAPI(CleanShaders) (void)
@ -1901,42 +1877,24 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
} }
} }
static void *Shader_Load(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade)
{
#ifdef GL_SHADERS
if (gl_shadersenabled && pglUseProgram)
{
gl_shaderprogram_t *shader = &gl_shaderprograms[gl_currentshaderprogram];
if (shader->program)
{
if (gl_shaderprogramchanged)
{
pglUseProgram(gl_shaderprograms[gl_currentshaderprogram].program);
gl_shaderprogramchanged = false;
}
Shader_SetUniforms(Surface, poly, tint, fade);
return shader;
}
else
pglUseProgram(0);
}
#else
(void)Surface;
(void)poly;
(void)tint;
(void)fade;
#endif
return NULL;
}
static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade) static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade)
{ {
#ifdef GL_SHADERS #ifdef GL_SHADERS
if (gl_shadersenabled) gl_shader_t *shader = gl_shaderstate.current;
if (gl_shadersenabled && (shader != NULL) && pglUseProgram)
{ {
gl_shaderprogram_t *shader = &gl_shaderprograms[gl_currentshaderprogram];
if (!shader->program) if (!shader->program)
{
pglUseProgram(0);
return; return;
}
if (gl_shaderstate.changed)
{
pglUseProgram(shader->program);
gl_shaderstate.changed = false;
}
// Color uniforms can be left NULL and will be set to white (1.0f, 1.0f, 1.0f, 1.0f) // Color uniforms can be left NULL and will be set to white (1.0f, 1.0f, 1.0f, 1.0f)
if (poly == NULL) if (poly == NULL)
@ -1989,6 +1947,97 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
#endif #endif
} }
static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i, const GLchar *vert_shader, const GLchar *frag_shader)
{
GLuint gl_vertShader, gl_fragShader;
GLint result;
//
// Load and compile vertex shader
//
gl_vertShader = pglCreateShader(GL_VERTEX_SHADER);
if (!gl_vertShader)
{
GL_MSG_Error("Shader_CompileProgram: Error creating vertex shader %s\n", HWR_GetShaderName(i));
return false;
}
pglShaderSource(gl_vertShader, 1, &vert_shader, NULL);
pglCompileShader(gl_vertShader);
// check for compile errors
pglGetShaderiv(gl_vertShader, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE)
{
Shader_CompileError("Error compiling vertex shader", gl_vertShader, i);
pglDeleteShader(gl_vertShader);
return false;
}
//
// Load and compile fragment shader
//
gl_fragShader = pglCreateShader(GL_FRAGMENT_SHADER);
if (!gl_fragShader)
{
GL_MSG_Error("Shader_CompileProgram: Error creating fragment shader %s\n", HWR_GetShaderName(i));
pglDeleteShader(gl_vertShader);
pglDeleteShader(gl_fragShader);
return false;
}
pglShaderSource(gl_fragShader, 1, &frag_shader, NULL);
pglCompileShader(gl_fragShader);
// check for compile errors
pglGetShaderiv(gl_fragShader, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE)
{
Shader_CompileError("Error compiling fragment shader", gl_fragShader, i);
pglDeleteShader(gl_vertShader);
pglDeleteShader(gl_fragShader);
return false;
}
shader->program = pglCreateProgram();
pglAttachShader(shader->program, gl_vertShader);
pglAttachShader(shader->program, gl_fragShader);
pglLinkProgram(shader->program);
// check link status
pglGetProgramiv(shader->program, GL_LINK_STATUS, &result);
// delete the shader objects
pglDeleteShader(gl_vertShader);
pglDeleteShader(gl_fragShader);
// couldn't link?
if (result != GL_TRUE)
{
GL_MSG_Error("Shader_CompileProgram: Error linking shader program %s\n", HWR_GetShaderName(i));
pglDeleteProgram(shader->program);
return false;
}
// 13062019
#define GETUNI(uniform) pglGetUniformLocation(shader->program, uniform);
// lighting
shader->uniforms[gluniform_poly_color] = GETUNI("poly_color");
shader->uniforms[gluniform_tint_color] = GETUNI("tint_color");
shader->uniforms[gluniform_fade_color] = GETUNI("fade_color");
shader->uniforms[gluniform_lighting] = GETUNI("lighting");
shader->uniforms[gluniform_fade_start] = GETUNI("fade_start");
shader->uniforms[gluniform_fade_end] = GETUNI("fade_end");
// misc. (custom shaders)
shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
#undef GETUNI
return true;
}
static void Shader_CompileError(const char *message, GLuint program, INT32 shadernum) static void Shader_CompileError(const char *message, GLuint program, INT32 shadernum)
{ {
GLchar *infoLog = NULL; GLchar *infoLog = NULL;
@ -2002,7 +2051,7 @@ static void Shader_CompileError(const char *message, GLuint program, INT32 shade
pglGetShaderInfoLog(program, logLength, NULL, infoLog); pglGetShaderInfoLog(program, logLength, NULL, infoLog);
} }
GL_MSG_Error("CompileShaders: %s (%s)\n%s", message, HWR_GetShaderName(shadernum), (infoLog ? infoLog : "")); GL_MSG_Error("Shader_CompileProgram: %s (%s)\n%s", message, HWR_GetShaderName(shadernum), (infoLog ? infoLog : ""));
if (infoLog) if (infoLog)
free(infoLog); free(infoLog);
@ -2112,7 +2161,7 @@ static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD
pglColor4ubv(c); pglColor4ubv(c);
} }
Shader_Load(pSurf, &poly, &tint, &fade); Shader_SetUniforms(pSurf, &poly, &tint, &fade);
} }
// -----------------+ // -----------------+
@ -2158,7 +2207,7 @@ EXPORT void HWRAPI(RenderSkyDome) (gl_sky_t *sky)
{ {
int i, j; int i, j;
Shader_Load(NULL, NULL, NULL, NULL); Shader_SetUniforms(NULL, NULL, NULL, NULL);
// Build the sky dome! Yes! // Build the sky dome! Yes!
if (sky->rebuild) if (sky->rebuild)
@ -2250,15 +2299,7 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
break; break;
case HWD_SET_SHADERS: case HWD_SET_SHADERS:
switch (Value) gl_allowshaders = (hwdshaderoption_t)Value;
{
case 1:
gl_allowshaders = true;
break;
default:
gl_allowshaders = false;
break;
}
break; break;
case HWD_SET_TEXTUREFILTERMODE: case HWD_SET_TEXTUREFILTERMODE:
@ -2607,7 +2648,7 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
fade.blue = byte2float[Surface->FadeColor.s.blue]; fade.blue = byte2float[Surface->FadeColor.s.blue];
fade.alpha = byte2float[Surface->FadeColor.s.alpha]; fade.alpha = byte2float[Surface->FadeColor.s.alpha];
Shader_Load(Surface, &poly, &tint, &fade); Shader_SetUniforms(Surface, &poly, &tint, &fade);
pglEnable(GL_CULL_FACE); pglEnable(GL_CULL_FACE);
pglEnable(GL_NORMALIZE); pglEnable(GL_NORMALIZE);

View File

@ -189,7 +189,7 @@ boolean OglSdlSurface(INT32 w, INT32 h)
SetupGLFunc4(); SetupGLFunc4();
granisotropicmode_cons_t[1].value = maximumAnisotropy; glanisotropicmode_cons_t[1].value = maximumAnisotropy;
SDL_GL_SetSwapInterval(cv_vidwait.value ? 1 : 0); SDL_GL_SetSwapInterval(cv_vidwait.value ? 1 : 0);

View File

@ -2125,6 +2125,8 @@ int W_VerifyNMUSlumps(const char *filename)
{"MINUS5", 6}, {"MINUS5", 6},
{"MUSICDEF", 8}, // Song definitions (thanks kart) {"MUSICDEF", 8}, // Song definitions (thanks kart)
{"SHADERS", 7}, // OpenGL shader definitions
{"SH_", 3}, // GLSL shader
{NULL, 0}, {NULL, 0},
}; };