mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-13 00:24:44 +00:00
Merge pull request #198 from DanielGibson/gl3-shadows-last
GL3: Render Model shadows last, refactor gl3_mesh.c
This commit is contained in:
commit
505c67385e
3 changed files with 190 additions and 95 deletions
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue