diff options
Diffstat (limited to 'src/refresh/gl/mesh.c')
-rw-r--r-- | src/refresh/gl/mesh.c | 468 |
1 files changed, 231 insertions, 237 deletions
diff --git a/src/refresh/gl/mesh.c b/src/refresh/gl/mesh.c index 1396cc6..e4f9183 100644 --- a/src/refresh/gl/mesh.c +++ b/src/refresh/gl/mesh.c @@ -16,43 +16,43 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include <assert.h> + #include "gl.h" -typedef void (*tessfunc_t)(const maliasmesh_t *); +typedef struct { + unsigned oldframenum; + unsigned newframenum; + float frontlerp; + float backlerp; -static int oldframenum; -static int newframenum; -static float frontlerp; -static float backlerp; -static vec3_t origin; -static vec3_t oldscale; -static vec3_t newscale; -static vec3_t translate; -static vec_t shellscale; -static tessfunc_t tessfunc; -static vec4_t color; + vec3_t origin; + vec3_t oldscale; + vec3_t newscale; + vec3_t translate; + vec_t shellscale; + vec4_t color; -static const vec_t *shadelight; -static vec3_t shadedir; + const vec_t *shadelight; + vec3_t shadedir; -static float celscale; + float celscale; -static mat4_t shadowmatrix; + mat4_t shadowmatrix; +} tess_info_t; -static void setup_dotshading(void) +static void setup_dotshading(tess_info_t *t) { float cp, cy, sp, sy; vec_t yaw; - shadelight = NULL; - if (!gl_dotshading->integer) return; if (glr.ent->flags & RF_SHELL_MASK) return; - shadelight = color; + t->shadelight = t->color; // matches the anormtab.h precalculations yaw = -DEG2RAD(glr.ent->angles[YAW]); @@ -60,14 +60,16 @@ static void setup_dotshading(void) sy = sin(yaw); cp = cos(-M_PI / 4); sp = sin(-M_PI / 4); - shadedir[0] = cp * cy; - shadedir[1] = cp * sy; - shadedir[2] = -sp; + + t->shadedir[0] = cp * cy; + t->shadedir[1] = cp * sy; + t->shadedir[2] = -sp; } -static inline vec_t shadedot(const vec_t *normal) +static inline vec_t shadedot(const tess_info_t *t, + const vec_t *normal) { - vec_t d = DotProduct(normal, shadedir); + vec_t d = DotProduct(normal, t->shadedir); // matches the anormtab.h precalculations if (d < 0) { @@ -89,9 +91,26 @@ static inline vec_t *get_static_normal(vec_t *normal, const maliasvert_t *vert) return normal; } -static void tess_static_shell(const maliasmesh_t *mesh) +static inline vec_t *get_lerped_normal(const tess_info_t *t, + vec_t *normal, + const maliasvert_t *oldvert, + const maliasvert_t *newvert) +{ + vec3_t oldnorm, newnorm; + + get_static_normal(oldnorm, oldvert); + get_static_normal(newnorm, newvert); + + LerpVector2(oldnorm, newnorm, t->backlerp, t->frontlerp, normal); + VectorNormalize(normal); + + return normal; +} + +static void tess_static_shell(const tess_info_t *t, + const maliasmesh_t *mesh) { - maliasvert_t *src_vert = &mesh->verts[newframenum * mesh->numverts]; + maliasvert_t *src_vert = &mesh->verts[t->newframenum * mesh->numverts]; vec_t *dst_vert = tess.vertices; int count = mesh->numverts; vec3_t normal; @@ -99,182 +118,146 @@ static void tess_static_shell(const maliasmesh_t *mesh) while (count--) { get_static_normal(normal, src_vert); - dst_vert[0] = normal[0] * shellscale + - src_vert->pos[0] * newscale[0] + translate[0]; - dst_vert[1] = normal[1] * shellscale + - src_vert->pos[1] * newscale[1] + translate[1]; - dst_vert[2] = normal[2] * shellscale + - src_vert->pos[2] * newscale[2] + translate[2]; - dst_vert += 4; + VectorCopy(t->translate, dst_vert); + VectorScaleAcc(normal, t->shellscale, dst_vert); + VectorVectorScaleAcc(src_vert->pos, t->newscale, dst_vert); + dst_vert += 4; src_vert++; } } -static void tess_static_shade(const maliasmesh_t *mesh) +static void tess_static_shade(const tess_info_t *t, + const maliasmesh_t *mesh) { - maliasvert_t *src_vert = &mesh->verts[newframenum * mesh->numverts]; + maliasvert_t *src_vert = &mesh->verts[t->newframenum * mesh->numverts]; vec_t *dst_vert = tess.vertices; int count = mesh->numverts; vec3_t normal; vec_t d; while (count--) { - d = shadedot(get_static_normal(normal, src_vert)); - - dst_vert[0] = src_vert->pos[0] * newscale[0] + translate[0]; - dst_vert[1] = src_vert->pos[1] * newscale[1] + translate[1]; - dst_vert[2] = src_vert->pos[2] * newscale[2] + translate[2]; - dst_vert[4] = shadelight[0] * d; - dst_vert[5] = shadelight[1] * d; - dst_vert[6] = shadelight[2] * d; - dst_vert[7] = shadelight[3]; - dst_vert += VERTEX_SIZE; + get_static_normal(normal, src_vert); + d = shadedot(t, normal); + VectorCopy(t->translate, dst_vert); + VectorVectorScaleAcc(src_vert->pos, t->newscale, dst_vert); + + Vector4Copy(t->shadelight, dst_vert + 4); + VectorScale(dst_vert + 4, d, dst_vert + 4); + + dst_vert += VERTEX_SIZE; src_vert++; } } -static void tess_static_plain(const maliasmesh_t *mesh) +static void tess_static_plain(const tess_info_t *t, + const maliasmesh_t *mesh) { - maliasvert_t *src_vert = &mesh->verts[newframenum * mesh->numverts]; + maliasvert_t *src_vert = &mesh->verts[t->newframenum * mesh->numverts]; vec_t *dst_vert = tess.vertices; int count = mesh->numverts; while (count--) { - dst_vert[0] = src_vert->pos[0] * newscale[0] + translate[0]; - dst_vert[1] = src_vert->pos[1] * newscale[1] + translate[1]; - dst_vert[2] = src_vert->pos[2] * newscale[2] + translate[2]; - dst_vert += 4; + VectorCopy(t->translate, dst_vert); + VectorVectorScaleAcc(src_vert->pos, t->newscale, dst_vert); + dst_vert += 4; src_vert++; } } -static inline vec_t *get_lerped_normal(vec_t *normal, - const maliasvert_t *oldvert, - const maliasvert_t *newvert) -{ - vec3_t oldnorm, newnorm, tmp; - vec_t len; - - get_static_normal(oldnorm, oldvert); - get_static_normal(newnorm, newvert); - - LerpVector2(oldnorm, newnorm, backlerp, frontlerp, tmp); - - // normalize result - len = 1 / VectorLength(tmp); - VectorScale(tmp, len, normal); - - return normal; -} - -static void tess_lerped_shell(const maliasmesh_t *mesh) +static void tess_lerped_shell(const tess_info_t *t, + const maliasmesh_t *mesh) { - maliasvert_t *src_oldvert = &mesh->verts[oldframenum * mesh->numverts]; - maliasvert_t *src_newvert = &mesh->verts[newframenum * mesh->numverts]; + maliasvert_t *src_oldvert = &mesh->verts[t->oldframenum * mesh->numverts]; + maliasvert_t *src_newvert = &mesh->verts[t->newframenum * mesh->numverts]; vec_t *dst_vert = tess.vertices; int count = mesh->numverts; vec3_t normal; while (count--) { - get_lerped_normal(normal, src_oldvert, src_newvert); - - dst_vert[0] = normal[0] * shellscale + - src_oldvert->pos[0] * oldscale[0] + - src_newvert->pos[0] * newscale[0] + translate[0]; - dst_vert[1] = normal[1] * shellscale + - src_oldvert->pos[1] * oldscale[1] + - src_newvert->pos[1] * newscale[1] + translate[1]; - dst_vert[2] = normal[2] * shellscale + - src_oldvert->pos[2] * oldscale[2] + - src_newvert->pos[2] * newscale[2] + translate[2]; - dst_vert += 4; + get_lerped_normal(t, normal, src_oldvert, src_newvert); + VectorCopy(t->translate, dst_vert); + VectorVectorScaleAcc(src_oldvert->pos, t->oldscale, dst_vert); + VectorVectorScaleAcc(src_newvert->pos, t->newscale, dst_vert); + VectorScaleAcc(normal, t->shellscale, dst_vert); + + dst_vert += 4; src_oldvert++; src_newvert++; } } -static void tess_lerped_shade(const maliasmesh_t *mesh) +static void tess_lerped_shade(const tess_info_t *t, + const maliasmesh_t *mesh) { - maliasvert_t *src_oldvert = &mesh->verts[oldframenum * mesh->numverts]; - maliasvert_t *src_newvert = &mesh->verts[newframenum * mesh->numverts]; + maliasvert_t *src_oldvert = &mesh->verts[t->oldframenum * mesh->numverts]; + maliasvert_t *src_newvert = &mesh->verts[t->newframenum * mesh->numverts]; vec_t *dst_vert = tess.vertices; int count = mesh->numverts; vec3_t normal; vec_t d; while (count--) { - d = shadedot(get_lerped_normal(normal, src_oldvert, src_newvert)); - - dst_vert[0] = - src_oldvert->pos[0] * oldscale[0] + - src_newvert->pos[0] * newscale[0] + translate[0]; - dst_vert[1] = - src_oldvert->pos[1] * oldscale[1] + - src_newvert->pos[1] * newscale[1] + translate[1]; - dst_vert[2] = - src_oldvert->pos[2] * oldscale[2] + - src_newvert->pos[2] * newscale[2] + translate[2]; - dst_vert[4] = shadelight[0] * d; - dst_vert[5] = shadelight[1] * d; - dst_vert[6] = shadelight[2] * d; - dst_vert[7] = shadelight[3]; - dst_vert += VERTEX_SIZE; + get_lerped_normal(t, normal, src_oldvert, src_newvert); + d = shadedot(t, normal); + + VectorCopy(t->translate, dst_vert); + VectorVectorScaleAcc(src_oldvert->pos, t->oldscale, dst_vert); + VectorVectorScaleAcc(src_newvert->pos, t->newscale, dst_vert); + + Vector4Copy(t->shadelight, dst_vert + 4); + VectorScale(dst_vert + 4, d, dst_vert + 4); + dst_vert += VERTEX_SIZE; src_oldvert++; src_newvert++; } } -static void tess_lerped_plain(const maliasmesh_t *mesh) +static void tess_lerped_plain(const tess_info_t *t, + const maliasmesh_t *mesh) { - maliasvert_t *src_oldvert = &mesh->verts[oldframenum * mesh->numverts]; - maliasvert_t *src_newvert = &mesh->verts[newframenum * mesh->numverts]; + maliasvert_t *src_oldvert = &mesh->verts[t->oldframenum * mesh->numverts]; + maliasvert_t *src_newvert = &mesh->verts[t->newframenum * mesh->numverts]; vec_t *dst_vert = tess.vertices; int count = mesh->numverts; while (count--) { - dst_vert[0] = - src_oldvert->pos[0] * oldscale[0] + - src_newvert->pos[0] * newscale[0] + translate[0]; - dst_vert[1] = - src_oldvert->pos[1] * oldscale[1] + - src_newvert->pos[1] * newscale[1] + translate[1]; - dst_vert[2] = - src_oldvert->pos[2] * oldscale[2] + - src_newvert->pos[2] * newscale[2] + translate[2]; - dst_vert += 4; + VectorCopy(t->translate, dst_vert); + VectorVectorScaleAcc(src_oldvert->pos, t->oldscale, dst_vert); + VectorVectorScaleAcc(src_newvert->pos, t->newscale, dst_vert); + dst_vert += 4; src_oldvert++; src_newvert++; } } -static glCullResult_t cull_static_model(model_t *model) +static glCullResult_t cull_static_model(tess_info_t *t, const model_t *model) { - maliasframe_t *newframe = &model->frames[newframenum]; + maliasframe_t *newframe = &model->frames[t->newframenum]; vec3_t bounds[2]; glCullResult_t cull; if (glr.entrotated) { - cull = GL_CullSphere(origin, newframe->radius); + cull = GL_CullSphere(t->origin, newframe->radius); if (cull == CULL_OUT) { c.spheresCulled++; return cull; } if (cull == CULL_CLIP) { - cull = GL_CullLocalBox(origin, newframe->bounds); + cull = GL_CullLocalBox(t->origin, newframe->bounds); if (cull == CULL_OUT) { c.rotatedBoxesCulled++; return cull; } } } else { - VectorAdd(newframe->bounds[0], origin, bounds[0]); - VectorAdd(newframe->bounds[1], origin, bounds[1]); + VectorAdd(newframe->bounds[0], t->origin, bounds[0]); + VectorAdd(newframe->bounds[1], t->origin, bounds[1]); cull = GL_CullBox(bounds); if (cull == CULL_OUT) { c.boxesCulled++; @@ -282,31 +265,30 @@ static glCullResult_t cull_static_model(model_t *model) } } - VectorCopy(newframe->scale, newscale); - VectorCopy(newframe->translate, translate); + VectorCopy(newframe->scale, t->newscale); + VectorCopy(newframe->translate, t->translate); return cull; } -static glCullResult_t cull_lerped_model(model_t *model) +static glCullResult_t cull_lerped_model(tess_info_t *t, const model_t *model) { - maliasframe_t *newframe = &model->frames[newframenum]; - maliasframe_t *oldframe = &model->frames[oldframenum]; + maliasframe_t *newframe = &model->frames[t->newframenum]; + maliasframe_t *oldframe = &model->frames[t->oldframenum]; vec3_t bounds[2]; vec_t radius; glCullResult_t cull; if (glr.entrotated) { - radius = newframe->radius > oldframe->radius ? - newframe->radius : oldframe->radius; - cull = GL_CullSphere(origin, radius); + radius = max(newframe->radius, oldframe->radius); + cull = GL_CullSphere(t->origin, radius); if (cull == CULL_OUT) { c.spheresCulled++; return cull; } UnionBounds(newframe->bounds, oldframe->bounds, bounds); if (cull == CULL_CLIP) { - cull = GL_CullLocalBox(origin, bounds); + cull = GL_CullLocalBox(t->origin, bounds); if (cull == CULL_OUT) { c.rotatedBoxesCulled++; return cull; @@ -314,8 +296,8 @@ static glCullResult_t cull_lerped_model(model_t *model) } } else { UnionBounds(newframe->bounds, oldframe->bounds, bounds); - VectorAdd(bounds[0], origin, bounds[0]); - VectorAdd(bounds[1], origin, bounds[1]); + VectorAdd(bounds[0], t->origin, bounds[0]); + VectorAdd(bounds[1], t->origin, bounds[1]); cull = GL_CullBox(bounds); if (cull == CULL_OUT) { c.boxesCulled++; @@ -323,127 +305,122 @@ static glCullResult_t cull_lerped_model(model_t *model) } } - VectorScale(oldframe->scale, backlerp, oldscale); - VectorScale(newframe->scale, frontlerp, newscale); + VectorScale(oldframe->scale, t->backlerp, t->oldscale); + VectorScale(newframe->scale, t->frontlerp, t->newscale); LerpVector2(oldframe->translate, newframe->translate, - backlerp, frontlerp, translate); + t->backlerp, t->frontlerp, t->translate); return cull; } -static void setup_color(void) +/* sets t->color */ +static void setup_color(tess_info_t *t) { int flags = glr.ent->flags; float f, m; int i; - memset(&glr.lightpoint, 0, sizeof(glr.lightpoint)); - if (flags & RF_SHELL_MASK) { - VectorClear(color); - if (flags & RF_SHELL_HALF_DAM) { - color[0] = 0.56f; - color[1] = 0.59f; - color[2] = 0.45f; - } + VectorClear(t->color); + + if (flags & RF_SHELL_HALF_DAM) + VectorSet(t->color, 0.56f, 0.59f, 0.45f); + if (flags & RF_SHELL_DOUBLE) { - color[0] = 0.9f; - color[1] = 0.7f; - } - if (flags & RF_SHELL_RED) { - color[0] = 1; - } - if (flags & RF_SHELL_GREEN) { - color[1] = 1; - } - if (flags & RF_SHELL_BLUE) { - color[2] = 1; + t->color[0] = 0.9f; + t->color[1] = 0.7f; } + + if (flags & RF_SHELL_RED) + t->color[0] = 1; + + if (flags & RF_SHELL_GREEN) + t->color[1] = 1; + + if (flags & RF_SHELL_BLUE) + t->color[2] = 1; } else if (flags & RF_FULLBRIGHT) { - VectorSet(color, 1, 1, 1); + VectorSet(t->color, 1, 1, 1); } else if ((flags & RF_IR_VISIBLE) && (glr.fd.rdflags & RDF_IRGOGGLES)) { - VectorSet(color, 1, 0, 0); + VectorSet(t->color, 1, 0, 0); } else { - GL_LightPoint(origin, color); + GL_LightPoint(t->origin, t->color); if (flags & RF_MINLIGHT) { for (i = 0; i < 3; i++) { - if (color[i] > 0.1f) { + if (t->color[i] <= 0.1f) { + VectorSet(t->color, 0.1f, 0.1f, 0.1f); break; } } - if (i == 3) { - VectorSet(color, 0.1f, 0.1f, 0.1f); - } } if (flags & RF_GLOW) { f = 0.1f * sin(glr.fd.time * 7); + for (i = 0; i < 3; i++) { - m = color[i] * 0.8f; - color[i] += f; - if (color[i] < m) - color[i] = m; + m = t->color[i] * 0.8f; + t->color[i] += f; + if (t->color[i] < m) + t->color[i] = m; } } - for (i = 0; i < 3; i++) { - clamp(color[i], 0, 1); - } + for (i = 0; i < 3; i++) + clamp(t->color[i], 0, 1); } if (flags & RF_TRANSLUCENT) { - color[3] = glr.ent->alpha; + t->color[3] = glr.ent->alpha; } else { - color[3] = 1; + t->color[3] = 1; } } -static void setup_celshading(void) +/* sets t->celscale */ +static void setup_celshading(tess_info_t *t) { float value = Cvar_ClampValue(gl_celshading, 0, 10); vec3_t dir; - celscale = 0; - if (value == 0) return; if (glr.ent->flags & (RF_TRANSLUCENT | RF_SHELL_MASK)) return; - VectorSubtract(origin, glr.fd.vieworg, dir); - celscale = 1.0f - VectorLength(dir) / 700.0f; + VectorSubtract(t->origin, glr.fd.vieworg, dir); + t->celscale = 1.0f - VectorLength(dir) / 700.0f; } -static void draw_celshading(maliasmesh_t *mesh) +static void draw_celshading(const tess_info_t *t, const maliasmesh_t *mesh) { - if (celscale < 0.01f || celscale > 1) + if (t->celscale < 0.01f || t->celscale > 1) return; GL_BindTexture(0, TEXNUM_BLACK); GL_StateBits(GLS_BLEND_BLEND); GL_ArrayBits(GLA_VERTEX); - qglLineWidth(gl_celshading->value * celscale); + qglLineWidth(gl_celshading->value * t->celscale); qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); qglCullFace(GL_FRONT); - qglColor4f(0, 0, 0, color[3] * celscale); - qglDrawElements(GL_TRIANGLES, mesh->numindices, QGL_INDEX_ENUM, - mesh->indices); + qglColor4f(0, 0, 0, t->color[3] * t->celscale); + qglDrawElements(GL_TRIANGLES, mesh->numindices, + QGL_INDEX_ENUM, mesh->indices); qglCullFace(GL_BACK); qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); qglLineWidth(1); } -static void setup_shadow(void) +static void setup_shadow(tess_info_t *t) { mat4_t m, tmp; cplane_t *plane; vec3_t dir; - shadowmatrix.i[3][3] = 0; + t->shadowmatrix.i[3][3] = 0; if (!gl_shadows->integer) return; @@ -487,17 +464,17 @@ static void setup_shadow(void) tmp = mul_mat4(&glr.viewmatrix, &m); // rotate for entity - m = AffineMatrix(glr.entaxis, origin); - shadowmatrix = mul_mat4(&tmp, &m); + m = AffineMatrix(glr.entaxis, t->origin); + t->shadowmatrix = mul_mat4(&tmp, &m); } -static void draw_shadow(maliasmesh_t *mesh) +static void draw_shadow(const tess_info_t *t, const maliasmesh_t *mesh) { - if (shadowmatrix.i[3][3] < 0.5f) + if (t->shadowmatrix.i[3][3] < 0.5f) return; // load shadow projection matrix - GL_LoadMatrix(&shadowmatrix); + GL_LoadMatrix(&t->shadowmatrix); // eliminate z-fighting by utilizing stencil buffer, if available if (gl_config.stencilbits) { @@ -512,7 +489,7 @@ static void draw_shadow(maliasmesh_t *mesh) qglEnable(GL_POLYGON_OFFSET_FILL); qglPolygonOffset(-1.0f, -2.0f); - qglColor4f(0, 0, 0, color[3] * 0.5f); + qglColor4f(0, 0, 0, t->color[3] * 0.5f); qglDrawElements(GL_TRIANGLES, mesh->numindices, QGL_INDEX_ENUM, mesh->indices); qglDisable(GL_POLYGON_OFFSET_FILL); @@ -526,7 +503,7 @@ static void draw_shadow(maliasmesh_t *mesh) } } -static int texnum_for_mesh(maliasmesh_t *mesh) +static int texnum_for_mesh(const maliasmesh_t *mesh) { entity_t *ent = glr.ent; @@ -550,14 +527,18 @@ static int texnum_for_mesh(maliasmesh_t *mesh) return mesh->skins[ent->skinnum]->texnum; } -static void draw_alias_mesh(maliasmesh_t *mesh) +typedef void (*tessfunc_t)(const tess_info_t *, const maliasmesh_t *); + +static void draw_alias_mesh(const tess_info_t *t, + tessfunc_t tessfunc, + const maliasmesh_t *mesh) { glStateBits_t state = GLS_DEFAULT; // fall back to entity matrix GL_LoadMatrix(&glr.entmatrix); - if (shadelight) + if (t->shadelight) state |= GLS_SHADE_SMOOTH; if (glr.ent->flags & RF_TRANSLUCENT) @@ -567,27 +548,27 @@ static void draw_alias_mesh(maliasmesh_t *mesh) GL_BindTexture(0, texnum_for_mesh(mesh)); - (*tessfunc)(mesh); + tessfunc(t, mesh); c.trisDrawn += mesh->numtris; - if (shadelight) { + if (t->shadelight) { GL_ArrayBits(GLA_VERTEX | GLA_TC | GLA_COLOR); GL_VertexPointer(3, VERTEX_SIZE, tess.vertices); GL_ColorFloatPointer(4, VERTEX_SIZE, tess.vertices + 4); } else { GL_ArrayBits(GLA_VERTEX | GLA_TC); GL_VertexPointer(3, 4, tess.vertices); - qglColor4fv(color); + qglColor4fv(t->color); } - GL_TexCoordPointer(2, 0, (GLfloat *)mesh->tcoords); + GL_TexCoordPointer(2, 0, (GLfloat *) mesh->tcoords); GL_LockArrays(mesh->numverts); qglDrawElements(GL_TRIANGLES, mesh->numindices, QGL_INDEX_ENUM, mesh->indices); - draw_celshading(mesh); + draw_celshading(t, mesh); if (gl_showtris->integer) { GL_EnableOutlines(); @@ -597,7 +578,7 @@ static void draw_alias_mesh(maliasmesh_t *mesh) } // FIXME: unlock arrays before changing matrix? - draw_shadow(mesh); + draw_shadow(t, mesh); GL_UnlockArrays(); } @@ -605,64 +586,77 @@ static void draw_alias_mesh(maliasmesh_t *mesh) void GL_DrawAliasModel(model_t *model) { entity_t *ent = glr.ent; + tessfunc_t tessfunc; glCullResult_t cull; - int i; - - newframenum = ent->frame; - if (newframenum < 0 || newframenum >= model->numframes) { - Com_DPrintf("%s: no such frame %d\n", __func__, newframenum); - newframenum = 0; + int i, do_lerp; + + tess_info_t t = { + .oldframenum = ent->oldframe, + .newframenum = ent->frame, + .frontlerp = 1.0f - ent->backlerp, + .backlerp = ent->backlerp, + + .shadelight = NULL, + .celscale = 0, + }; + +#if 0 + if (t.newframenum >= model->numframes) { + Com_DPrintf("%s: no such frame %d\n", __func__, t.newframenum); + t.newframenum = 0; } - oldframenum = ent->oldframe; - if (oldframenum < 0 || oldframenum >= model->numframes) { - Com_DPrintf("%s: no such oldframe %d\n", __func__, oldframenum); - oldframenum = 0; + if (t.oldframenum >= model->numframes) { + Com_DPrintf("%s: no such oldframe %d\n", __func__, t.oldframenum); + t.oldframenum = 0; } - - backlerp = ent->backlerp; - frontlerp = 1.0f - backlerp; +#else + assert(t.oldframenum <= model->numframes); + assert(t.newframenum <= model->numframes); +#endif // optimized case - if (backlerp == 0) - oldframenum = newframenum; + if (t.backlerp == 0) + t.oldframenum = t.newframenum; + + do_lerp = t.newframenum != t.oldframenum; // interpolate origin, if necessarry if (ent->flags & RF_FRAMELERP) LerpVector2(ent->oldorigin, ent->origin, - backlerp, frontlerp, origin); + t.backlerp, t.frontlerp, t.origin); else - VectorCopy(ent->origin, origin); + VectorCopy(ent->origin, t.origin); // cull the model, setup scale and translate vectors - if (newframenum == oldframenum) - cull = cull_static_model(model); - else - cull = cull_lerped_model(model); + cull = do_lerp + ? cull_lerped_model(&t, model) + : cull_static_model(&t, model); + if (cull == CULL_OUT) return; + memset(&glr.lightpoint, 0, sizeof(glr.lightpoint)); + // setup parameters common for all meshes - setup_color(); - setup_celshading(); - setup_dotshading(); - setup_shadow(); + setup_color(&t); + setup_celshading(&t); + setup_dotshading(&t); + setup_shadow(&t); // select proper tessfunc if (ent->flags & RF_SHELL_MASK) { - shellscale = (ent->flags & RF_WEAPONMODEL) ? + t.shellscale = (ent->flags & RF_WEAPONMODEL) ? WEAPONSHELL_SCALE : POWERSUIT_SCALE; - tessfunc = newframenum == oldframenum ? - tess_static_shell : tess_lerped_shell; - } else if (shadelight) { - tessfunc = newframenum == oldframenum ? - tess_static_shade : tess_lerped_shade; + + tessfunc = do_lerp ? tess_lerped_shell : tess_static_shell; + } else if (t.shadelight) { + tessfunc = do_lerp ? tess_lerped_shade : tess_static_shade; } else { - tessfunc = newframenum == oldframenum ? - tess_static_plain : tess_lerped_plain; + tessfunc = do_lerp ? tess_lerped_plain : tess_static_plain; } - GL_RotateForEntity(origin); + GL_RotateForEntity(t.origin); if ((ent->flags & (RF_WEAPONMODEL | RF_LEFTHAND)) == (RF_WEAPONMODEL | RF_LEFTHAND)) { @@ -677,7 +671,7 @@ void GL_DrawAliasModel(model_t *model) // draw all the meshes for (i = 0; i < model->nummeshes; i++) - draw_alias_mesh(&model->meshes[i]); + draw_alias_mesh(&t, tessfunc, &model->meshes[i]); if (ent->flags & RF_DEPTHHACK) qglDepthRange(0, 1); |