GL3: Render Model shadows last, reduce global variables in gl3_mesh.c

The model shadows are rendered after all entities are rendered.
This fixes them making entity brushes below them translucent (#194)

The model rendering code used lots of global variables, many of them
totally superfluous (esp. currententity, currentmodel).
I refactored the code to use less global variables (this was at least
partly needed to render the shadows later).
So this looks like lots of changes, but many of them are just using
"entity" instead of "currententity" or "model" instead of "currentmodel"
This commit is contained in:
Daniel Gibson 2017-05-15 12:34:38 +02:00
parent 6119591c6a
commit 865e97514d
3 changed files with 190 additions and 95 deletions

View file

@ -887,6 +887,8 @@ GL3_DrawEntitiesOnList(void)
return; return;
} }
GL3_ResetShadowAliasModels();
/* draw non-transparent first */ /* draw non-transparent first */
for (i = 0; i < gl3_newrefdef.num_entities; i++) for (i = 0; i < gl3_newrefdef.num_entities; i++)
{ {
@ -975,7 +977,10 @@ GL3_DrawEntitiesOnList(void)
} }
} }
GL3_DrawAliasShadows();
glDepthMask(1); /* back to writing */ glDepthMask(1); /* back to writing */
} }
static int static int

View file

@ -43,13 +43,22 @@ static float r_avertexnormal_dots[SHADEDOT_QUANT][256] = {
typedef float vec4_t[4]; typedef float vec4_t[4];
static vec4_t s_lerped[MAX_VERTS]; static vec4_t s_lerped[MAX_VERTS];
vec3_t shadevector;
float shadelight[3];
float *shadedots = r_avertexnormal_dots[0];
extern vec3_t lightspot; extern vec3_t lightspot;
extern qboolean have_stencil; extern qboolean have_stencil;
typedef struct gl3_shadowinfo_s {
vec3_t lightspot;
vec3_t shadevector;
dmdl_t* paliashdr;
entity_t* entity;
} gl3_shadowinfo_t;
DA_TYPEDEF(gl3_shadowinfo_t, ShadowInfoArray_t);
// collect all models casting shadows (each frame)
// to draw shadows last
static ShadowInfoArray_t shadowModels = {0};
DA_TYPEDEF(gl3_alias_vtx_t, AliasVtxArray_t); DA_TYPEDEF(gl3_alias_vtx_t, AliasVtxArray_t);
DA_TYPEDEF(GLushort, UShortArray_t); DA_TYPEDEF(GLushort, UShortArray_t);
// dynamic arrays to batch all the data of a model, so we can render a model in one draw call // dynamic arrays to batch all the data of a model, so we can render a model in one draw call
@ -61,19 +70,18 @@ GL3_ShutdownMeshes(void)
{ {
da_free(vtxBuf); da_free(vtxBuf);
da_free(idxBuf); da_free(idxBuf);
da_free(shadowModels);
} }
static void static void
LerpVerts(int nverts, dtrivertx_t *v, dtrivertx_t *ov, LerpVerts(qboolean powerUpEffect, int nverts, dtrivertx_t *v, dtrivertx_t *ov,
dtrivertx_t *verts, float *lerp, float move[3], dtrivertx_t *verts, float *lerp, float move[3],
float frontv[3], float backv[3]) float frontv[3], float backv[3])
{ {
int i; int i;
if (currententity->flags & if (powerUpEffect)
(RF_SHELL_RED | RF_SHELL_GREEN |
RF_SHELL_BLUE | RF_SHELL_DOUBLE |
RF_SHELL_HALF_DAM))
{ {
for (i = 0; i < nverts; i++, v++, ov++, lerp += 4) for (i = 0; i < nverts; i++, v++, ov++, lerp += 4)
{ {
@ -102,7 +110,7 @@ LerpVerts(int nverts, dtrivertx_t *v, dtrivertx_t *ov,
* Interpolates between two frames and origins * Interpolates between two frames and origins
*/ */
static void static void
DrawAliasFrameLerp(dmdl_t *paliashdr, float backlerp) DrawAliasFrameLerp(dmdl_t *paliashdr, entity_t* entity, vec3_t shadelight)
{ {
GLenum type; GLenum type;
float l; float l;
@ -110,31 +118,36 @@ DrawAliasFrameLerp(dmdl_t *paliashdr, float backlerp)
dtrivertx_t *v, *ov, *verts; dtrivertx_t *v, *ov, *verts;
int *order; int *order;
int count; int count;
float frontlerp;
float alpha; float alpha;
vec3_t move, delta, vectors[3]; vec3_t move, delta, vectors[3];
vec3_t frontv, backv; vec3_t frontv, backv;
int i; int i;
int index_xyz; int index_xyz;
float backlerp = entity->backlerp;
float frontlerp = 1.0 - backlerp;
float *lerp; float *lerp;
// draw without texture? used for quad damage effect etc, I think // draw without texture? used for quad damage effect etc, I think
qboolean colorOnly = 0 != (currententity->flags & qboolean colorOnly = 0 != (entity->flags &
(RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | (RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE |
RF_SHELL_HALF_DAM)); RF_SHELL_HALF_DAM));
// TODO: maybe we could somehow store the non-rotated normal and do the dot in shader?
float* shadedots = r_avertexnormal_dots[((int)(entity->angles[1] *
(SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
+ currententity->frame * paliashdr->framesize); + entity->frame * paliashdr->framesize);
verts = v = frame->verts; verts = v = frame->verts;
oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
+ currententity->oldframe * paliashdr->framesize); + entity->oldframe * paliashdr->framesize);
ov = oldframe->verts; ov = oldframe->verts;
order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds); order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds);
if (currententity->flags & RF_TRANSLUCENT) if (entity->flags & RF_TRANSLUCENT)
{ {
alpha = currententity->alpha * 0.666f; alpha = entity->alpha * 0.666f;
} }
else else
{ {
@ -150,11 +163,9 @@ DrawAliasFrameLerp(dmdl_t *paliashdr, float backlerp)
GL3_UseProgram(gl3state.si3Dalias.shaderProgram); GL3_UseProgram(gl3state.si3Dalias.shaderProgram);
} }
frontlerp = 1.0 - backlerp;
/* move should be the delta back to the previous frame * backlerp */ /* move should be the delta back to the previous frame * backlerp */
VectorSubtract(currententity->oldorigin, currententity->origin, delta); VectorSubtract(entity->oldorigin, entity->origin, delta);
AngleVectors(currententity->angles, vectors[0], vectors[1], vectors[2]); AngleVectors(entity->angles, vectors[0], vectors[1], vectors[2]);
move[0] = DotProduct(delta, vectors[0]); /* forward */ move[0] = DotProduct(delta, vectors[0]); /* forward */
move[1] = -DotProduct(delta, vectors[1]); /* left */ move[1] = -DotProduct(delta, vectors[1]); /* left */
@ -172,7 +183,7 @@ DrawAliasFrameLerp(dmdl_t *paliashdr, float backlerp)
lerp = s_lerped[0]; lerp = s_lerped[0];
LerpVerts(paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv); LerpVerts(colorOnly, paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv);
assert(sizeof(gl3_alias_vtx_t) == 9*sizeof(GLfloat)); assert(sizeof(gl3_alias_vtx_t) == 9*sizeof(GLfloat));
@ -246,7 +257,7 @@ DrawAliasFrameLerp(dmdl_t *paliashdr, float backlerp)
order += 3; order += 3;
/* normals and vertexes come from the frame list */ /* normals and vertexes come from the frame list */
// shadedots is set in GL3DrawAliasModel() according to rotation (around Z axis I think) // shadedots is set above according to rotation (around Z axis I think)
// to one of 16 (SHADEDOT_QUANT) presets in r_avertexnormal_dots // to one of 16 (SHADEDOT_QUANT) presets in r_avertexnormal_dots
l = shadedots[verts[index_xyz].lightnormalindex]; l = shadedots[verts[index_xyz].lightnormalindex];
@ -311,7 +322,7 @@ DrawAliasFrameLerp(dmdl_t *paliashdr, float backlerp)
} }
static void static void
DrawAliasShadow(dmdl_t *paliashdr, int posenum) DrawAliasShadow(gl3_shadowinfo_t* shadowInfo)
{ {
GLenum type; GLenum type;
int *order; int *order;
@ -319,18 +330,56 @@ DrawAliasShadow(dmdl_t *paliashdr, int posenum)
float height = 0, lheight; float height = 0, lheight;
int count; int count;
lheight = currententity->origin[2] - lightspot[2]; dmdl_t* paliashdr = shadowInfo->paliashdr;
order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds); entity_t* entity = shadowInfo->entity;
height = -lheight + 0.1f;
if (have_stencil) vec3_t shadevector;
VectorCopy(shadowInfo->shadevector, shadevector);
// all in this scope is to set s_lerped
{ {
glEnable(GL_STENCIL_TEST); daliasframe_t *frame, *oldframe;
glStencilFunc(GL_EQUAL, 1, 2); dtrivertx_t *v, *ov, *verts;
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); float backlerp = entity->backlerp;
float frontlerp = 1.0f - backlerp;
vec3_t move, delta, vectors[3];
vec3_t frontv, backv;
int i;
frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
+ entity->frame * paliashdr->framesize);
verts = v = frame->verts;
oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames
+ entity->oldframe * paliashdr->framesize);
ov = oldframe->verts;
/* move should be the delta back to the previous frame * backlerp */
VectorSubtract(entity->oldorigin, entity->origin, delta);
AngleVectors(entity->angles, vectors[0], vectors[1], vectors[2]);
move[0] = DotProduct(delta, vectors[0]); /* forward */
move[1] = -DotProduct(delta, vectors[1]); /* left */
move[2] = DotProduct(delta, vectors[2]); /* up */
VectorAdd(move, oldframe->translate, move);
for (i = 0; i < 3; i++)
{
move[i] = backlerp * move[i] + frontlerp * frame->translate[i];
frontv[i] = frontlerp * frame->scale[i];
backv[i] = backlerp * oldframe->scale[i];
}
// false: don't extrude vertices for powerup - this means the powerup shell
// is not seen in the shadow, only the underlying model..
LerpVerts(false, paliashdr->num_xyz, v, ov, verts, s_lerped[0], move, frontv, backv);
} }
GL3_UseProgram(gl3state.si3DaliasColor.shaderProgram); lheight = entity->origin[2] - shadowInfo->lightspot[2];
order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds);
height = -lheight + 0.1f;
// GL1 uses alpha 0.5, but in GL3 0.3 looks better // GL1 uses alpha 0.5, but in GL3 0.3 looks better
GLfloat color[4] = {0, 0, 0, 0.3}; GLfloat color[4] = {0, 0, 0, 0.3};
@ -431,11 +480,6 @@ DrawAliasShadow(dmdl_t *paliashdr, int posenum)
GL3_BindEBO(gl3state.eboAlias); GL3_BindEBO(gl3state.eboAlias);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, da_count(idxBuf)*sizeof(GLushort), idxBuf.p, GL_STREAM_DRAW); 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); glDrawElements(GL_TRIANGLES, da_count(idxBuf), GL_UNSIGNED_SHORT, NULL);
if (have_stencil)
{
glDisable(GL_STENCIL_TEST);
}
} }
static qboolean static qboolean
@ -449,19 +493,21 @@ CullAliasModel(vec3_t bbox[8], entity_t *e)
daliasframe_t *pframe, *poldframe; daliasframe_t *pframe, *poldframe;
vec3_t angles; vec3_t angles;
paliashdr = (dmdl_t *)currentmodel->extradata; gl3model_t* model = e->model;
paliashdr = (dmdl_t *)model->extradata;
if ((e->frame >= paliashdr->num_frames) || (e->frame < 0)) if ((e->frame >= paliashdr->num_frames) || (e->frame < 0))
{ {
R_Printf(PRINT_DEVELOPER, "R_CullAliasModel %s: no such frame %d\n", R_Printf(PRINT_DEVELOPER, "R_CullAliasModel %s: no such frame %d\n",
currentmodel->name, e->frame); model->name, e->frame);
e->frame = 0; e->frame = 0;
} }
if ((e->oldframe >= paliashdr->num_frames) || (e->oldframe < 0)) if ((e->oldframe >= paliashdr->num_frames) || (e->oldframe < 0))
{ {
R_Printf(PRINT_DEVELOPER, "R_CullAliasModel %s: no such oldframe %d\n", R_Printf(PRINT_DEVELOPER, "R_CullAliasModel %s: no such oldframe %d\n",
currentmodel->name, e->oldframe); model->name, e->oldframe);
e->oldframe = 0; e->oldframe = 0;
} }
@ -591,26 +637,28 @@ CullAliasModel(vec3_t bbox[8], entity_t *e)
} }
void void
GL3_DrawAliasModel(entity_t *e) GL3_DrawAliasModel(entity_t *entity)
{ {
int i; int i;
dmdl_t *paliashdr; dmdl_t *paliashdr;
float an; float an;
vec3_t bbox[8]; vec3_t bbox[8];
vec3_t shadelight;
vec3_t shadevector;
gl3image_t *skin; gl3image_t *skin;
hmm_mat4 origProjMat = {0}; // use for left-handed rendering hmm_mat4 origProjMat = {0}; // use for left-handed rendering
// used to restore ModelView matrix after changing it for this entities position/rotation // used to restore ModelView matrix after changing it for this entities position/rotation
hmm_mat4 origModelMat = {0}; hmm_mat4 origModelMat = {0};
if (!(e->flags & RF_WEAPONMODEL)) if (!(entity->flags & RF_WEAPONMODEL))
{ {
if (CullAliasModel(bbox, e)) if (CullAliasModel(bbox, entity))
{ {
return; return;
} }
} }
if (e->flags & RF_WEAPONMODEL) if (entity->flags & RF_WEAPONMODEL)
{ {
if (gl_lefthand->value == 2) if (gl_lefthand->value == 2)
{ {
@ -618,44 +666,45 @@ GL3_DrawAliasModel(entity_t *e)
} }
} }
paliashdr = (dmdl_t *)currentmodel->extradata; gl3model_t* model = entity->model;
paliashdr = (dmdl_t *)model->extradata;
/* get lighting information */ /* get lighting information */
if (currententity->flags & if (entity->flags &
(RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | (RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED |
RF_SHELL_BLUE | RF_SHELL_DOUBLE)) RF_SHELL_BLUE | RF_SHELL_DOUBLE))
{ {
VectorClear(shadelight); VectorClear(shadelight);
if (currententity->flags & RF_SHELL_HALF_DAM) if (entity->flags & RF_SHELL_HALF_DAM)
{ {
shadelight[0] = 0.56; shadelight[0] = 0.56;
shadelight[1] = 0.59; shadelight[1] = 0.59;
shadelight[2] = 0.45; shadelight[2] = 0.45;
} }
if (currententity->flags & RF_SHELL_DOUBLE) if (entity->flags & RF_SHELL_DOUBLE)
{ {
shadelight[0] = 0.9; shadelight[0] = 0.9;
shadelight[1] = 0.7; shadelight[1] = 0.7;
} }
if (currententity->flags & RF_SHELL_RED) if (entity->flags & RF_SHELL_RED)
{ {
shadelight[0] = 1.0; shadelight[0] = 1.0;
} }
if (currententity->flags & RF_SHELL_GREEN) if (entity->flags & RF_SHELL_GREEN)
{ {
shadelight[1] = 1.0; shadelight[1] = 1.0;
} }
if (currententity->flags & RF_SHELL_BLUE) if (entity->flags & RF_SHELL_BLUE)
{ {
shadelight[2] = 1.0; shadelight[2] = 1.0;
} }
} }
else if (currententity->flags & RF_FULLBRIGHT) else if (entity->flags & RF_FULLBRIGHT)
{ {
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
@ -664,10 +713,10 @@ GL3_DrawAliasModel(entity_t *e)
} }
else else
{ {
GL3_LightPoint(currententity->origin, shadelight); GL3_LightPoint(entity->origin, shadelight);
/* player lighting hack for communication back to server */ /* player lighting hack for communication back to server */
if (currententity->flags & RF_WEAPONMODEL) if (entity->flags & RF_WEAPONMODEL)
{ {
/* pick the greatest component, which should be /* pick the greatest component, which should be
the same as the mono value returned by software */ the same as the mono value returned by software */
@ -696,7 +745,7 @@ GL3_DrawAliasModel(entity_t *e)
} }
} }
if (currententity->flags & RF_MINLIGHT) if (entity->flags & RF_MINLIGHT)
{ {
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
@ -714,7 +763,7 @@ GL3_DrawAliasModel(entity_t *e)
} }
} }
if (currententity->flags & RF_GLOW) if (entity->flags & RF_GLOW)
{ {
/* bonus items will pulse with time */ /* bonus items will pulse with time */
float scale; float scale;
@ -737,18 +786,14 @@ GL3_DrawAliasModel(entity_t *e)
// Note: gl_overbrightbits are now applied in shader. // Note: gl_overbrightbits are now applied in shader.
/* ir goggles color override */ /* ir goggles color override */
if ((gl3_newrefdef.rdflags & RDF_IRGOGGLES) && (currententity->flags & RF_IR_VISIBLE)) if ((gl3_newrefdef.rdflags & RDF_IRGOGGLES) && (entity->flags & RF_IR_VISIBLE))
{ {
shadelight[0] = 1.0; shadelight[0] = 1.0;
shadelight[1] = 0.0; shadelight[1] = 0.0;
shadelight[2] = 0.0; shadelight[2] = 0.0;
} }
// TODO: maybe we could somehow store the non-rotated normal and do the dot in shader? an = entity->angles[1] / 180 * M_PI;
shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] *
(SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
an = currententity->angles[1] / 180 * M_PI;
shadevector[0] = cos(-an); shadevector[0] = cos(-an);
shadevector[1] = sin(-an); shadevector[1] = sin(-an);
shadevector[2] = 1; shadevector[2] = 1;
@ -758,13 +803,13 @@ GL3_DrawAliasModel(entity_t *e)
c_alias_polys += paliashdr->num_tris; c_alias_polys += paliashdr->num_tris;
/* draw all the triangles */ /* draw all the triangles */
if (currententity->flags & RF_DEPTHHACK) if (entity->flags & RF_DEPTHHACK)
{ {
/* hack the depth range to prevent view model from poking into walls */ /* hack the depth range to prevent view model from poking into walls */
glDepthRange(gl3depthmin, gl3depthmin + 0.3 * (gl3depthmax - gl3depthmin)); glDepthRange(gl3depthmin, gl3depthmin + 0.3 * (gl3depthmax - gl3depthmin));
} }
if ((currententity->flags & RF_WEAPONMODEL) && (gl_lefthand->value == 1.0F)) if ((entity->flags & RF_WEAPONMODEL) && (gl_lefthand->value == 1.0F))
{ {
origProjMat = gl3state.uni3DData.transProjMat4; origProjMat = gl3state.uni3DData.transProjMat4;
// to mirror gun so it's rendered left-handed, just invert X-axis column // to mirror gun so it's rendered left-handed, just invert X-axis column
@ -782,29 +827,29 @@ GL3_DrawAliasModel(entity_t *e)
//glPushMatrix(); //glPushMatrix();
origModelMat = gl3state.uni3DData.transModelMat4; origModelMat = gl3state.uni3DData.transModelMat4;
e->angles[PITCH] = -e->angles[PITCH]; entity->angles[PITCH] = -entity->angles[PITCH];
GL3_RotateForEntity(e); GL3_RotateForEntity(entity);
e->angles[PITCH] = -e->angles[PITCH]; entity->angles[PITCH] = -entity->angles[PITCH];
/* select skin */ /* select skin */
if (currententity->skin) if (entity->skin)
{ {
skin = currententity->skin; /* custom player skin */ skin = entity->skin; /* custom player skin */
} }
else else
{ {
if (currententity->skinnum >= MAX_MD2SKINS) if (entity->skinnum >= MAX_MD2SKINS)
{ {
skin = currentmodel->skins[0]; skin = model->skins[0];
} }
else else
{ {
skin = currentmodel->skins[currententity->skinnum]; skin = model->skins[entity->skinnum];
if (!skin) if (!skin)
{ {
skin = currentmodel->skins[0]; skin = model->skins[0];
} }
} }
} }
@ -816,58 +861,95 @@ GL3_DrawAliasModel(entity_t *e)
GL3_Bind(skin->texnum); GL3_Bind(skin->texnum);
if (currententity->flags & RF_TRANSLUCENT) if (entity->flags & RF_TRANSLUCENT)
{ {
glEnable(GL_BLEND); glEnable(GL_BLEND);
} }
if ((currententity->frame >= paliashdr->num_frames) || if ((entity->frame >= paliashdr->num_frames) ||
(currententity->frame < 0)) (entity->frame < 0))
{ {
R_Printf(PRINT_DEVELOPER, "R_DrawAliasModel %s: no such frame %d\n", R_Printf(PRINT_DEVELOPER, "R_DrawAliasModel %s: no such frame %d\n",
currentmodel->name, currententity->frame); model->name, entity->frame);
currententity->frame = 0; entity->frame = 0;
currententity->oldframe = 0; entity->oldframe = 0;
} }
if ((currententity->oldframe >= paliashdr->num_frames) || if ((entity->oldframe >= paliashdr->num_frames) ||
(currententity->oldframe < 0)) (entity->oldframe < 0))
{ {
R_Printf(PRINT_DEVELOPER, "R_DrawAliasModel %s: no such oldframe %d\n", R_Printf(PRINT_DEVELOPER, "R_DrawAliasModel %s: no such oldframe %d\n",
currentmodel->name, currententity->oldframe); model->name, entity->oldframe);
currententity->frame = 0; entity->frame = 0;
currententity->oldframe = 0; entity->oldframe = 0;
} }
DrawAliasFrameLerp(paliashdr, currententity->backlerp); DrawAliasFrameLerp(paliashdr, entity, shadelight);
//glPopMatrix(); //glPopMatrix();
gl3state.uni3DData.transModelMat4 = origModelMat; gl3state.uni3DData.transModelMat4 = origModelMat;
GL3_UpdateUBO3D(); GL3_UpdateUBO3D();
if ((currententity->flags & RF_WEAPONMODEL) && (gl_lefthand->value == 1.0F)) if ((entity->flags & RF_WEAPONMODEL) && (gl_lefthand->value == 1.0F))
{ {
gl3state.uni3DData.transProjMat4 = origProjMat; gl3state.uni3DData.transProjMat4 = origProjMat;
GL3_UpdateUBO3D(); GL3_UpdateUBO3D();
glCullFace(GL_FRONT); glCullFace(GL_FRONT);
} }
if (currententity->flags & RF_TRANSLUCENT) if (entity->flags & RF_TRANSLUCENT)
{ {
glDisable(GL_BLEND); glDisable(GL_BLEND);
} }
if (currententity->flags & RF_DEPTHHACK) if (entity->flags & RF_DEPTHHACK)
{ {
glDepthRange(gl3depthmin, gl3depthmax); glDepthRange(gl3depthmin, gl3depthmax);
} }
if (gl_shadows->value && if (gl_shadows->value &&
!(currententity->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL | RF_NOSHADOW))) !(entity->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL | RF_NOSHADOW)))
{ {
//glPushMatrix(); gl3_shadowinfo_t si = {0};
hmm_mat4 oldMat = gl3state.uni3DData.transModelMat4; VectorCopy(lightspot, si.lightspot);
VectorCopy(shadevector, si.shadevector);
si.paliashdr = paliashdr;
si.entity = entity;
da_push(shadowModels, si);
}
}
void GL3_ResetShadowAliasModels(void)
{
da_clear(shadowModels);
}
void GL3_DrawAliasShadows(void)
{
size_t numShadowModels = da_count(shadowModels);
if(numShadowModels == 0)
{
return;
}
//glPushMatrix();
hmm_mat4 oldMat = gl3state.uni3DData.transModelMat4;
glEnable(GL_BLEND);
GL3_UseProgram(gl3state.si3DaliasColor.shaderProgram);
if (have_stencil)
{
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_EQUAL, 1, 2);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
}
for(size_t i=0; i<numShadowModels; ++i)
{
gl3_shadowinfo_t* si = &shadowModels.p[i]; // XXX da_getptr(shadowModels, i);
entity_t* e = si->entity;
/* don't rotate shadows on ungodly axes */ /* don't rotate shadows on ungodly axes */
//glTranslatef(e->origin[0], e->origin[1], e->origin[2]); //glTranslatef(e->origin[0], e->origin[1], e->origin[2]);
@ -877,12 +959,18 @@ GL3_DrawAliasModel(entity_t *e)
gl3state.uni3DData.transModelMat4 = HMM_MultiplyMat4(oldMat, rotTransMat); gl3state.uni3DData.transModelMat4 = HMM_MultiplyMat4(oldMat, rotTransMat);
GL3_UpdateUBO3D(); GL3_UpdateUBO3D();
glEnable(GL_BLEND); DrawAliasShadow(si);
DrawAliasShadow(paliashdr, currententity->frame);
glDisable(GL_BLEND);
//glPopMatrix();
gl3state.uni3DData.transModelMat4 = oldMat;
GL3_UpdateUBO3D();
} }
if (have_stencil)
{
glDisable(GL_STENCIL_TEST);
}
glDisable(GL_BLEND);
//glPopMatrix();
gl3state.uni3DData.transModelMat4 = oldMat;
GL3_UpdateUBO3D();
} }

View file

@ -462,6 +462,8 @@ extern void GL3_MarkLeaves(void);
// gl3_mesh.c // gl3_mesh.c
extern void GL3_DrawAliasModel(entity_t *e); extern void GL3_DrawAliasModel(entity_t *e);
extern void GL3_ResetShadowAliasModels(void);
extern void GL3_DrawAliasShadows(void);
extern void GL3_ShutdownMeshes(void); extern void GL3_ShutdownMeshes(void);
// gl3_shaders.c // gl3_shaders.c