mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-22 02:42:20 +00:00
Let the server or an admin toggle clients' custom shaders
This commit is contained in:
parent
63d4c1dffc
commit
0811f60b2a
7 changed files with 250 additions and 182 deletions
|
@ -295,6 +295,16 @@ enum hwdsetspecialstate
|
|||
|
||||
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
|
||||
// Generally set at the start of the frame.
|
||||
enum hwdshaderinfo
|
||||
|
|
|
@ -70,7 +70,7 @@ EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
|
|||
// jimita
|
||||
EXPORT boolean HWRAPI(CompileShaders) (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(SetShaderInfo) (hwdshaderinfo_t info, INT32 value);
|
||||
|
|
|
@ -5555,6 +5555,20 @@ static void HWR_SetTransformAiming(FTransform *trans, player_t *player, boolean
|
|||
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
|
||||
// ==========================================================================
|
||||
|
@ -5673,8 +5687,7 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
|
|||
HWD.pfnSetTransform(&atransform);
|
||||
|
||||
// Reset the shader state.
|
||||
HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_glshaders.value);
|
||||
HWD.pfnSetShader(SHADER_DEFAULT);
|
||||
HWR_SetShaderState();
|
||||
|
||||
validcount++;
|
||||
|
||||
|
@ -5886,8 +5899,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
|||
HWD.pfnSetTransform(&atransform);
|
||||
|
||||
// Reset the shader state.
|
||||
HWD.pfnSetSpecialState(HWD_SET_SHADERS, cv_glshaders.value);
|
||||
HWD.pfnSetShader(SHADER_DEFAULT);
|
||||
HWR_SetShaderState();
|
||||
|
||||
rs_numbspcalls = 0;
|
||||
rs_numpolyobjects = 0;
|
||||
|
@ -5982,9 +5994,10 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
|||
// 3D ENGINE COMMANDS
|
||||
// ==========================================================================
|
||||
|
||||
static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}};
|
||||
static CV_PossibleValue_t grfakecontrast_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}};
|
||||
static CV_PossibleValue_t grshearing_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Third-person"}, {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 glmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {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_glanisotropic_OnChange(void);
|
||||
|
@ -5995,9 +6008,10 @@ static CV_PossibleValue_t glfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSA
|
|||
{HWD_SET_TEXTUREFILTER_MIXED2, "Nearest_Linear"},
|
||||
{HWD_SET_TEXTUREFILTER_MIXED3, "Nearest_Mipmap"},
|
||||
{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 = {"gr_shaders", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glshaders = {"gr_shaders", "On", CV_SAVE, glshaders_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glallowshaders = {"gr_allowshaders", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_fovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
#ifdef ALAM_LIGHTING
|
||||
|
@ -6008,18 +6022,18 @@ consvar_t cv_glcoronasize = {"gr_coronasize", "1", CV_SAVE|CV_FLOAT, 0, NULL, 0,
|
|||
#endif
|
||||
|
||||
consvar_t cv_glmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, glmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glmodellighting = {"gr_modellighting", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_glshearing = {"gr_shearing", "Off", CV_SAVE, grshearing_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glshearing = {"gr_shearing", "Off", CV_SAVE, glshearing_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glfakecontrast = {"gr_fakecontrast", "Smooth", CV_SAVE, grfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glfakecontrast = {"gr_fakecontrast", "Smooth", CV_SAVE, glfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glslopecontrast = {"gr_slopecontrast", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_glfiltermode = {"gr_filtermode", "Nearest", CV_SAVE|CV_CALL, glfiltermode_cons_t,
|
||||
CV_glfiltermode_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
consvar_t cv_glanisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t,
|
||||
consvar_t cv_glanisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, glanisotropicmode_cons_t,
|
||||
CV_glanisotropic_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
consvar_t cv_glsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
@ -6059,6 +6073,7 @@ void HWR_AddCommands(void)
|
|||
CV_RegisterVar(&cv_glfakecontrast);
|
||||
CV_RegisterVar(&cv_glshearing);
|
||||
CV_RegisterVar(&cv_glshaders);
|
||||
CV_RegisterVar(&cv_glallowshaders);
|
||||
|
||||
CV_RegisterVar(&cv_glfiltermode);
|
||||
CV_RegisterVar(&cv_glsolvetjoin);
|
||||
|
|
|
@ -78,7 +78,7 @@ const char *HWR_GetShaderName(INT32 shader);
|
|||
|
||||
extern customshaderxlat_t shaderxlat[];
|
||||
|
||||
extern CV_PossibleValue_t granisotropicmode_cons_t[];
|
||||
extern CV_PossibleValue_t glanisotropicmode_cons_t[];
|
||||
|
||||
#ifdef ALAM_LIGHTING
|
||||
extern consvar_t cv_gldynamiclighting;
|
||||
|
@ -87,7 +87,7 @@ extern consvar_t cv_glcoronas;
|
|||
extern consvar_t cv_glcoronasize;
|
||||
#endif
|
||||
|
||||
extern consvar_t cv_glshaders;
|
||||
extern consvar_t cv_glshaders, cv_glallowshaders;
|
||||
extern consvar_t cv_glmodels;
|
||||
extern consvar_t cv_glmodelinterpolation;
|
||||
extern consvar_t cv_glmodellighting;
|
||||
|
|
|
@ -91,13 +91,6 @@ static GLuint startScreenWipe = 0;
|
|||
static GLuint endScreenWipe = 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)
|
||||
static const GLfloat byte2float[256] = {
|
||||
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;
|
||||
}
|
||||
|
||||
static boolean gl_allowshaders = false;
|
||||
static boolean gl_shadersenabled = false;
|
||||
static hwdshaderoption_t gl_allowshaders = HWD_SHADEROPTION_OFF;
|
||||
|
||||
#ifdef GL_SHADERS
|
||||
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 *PFNglDeleteShader) (GLuint);
|
||||
typedef GLuint (APIENTRY *PFNglCreateProgram) (void);
|
||||
typedef void (APIENTRY *PFNglDeleteProgram) (GLuint);
|
||||
typedef void (APIENTRY *PFNglAttachShader) (GLuint, GLuint);
|
||||
typedef void (APIENTRY *PFNglLinkProgram) (GLuint);
|
||||
typedef void (APIENTRY *PFNglGetProgramiv) (GLuint, GLenum, GLint*);
|
||||
|
@ -565,6 +559,7 @@ static PFNglGetShaderiv pglGetShaderiv;
|
|||
static PFNglGetShaderInfoLog pglGetShaderInfoLog;
|
||||
static PFNglDeleteShader pglDeleteShader;
|
||||
static PFNglCreateProgram pglCreateProgram;
|
||||
static PFNglDeleteProgram pglDeleteProgram;
|
||||
static PFNglAttachShader pglAttachShader;
|
||||
static PFNglLinkProgram pglLinkProgram;
|
||||
static PFNglGetProgramiv pglGetProgramiv;
|
||||
|
@ -579,12 +574,6 @@ static PFNglUniform2fv pglUniform2fv;
|
|||
static PFNglUniform3fv pglUniform3fv;
|
||||
static PFNglGetUniformLocation pglGetUniformLocation;
|
||||
|
||||
// 18032019
|
||||
static GLuint gl_currentshaderprogram = 0;
|
||||
static boolean gl_shaderprogramchanged = true;
|
||||
|
||||
static shadersource_t gl_customshaders[HWR_MAXSHADERS];
|
||||
|
||||
// 13062019
|
||||
typedef enum
|
||||
{
|
||||
|
@ -602,17 +591,37 @@ typedef enum
|
|||
gluniform_max,
|
||||
} gluniform_t;
|
||||
|
||||
typedef struct gl_shaderprogram_s
|
||||
typedef struct gl_shader_s
|
||||
{
|
||||
GLuint program;
|
||||
boolean custom;
|
||||
GLint uniforms[gluniform_max+1];
|
||||
} gl_shaderprogram_t;
|
||||
static gl_shaderprogram_t gl_shaderprograms[HWR_MAXSHADERS];
|
||||
boolean custom;
|
||||
} 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
|
||||
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
|
||||
// ================
|
||||
|
@ -873,6 +882,7 @@ void SetupGLFunc4(void)
|
|||
pglGetShaderInfoLog = GetGLFunc("glGetShaderInfoLog");
|
||||
pglDeleteShader = GetGLFunc("glDeleteShader");
|
||||
pglCreateProgram = GetGLFunc("glCreateProgram");
|
||||
pglDeleteProgram = GetGLFunc("glDeleteProgram");
|
||||
pglAttachShader = GetGLFunc("glAttachShader");
|
||||
pglLinkProgram = GetGLFunc("glLinkProgram");
|
||||
pglGetProgramiv = GetGLFunc("glGetProgramiv");
|
||||
|
@ -896,20 +906,40 @@ void SetupGLFunc4(void)
|
|||
EXPORT boolean HWRAPI(CompileShaders) (void)
|
||||
{
|
||||
#ifdef GL_SHADERS
|
||||
GLuint gl_vertShader, gl_fragShader;
|
||||
GLint i, result;
|
||||
GLint i;
|
||||
|
||||
if (!pglUseProgram) return false;
|
||||
if (!pglUseProgram)
|
||||
return false;
|
||||
|
||||
gl_customshaders[0].vertex = NULL;
|
||||
gl_customshaders[0].fragment = NULL;
|
||||
gl_customshaders[SHADER_DEFAULT].vertex = NULL;
|
||||
gl_customshaders[SHADER_DEFAULT].fragment = NULL;
|
||||
|
||||
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 *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
|
||||
if (gl_customshaders[i].vertex)
|
||||
|
@ -917,92 +947,15 @@ EXPORT boolean HWRAPI(CompileShaders) (void)
|
|||
if (gl_customshaders[i].fragment)
|
||||
frag_shader = gl_customshaders[i].fragment;
|
||||
|
||||
if (i >= HWR_MAXSHADERS)
|
||||
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)
|
||||
if (!Shader_CompileProgram(usershader, i, vert_shader, frag_shader))
|
||||
{
|
||||
GL_MSG_Error("CompileShaders: Error creating vertex shader %s\n", HWR_GetShaderName(i));
|
||||
continue;
|
||||
GL_MSG_Warning("CompileShaders: Could not compile custom shader program for %s\n", HWR_GetShaderName(i));
|
||||
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;
|
||||
#else
|
||||
return false;
|
||||
|
@ -1070,26 +1023,45 @@ EXPORT void HWRAPI(LoadCustomShader) (int number, char *code, size_t size, boole
|
|||
#endif
|
||||
}
|
||||
|
||||
EXPORT void HWRAPI(SetShader) (int shader)
|
||||
EXPORT void HWRAPI(SetShader) (int type)
|
||||
{
|
||||
#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.
|
||||
// However don't override a custom shader.
|
||||
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)
|
||||
if (type == SHADER_MODEL && model_lighting
|
||||
&& !(gl_shaders[SHADER_MODEL].custom && !gl_shaders[SHADER_MODEL_LIGHTING].custom))
|
||||
type = SHADER_MODEL_LIGHTING;
|
||||
|
||||
if ((shader == NULL) || (GLuint)type != gl_shaderstate.type)
|
||||
{
|
||||
gl_currentshaderprogram = shader;
|
||||
gl_shaderprogramchanged = true;
|
||||
gl_shader_t *baseshader = &gl_shaders[type];
|
||||
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;
|
||||
}
|
||||
#else
|
||||
(void)shader;
|
||||
(void)type;
|
||||
#endif
|
||||
gl_shadersenabled = false;
|
||||
}
|
||||
|
@ -1097,11 +1069,15 @@ EXPORT void HWRAPI(SetShader) (int shader)
|
|||
EXPORT void HWRAPI(UnSetShader) (void)
|
||||
{
|
||||
#ifdef GL_SHADERS
|
||||
gl_shadersenabled = false;
|
||||
gl_currentshaderprogram = 0;
|
||||
if (!pglUseProgram) return;
|
||||
pglUseProgram(0);
|
||||
gl_shaderstate.current = NULL;
|
||||
gl_shaderstate.type = 0;
|
||||
gl_shaderstate.program = 0;
|
||||
|
||||
if (pglUseProgram)
|
||||
pglUseProgram(0);
|
||||
#endif
|
||||
|
||||
gl_shadersenabled = false;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
#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)
|
||||
{
|
||||
pglUseProgram(0);
|
||||
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)
|
||||
if (poly == NULL)
|
||||
|
@ -1989,6 +1947,97 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
|
|||
#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)
|
||||
{
|
||||
GLchar *infoLog = NULL;
|
||||
|
@ -2002,7 +2051,7 @@ static void Shader_CompileError(const char *message, GLuint program, INT32 shade
|
|||
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)
|
||||
free(infoLog);
|
||||
|
@ -2112,7 +2161,7 @@ static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD
|
|||
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;
|
||||
|
||||
Shader_Load(NULL, NULL, NULL, NULL);
|
||||
Shader_SetUniforms(NULL, NULL, NULL, NULL);
|
||||
|
||||
// Build the sky dome! Yes!
|
||||
if (sky->rebuild)
|
||||
|
@ -2250,15 +2299,7 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
|
|||
break;
|
||||
|
||||
case HWD_SET_SHADERS:
|
||||
switch (Value)
|
||||
{
|
||||
case 1:
|
||||
gl_allowshaders = true;
|
||||
break;
|
||||
default:
|
||||
gl_allowshaders = false;
|
||||
break;
|
||||
}
|
||||
gl_allowshaders = (hwdshaderoption_t)Value;
|
||||
break;
|
||||
|
||||
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.alpha = byte2float[Surface->FadeColor.s.alpha];
|
||||
|
||||
Shader_Load(Surface, &poly, &tint, &fade);
|
||||
Shader_SetUniforms(Surface, &poly, &tint, &fade);
|
||||
|
||||
pglEnable(GL_CULL_FACE);
|
||||
pglEnable(GL_NORMALIZE);
|
||||
|
|
|
@ -177,7 +177,7 @@ boolean OglSdlSurface(INT32 w, INT32 h)
|
|||
|
||||
SetupGLFunc4();
|
||||
|
||||
granisotropicmode_cons_t[1].value = maximumAnisotropy;
|
||||
glanisotropicmode_cons_t[1].value = maximumAnisotropy;
|
||||
|
||||
SDL_GL_SetSwapInterval(cv_vidwait.value ? 1 : 0);
|
||||
|
||||
|
|
|
@ -2082,6 +2082,8 @@ int W_VerifyNMUSlumps(const char *filename)
|
|||
{"YB_", 3}, // Intermission graphics, goes with the above
|
||||
{"M_", 2}, // As does menu stuff
|
||||
{"MUSICDEF", 8}, // Song definitions (thanks kart)
|
||||
{"SHADERS", 7}, // OpenGL shader definitions
|
||||
{"SH_", 3}, // GLSL shader
|
||||
|
||||
{NULL, 0},
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue