custom shader support

This commit is contained in:
Jaime Passos 2019-03-18 23:03:29 -03:00
parent 1de35b9076
commit 75919422c6
8 changed files with 158 additions and 55 deletions

View File

@ -76,6 +76,8 @@ EXPORT void HWRAPI(KillShaders) (void);
EXPORT void HWRAPI(SetShader) (int shader);
EXPORT void HWRAPI(UnSetShader) (void);
EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment);
// ==========================================================================
// HWR DRIVER OBJECT, FOR CLIENT PROGRAM
// ==========================================================================
@ -122,6 +124,8 @@ struct hwdriver_s
KillShaders pfnKillShaders;
SetShader pfnSetShader;
UnSetShader pfnUnSetShader;
LoadCustomShader pfnLoadCustomShader;
};
extern struct hwdriver_s hwdriver;

View File

@ -353,12 +353,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
if (nrPlaneVerts < 3) //not even a triangle ?
return;
if (nrPlaneVerts > UINT16_MAX) // FIXME: exceeds plVerts size
{
CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, UINT16_MAX);
return;
}
// Allocate plane-vertex buffer if we need to
if (!planeVerts || nrPlaneVerts > numAllocedPlaneVerts)
{
@ -505,7 +499,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is
HWD.pfnSetShader(1); // jimita: floor shader
if (PolyFlags & PF_Ripple)
HWD.pfnSetShader(4); // jimita: water shader
HWD.pfnSetShader(5); // jimita: water shader
HWD.pfnDrawPolygon(&Surf, planeVerts, nrPlaneVerts, PolyFlags);
}
@ -5206,7 +5200,7 @@ static void HWR_DrawSkyBackground(void)
v[0].tow = v[1].tow -= ((float) angle / angleturn);
}
HWD.pfnSetShader(5); // jimita: sky shader
HWD.pfnSetShader(6); // jimita: sky shader
HWD.pfnDrawPolygon(NULL, v, 4, 0);
HWD.pfnSetShader(0); // jimita
}
@ -5942,4 +5936,10 @@ void HWR_DrawScreenFinalTexture(int width, int height)
HWD.pfnDrawScreenFinalTexture(width, height);
}
// jimita 18032019
void HWR_LoadShader(int number, char *shader, size_t size, boolean fragment)
{
HWD.pfnLoadCustomShader(number, shader, size, fragment);
}
#endif // HWRENDER

View File

@ -65,6 +65,7 @@ void HWR_DrawIntermissionBG(void);
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
void HWR_MakeScreenFinalTexture(void);
void HWR_DrawScreenFinalTexture(int width, int height);
void HWR_LoadShader(int number, char *shader, size_t size, boolean fragment);
// This stuff is put here so MD2's can use them
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, UINT32 mixcolor, UINT32 fadecolor);

View File

@ -860,7 +860,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, con
// -----------------+
// HWR_DrawMD2 : Draw MD2
// : (monsters, bonuses, weapons, lights, ...)
// :
// Returns :
// -----------------+
@ -1096,6 +1096,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
p.mirror = atransform.mirror; // from Kart
#endif
HWD.pfnSetShader(4); // jimita: model shader
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, &Surf);
}
}

View File

@ -514,10 +514,15 @@ static boolean gl_shadersenabled = false;
static GLuint gl_currentshaderprogram = 0;
static GLuint gl_shaderprograms[MAXSHADERPROGRAMS];
// 18032019
static char *gl_customvertexshaders[MAXSHADERS];
static char *gl_customfragmentshaders[MAXSHADERS];
typedef GLuint (APIENTRY *PFNglCreateShader) (GLenum);
typedef void (APIENTRY *PFNglShaderSource) (GLuint, GLsizei, const GLchar**, GLint*);
typedef void (APIENTRY *PFNglCompileShader) (GLuint);
typedef void (APIENTRY *PFNglGetShaderiv) (GLuint, GLenum, GLint*);
typedef void (APIENTRY *PFNglGetShaderInfoLog) (GLuint, GLsizei, GLsizei*, GLchar*);
typedef void (APIENTRY *PFNglDeleteShader) (GLuint);
typedef GLuint (APIENTRY *PFNglCreateProgram) (void);
typedef void (APIENTRY *PFNglAttachShader) (GLuint, GLuint);
@ -538,6 +543,7 @@ static PFNglCreateShader pglCreateShader;
static PFNglShaderSource pglShaderSource;
static PFNglCompileShader pglCompileShader;
static PFNglGetShaderiv pglGetShaderiv;
static PFNglGetShaderInfoLog pglGetShaderInfoLog;
static PFNglDeleteShader pglDeleteShader;
static PFNglCreateProgram pglCreateProgram;
static PFNglAttachShader pglAttachShader;
@ -603,7 +609,7 @@ static PFNglGetUniformLocation pglGetUniformLocation;
"}\0"
static const char *fragment_shaders[] = {
// Default shader
// Default fragment shader
"uniform sampler2D tex;\n"
"uniform vec4 mix_color;\n"
"void main(void) {\n"
@ -612,48 +618,27 @@ static const char *fragment_shaders[] = {
"gl_FragColor = mixed_color;\n"
"}\0",
// Floor shader
// Floor fragment shader
SHARED_FRAGMENT_SHADER,
// Wall shader
// Wall fragment shader
SHARED_FRAGMENT_SHADER,
// Sprite shader
// Sprite fragment shader
SHARED_FRAGMENT_SHADER,
// Water shader
"uniform sampler2D tex;\n"
"uniform vec4 mix_color;\n"
"uniform vec4 fade_color;\n"
"uniform float lighting;\n"
"uniform int fog_mode;\n"
"uniform int fog_density;\n"
"uniform float leveltime;\n"
// Model fragment shader
SHARED_FRAGMENT_SHADER,
GLSL_SHARED_FOG_FUNCTION
// Water fragment shader
SHARED_FRAGMENT_SHADER,
"void main(void) {\n"
"float texU = gl_TexCoord[0].s;\n"
"float texV = gl_TexCoord[0].t;\n"
"float wtofs = leveltime/16;\n"
"float pi = 3.14159265358979323846;\n"
"texU += cos(pi * 2.0 * (texV/4 + wtofs * 0.125)) * 0.3;\n"
"texV += sin(pi * 2.0 * (texV/6 + wtofs * 0.125)) * 0.4;\n"
"vec4 color = texture2D(tex, vec2(texU, texV));\n"
GLSL_SHARED_FOG_MIX
"gl_FragColor = final_color;\n"
"}\0",
// Sky shader
// Sky fragment shader
"uniform sampler2D tex;\n"
"uniform vec2 resolution;\n"
"void main(void) {\n"
"float texU = gl_TexCoord[0].s;\n"
"float texV = gl_TexCoord[0].t;\n"
//"float scale = abs(gl_FragCoord.x - (resolution.x/2.0));\n"
//"scale /= resolution.x;\n"
"gl_FragColor = texture2D(tex, vec2(texU, texV));\n"
"}\0",
};
@ -663,7 +648,7 @@ static const char *fragment_shaders[] = {
//
// Macro to reduce boilerplate code
#define SHARED_VERTEX_SHADER \
#define DEFAULT_VERTEX_SHADER \
"void main()\n" \
"{\n" \
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
@ -673,23 +658,26 @@ static const char *fragment_shaders[] = {
"}\0"
static const char *vertex_shaders[] = {
// Default shader
SHARED_VERTEX_SHADER,
// Default vertex shader
DEFAULT_VERTEX_SHADER,
// Floor shader
SHARED_VERTEX_SHADER,
// Floor vertex shader
DEFAULT_VERTEX_SHADER,
// Wall shader
SHARED_VERTEX_SHADER,
// Wall vertex shader
DEFAULT_VERTEX_SHADER,
// Sprite shader
SHARED_VERTEX_SHADER,
// Sprite vertex shader
DEFAULT_VERTEX_SHADER,
// Water shader
SHARED_VERTEX_SHADER,
// Model vertex shader
DEFAULT_VERTEX_SHADER,
// Sky shader
SHARED_VERTEX_SHADER,
// Water vertex shader
DEFAULT_VERTEX_SHADER,
// Sky vertex shader
DEFAULT_VERTEX_SHADER,
};
#endif // USE_SHADERS
@ -710,6 +698,7 @@ void SetupGLFunc4(void)
pglShaderSource = GetGLFunc("glShaderSource");
pglCompileShader = GetGLFunc("glCompileShader");
pglGetShaderiv = GetGLFunc("glGetShaderiv");
pglGetShaderInfoLog = GetGLFunc("glGetShaderInfoLog");
pglDeleteShader = GetGLFunc("glDeleteShader");
pglCreateProgram = GetGLFunc("glCreateProgram");
pglAttachShader = GetGLFunc("glAttachShader");
@ -742,6 +731,14 @@ EXPORT void HWRAPI(LoadShaders) (void)
{
const GLchar* vert_shader = vertex_shaders[i];
const GLchar* frag_shader = fragment_shaders[i];
// 18032019
if (gl_customvertexshaders[i])
vert_shader = gl_customvertexshaders[i];
if (gl_customfragmentshaders[i])
frag_shader = gl_customfragmentshaders[i];
if (i >= MAXSHADERS || i >= MAXSHADERPROGRAMS)
break;
@ -758,7 +755,17 @@ EXPORT void HWRAPI(LoadShaders) (void)
// check for compile errors
pglGetShaderiv(gl_vertShader, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE)
I_Error("Hardware driver: Error compiling vertex shader %d", i);
{
GLchar* infoLog;
GLint logLength;
pglGetShaderiv(gl_vertShader, GL_INFO_LOG_LENGTH, &logLength);
infoLog = malloc(logLength);
pglGetShaderInfoLog(gl_vertShader, logLength, NULL, infoLog);
I_Error("Hardware driver: Error compiling vertex shader %d\n%s", i, infoLog);
}
//
// Load and compile fragment shader
@ -773,7 +780,17 @@ EXPORT void HWRAPI(LoadShaders) (void)
// check for compile errors
pglGetShaderiv(gl_fragShader, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE)
I_Error("Hardware driver: Error compiling fragment shader %d", i);
{
GLchar* infoLog;
GLint logLength;
pglGetShaderiv(gl_fragShader, GL_INFO_LOG_LENGTH, &logLength);
infoLog = malloc(logLength);
pglGetShaderInfoLog(gl_fragShader, logLength, NULL, infoLog);
I_Error("Hardware driver: Error compiling fragment shader %d\n%s", i, infoLog);
}
gl_shaderprograms[i] = pglCreateProgram();
pglAttachShader(gl_shaderprograms[i], gl_vertShader);
@ -788,6 +805,33 @@ EXPORT void HWRAPI(LoadShaders) (void)
#endif
}
EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment)
{
#ifdef USE_SHADERS
(void)shader;
(void)size;
(void)fragment;
if (number < 1 || number > MAXSHADERS)
I_Error("LoadCustomShader(): cannot load shader %d (max %d)", number, MAXSHADERS);
if (fragment)
{
gl_customfragmentshaders[number] = malloc(size+1);
strncpy(gl_customfragmentshaders[number], shader, size);
gl_customfragmentshaders[number][size] = 0;
}
else
{
gl_customvertexshaders[number] = malloc(size+1);
strncpy(gl_customvertexshaders[number], shader, size);
gl_customvertexshaders[number][size] = 0;
}
KillShaders();
LoadShaders();
#endif
}
EXPORT void HWRAPI(SetShader) (int shader)
{
#ifdef USE_SHADERS

View File

@ -108,6 +108,8 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(SetShader);
GETFUNC(UnSetShader);
GETFUNC(LoadCustomShader);
#else //HWRENDER
if (0 == strcmp("FinishUpdate", funcName))
return funcPointer; //&FinishUpdate;

View File

@ -1505,6 +1505,8 @@ void I_StartupGraphics(void)
HWD.pfnSetShader = hwSym("SetShader",NULL);
HWD.pfnUnSetShader = hwSym("UnSetShader",NULL);
HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL);
// check gl renderer lib
if (HWD.pfnGetRenderVersion() != VERSION)
I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n"));

View File

@ -181,6 +181,24 @@ FILE *W_OpenWadFile(const char **filename, boolean useerrors)
return handle;
}
static inline void W_LoadShader(UINT16 wadnum, UINT16 lump, char *name, boolean fragment)
{
size_t shader_size;
char *shader_string;
char shader_number[2];
shader_size = W_LumpLengthPwad(wadnum, lump);
shader_string = Z_Malloc(shader_size, PU_STATIC, NULL);
W_ReadLumpPwad(wadnum, lump, shader_string);
shader_number[0] = name[6];
shader_number[1] = name[7];
HWR_LoadShader(atoi(shader_number), shader_string, shader_size, fragment);
Z_Free(shader_string);
}
// Look for all DEHACKED and Lua scripts inside a PK3 archive.
static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum)
{
@ -195,6 +213,7 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum)
LUA_LoadLump(wadnum, posStart);
}
#endif
posStart = W_CheckNumForFolderStartPK3("SOC/", wadnum, 0);
if (posStart != INT16_MAX)
{
@ -211,8 +230,22 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum)
DEH_LoadDehackedLumpPwad(wadnum, posStart);
free(name);
}
}
// jimita 18032019
#ifdef HWRENDER
posStart = W_CheckNumForFolderStartPK3("Shaders/", wadnum, 0);
if (posStart != INT16_MAX)
{
posEnd = W_CheckNumForFolderEndPK3("Shaders/", wadnum, posStart);
posStart++;
for (; posStart < posEnd; posStart++)
{
lumpinfo_t *lump_p = &wadfiles[wadnum]->lumpinfo[posStart];
W_LoadShader(wadnum, posStart, lump_p->name2, !(memcmp(lump_p->name2,"FRGSHD",6)));
}
}
#endif
}
// search for all DEHACKED lump in all wads and load it
@ -256,6 +289,20 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum)
}
}
// jimita 18032019
#ifdef HWRENDER
{
lumpinfo_t *lump_p = wadfiles[wadnum]->lumpinfo;
for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
{
boolean vertex = (!(memcmp(lump_p->name,"VRTSHD",6)));
boolean fragment = (!(memcmp(lump_p->name,"FRGSHD",6)));
if (vertex || fragment)
W_LoadShader(wadnum, lump, lump_p->name, fragment);
}
}
#endif
#ifdef SCANTHINGS
// Scan maps for emblems 'n shit
{
@ -1694,6 +1741,8 @@ int W_VerifyNMUSlumps(const char *filename)
{"PAL", 3},
{"CLM", 3},
{"TRANS", 5},
{"VRTSHD", 6},
{"FRGSHD", 6},
{NULL, 0},
};
return W_VerifyFile(filename, NMUSlist, false);