From b45a6d8ef993fd93e3c71b9d125cbc171a5789fc Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Tue, 2 May 2017 02:43:45 +0200 Subject: [PATCH] GL3: Simple Stencil-Shadows Like GL1 gl_shadows + gl_stencilshadows: no shadow volumes, but looks ok apart from standing over edges The gl_stencilshadows cvar isn't used in GL3, it always uses the stencil buffer if available (and if gl_shadows != 0) This still needs performance optimizations: Like the GL1 impl it takes lots of draw calls per model, it could be done with one per model like when rendering the actual model. --- src/client/refresh/gl3/gl3_main.c | 7 ++- src/client/refresh/gl3/gl3_mesh.c | 73 ++++++++++++--------------- src/client/refresh/gl3/header/local.h | 2 +- 3 files changed, 36 insertions(+), 46 deletions(-) diff --git a/src/client/refresh/gl3/gl3_main.c b/src/client/refresh/gl3/gl3_main.c index 7d6e2124..de516915 100644 --- a/src/client/refresh/gl3/gl3_main.c +++ b/src/client/refresh/gl3/gl3_main.c @@ -123,8 +123,8 @@ cvar_t *gl_zfix; cvar_t *gl_fullbright; cvar_t *gl_modulate; cvar_t *gl_lightmap; -cvar_t *gl_shadows; // TODO: do we really need 2 cvars for shadows here? -cvar_t *gl_stencilshadow; +cvar_t *gl_shadows; +// no gl_stencilshadows, always use stencil (if available) cvar_t *gl_dynamic; @@ -234,7 +234,6 @@ GL3_Register(void) gl_lightmap = ri.Cvar_Get("gl_lightmap", "0", 0); gl_shadows = ri.Cvar_Get("gl_shadows", "0", CVAR_ARCHIVE); - gl_stencilshadow = ri.Cvar_Get("gl_stencilshadow", "0", CVAR_ARCHIVE); gl_modulate = ri.Cvar_Get("gl_modulate", "1", CVAR_ARCHIVE); gl_zfix = ri.Cvar_Get("gl_zfix", "0", 0); @@ -1589,7 +1588,7 @@ GL3_Clear(void) } /* stencilbuffer shadows */ - if (gl_shadows->value && have_stencil && gl_stencilshadow->value) + if (gl_shadows->value && have_stencil) { glClearStencil(1); glClear(GL_STENCIL_BUFFER_BIT); diff --git a/src/client/refresh/gl3/gl3_mesh.c b/src/client/refresh/gl3/gl3_mesh.c index 2a386b71..117b9e81 100644 --- a/src/client/refresh/gl3/gl3_mesh.c +++ b/src/client/refresh/gl3/gl3_mesh.c @@ -309,12 +309,10 @@ DrawAliasFrameLerp(dmdl_t *paliashdr, float backlerp) glBufferData(GL_ELEMENT_ARRAY_BUFFER, da_count(idxBuf)*sizeof(GLushort), idxBuf.p, GL_STREAM_DRAW); glDrawElements(GL_TRIANGLES, da_count(idxBuf), GL_UNSIGNED_SHORT, NULL); } -#if 0 // TODO: implemenet some time.. + static void DrawAliasShadow(dmdl_t *paliashdr, int posenum) { - - unsigned short total; GLenum type; int *order; vec3_t point; @@ -325,16 +323,19 @@ DrawAliasShadow(dmdl_t *paliashdr, int posenum) order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds); height = -lheight + 0.1f; - /* stencilbuffer shadows */ - -#if 0 - if (have_stencil && gl_stencilshadow->value) + if (have_stencil) { glEnable(GL_STENCIL_TEST); glStencilFunc(GL_EQUAL, 1, 2); glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); } -#endif // 0 + + GL3_UseProgram(gl3state.si3DaliasColor.shaderProgram); + + // GL1 uses alpha 0.5, but in GL3 0.3 looks better + GLfloat color[4] = {0, 0, 0, 0.3}; + + STUB_ONCE("TODO: Draw Stencil Shadows in one drawcall, like models!"); while (1) { @@ -357,44 +358,35 @@ DrawAliasShadow(dmdl_t *paliashdr, int posenum) type = GL_TRIANGLE_STRIP; } - total = count; - GLfloat vtx[3*total]; - unsigned int index_vtx = 0; + gl3_alias_vtx_t vtx[count]; - do + for(int i=0; ivalue) + if (have_stencil) { - //glDisable(GL_STENCIL_TEST); + glDisable(GL_STENCIL_TEST); } } -#endif // 0 static qboolean CullAliasModel(vec3_t bbox[8], entity_t *e) @@ -821,27 +813,26 @@ GL3_DrawAliasModel(entity_t *e) glDepthRange(gl3depthmin, gl3depthmax); } - STUB_ONCE("TODO: *proper* stencil shadows!") -#if 0 if (gl_shadows->value && !(currententity->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL | RF_NOSHADOW))) { - glPushMatrix(); + //glPushMatrix(); + hmm_mat4 oldMat = gl3state.uni3DData.transModelMat4; /* don't rotate shadows on ungodly axes */ - glTranslatef(e->origin[0], e->origin[1], e->origin[2]); - glRotatef(e->angles[1], 0, 0, 1); + //glTranslatef(e->origin[0], e->origin[1], e->origin[2]); + //glRotatef(e->angles[1], 0, 0, 1); + hmm_mat4 rotTransMat = HMM_Rotate(e->angles[1], HMM_Vec3(0, 0, 1)); + VectorCopy(e->origin, rotTransMat.Elements[3]); + gl3state.uni3DData.transModelMat4 = HMM_MultiplyMat4(oldMat, rotTransMat); + GL3_UpdateUBO3D(); - glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); - glColor4f(0, 0, 0, 0.5f); DrawAliasShadow(paliashdr, currententity->frame); - glEnable(GL_TEXTURE_2D); glDisable(GL_BLEND); - glPopMatrix(); + //glPopMatrix(); + gl3state.uni3DData.transModelMat4 = oldMat; + GL3_UpdateUBO3D(); } - - glColor4f(1, 1, 1, 1); -#endif // 0 } diff --git a/src/client/refresh/gl3/header/local.h b/src/client/refresh/gl3/header/local.h index 752896c6..e0efc8c7 100644 --- a/src/client/refresh/gl3/header/local.h +++ b/src/client/refresh/gl3/header/local.h @@ -508,7 +508,7 @@ extern cvar_t *gl3_particle_fade_factor; extern cvar_t *gl_modulate; extern cvar_t *gl_lightmap; -extern cvar_t *gl_stencilshadow; +extern cvar_t *gl_shadows; extern cvar_t *gl_dynamic;