Merge pull request #198 from DanielGibson/gl3-shadows-last

GL3: Render Model shadows last, refactor gl3_mesh.c
This commit is contained in:
Yamagi 2017-05-16 08:58:09 +02:00 committed by GitHub
commit 505c67385e
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];
} }
GL3_UseProgram(gl3state.si3DaliasColor.shaderProgram); // 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);
}
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,59 +861,96 @@ 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)))
{ {
gl3_shadowinfo_t si = {0};
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(); //glPushMatrix();
hmm_mat4 oldMat = gl3state.uni3DData.transModelMat4; 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]);
//glRotatef(e->angles[1], 0, 0, 1); //glRotatef(e->angles[1], 0, 0, 1);
@ -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); }
if (have_stencil)
{
glDisable(GL_STENCIL_TEST);
}
glDisable(GL_BLEND); glDisable(GL_BLEND);
//glPopMatrix(); //glPopMatrix();
gl3state.uni3DData.transModelMat4 = oldMat; gl3state.uni3DData.transModelMat4 = oldMat;
GL3_UpdateUBO3D(); 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