#include "quakedef.h"
-
-//cvar_t gl_transform = {0, "gl_transform", "1"};
-cvar_t gl_lockarrays = {0, "gl_lockarrays", "1"};
-
-typedef struct
-{
- float m[3][4];
-} zymbonematrix;
-
-// LordHavoc: vertex array
-float *aliasvert;
-float *aliasvertnorm;
-float *aliasvertcolor;
-float *aliasvertcolor2;
-zymbonematrix *zymbonepose;
-int *aliasvertusage;
-
-rmeshinfo_t aliasmeshinfo;
-
-rtexture_t *chrometexture;
-
-int arraylocked = false;
-void GL_LockArray(int first, int count)
-{
- if (gl_supportslockarrays && gl_lockarrays.integer)
- {
- qglLockArraysEXT(first, count);
- arraylocked = true;
- }
-}
-
-void GL_UnlockArray(void)
-{
- if (arraylocked)
- {
- qglUnlockArraysEXT();
- arraylocked = false;
- }
-}
-
-/*
-void GL_SetupModelTransform (vec3_t origin, vec3_t angles, vec_t scale)
-{
- glTranslatef (origin[0], origin[1], origin[2]);
-
- if (scale != 1)
- glScalef (scale, scale, scale);
- if (angles[1])
- glRotatef (angles[1], 0, 0, 1);
- if (angles[0])
- glRotatef (-angles[0], 0, 1, 0);
- if (angles[2])
- glRotatef (angles[2], 1, 0, 0);
-}
-*/
-
-rtexturepool_t *chrometexturepool;
-
-// currently unused reflection effect texture
-void makechrometexture(void)
-{
- int i;
- byte noise[64*64];
- byte data[64*64][4];
-
- fractalnoise(noise, 64, 8);
-
- // convert to RGBA data
- for (i = 0;i < 64*64;i++)
- {
- data[i][0] = data[i][1] = data[i][2] = noise[i];
- data[i][3] = 255;
- }
-
- chrometexture = R_LoadTexture (chrometexturepool, "chrometexture", 64, 64, &data[0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_PRECACHE);
-}
-
-mempool_t *gl_models_mempool;
-
-void gl_models_start(void)
-{
- // allocate vertex processing arrays
- gl_models_mempool = Mem_AllocPool("GL_Models");
- aliasvert = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][3]));
- aliasvertnorm = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][3]));
- aliasvertcolor = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4]));
- aliasvertcolor2 = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); // used temporarily for tinted coloring
- zymbonepose = Mem_Alloc(gl_models_mempool, sizeof(zymbonematrix[256]));
- aliasvertusage = Mem_Alloc(gl_models_mempool, sizeof(int[MD2MAX_VERTS]));
- chrometexturepool = R_AllocTexturePool();
- makechrometexture();
-}
-
-void gl_models_shutdown(void)
-{
- R_FreeTexturePool(&chrometexturepool);
- Mem_FreePool(&gl_models_mempool);
-}
-
-void gl_models_newmap(void)
-{
-}
+#include "r_shadow.h"
void GL_Models_Init(void)
{
-// Cvar_RegisterVariable(&gl_transform);
- Cvar_RegisterVariable(&gl_lockarrays);
-
- R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown, gl_models_newmap);
}
-void R_AliasTransformVerts(int vertcount)
+static texture_t r_aliasnotexture;
+static texture_t *R_FetchAliasSkin(const entity_render_t *ent, const aliasmesh_t *mesh)
{
- vec3_t point;
- float *av, *avn;
- av = aliasvert;
- avn = aliasvertnorm;
- while (vertcount >= 4)
- {
- VectorCopy(av, point);softwaretransform(point, av);av += 3;
- VectorCopy(av, point);softwaretransform(point, av);av += 3;
- VectorCopy(av, point);softwaretransform(point, av);av += 3;
- VectorCopy(av, point);softwaretransform(point, av);av += 3;
- VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
- VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
- VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
- VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
- vertcount -= 4;
- }
- while(vertcount > 0)
+ model_t *model = ent->model;
+ if (model->numskins)
{
- VectorCopy(av, point);softwaretransform(point, av);av += 3;
- VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
- vertcount--;
- }
-}
-
-void R_AliasLerpVerts(int vertcount,
- float lerp1, trivertx_t *verts1, vec3_t fscale1, vec3_t translate1,
- float lerp2, trivertx_t *verts2, vec3_t fscale2, vec3_t translate2,
- float lerp3, trivertx_t *verts3, vec3_t fscale3, vec3_t translate3,
- float lerp4, trivertx_t *verts4, vec3_t fscale4, vec3_t translate4)
-{
- int i;
- vec3_t scale1, scale2, scale3, scale4, translate;
- float *n1, *n2, *n3, *n4;
- float *av, *avn;
- av = aliasvert;
- avn = aliasvertnorm;
- VectorScale(fscale1, lerp1, scale1);
- if (lerp2)
- {
- VectorScale(fscale2, lerp2, scale2);
- if (lerp3)
- {
- VectorScale(fscale3, lerp3, scale3);
- if (lerp4)
- {
- VectorScale(fscale4, lerp4, scale4);
- translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2 + translate3[0] * lerp3 + translate4[0] * lerp4;
- translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2 + translate3[1] * lerp3 + translate4[1] * lerp4;
- translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2 + translate3[2] * lerp3 + translate4[2] * lerp4;
- // generate vertices
- for (i = 0;i < vertcount;i++)
- {
- av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + verts3->v[0] * scale3[0] + verts4->v[0] * scale4[0] + translate[0];
- av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + verts3->v[1] * scale3[1] + verts4->v[1] * scale4[1] + translate[1];
- av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + verts3->v[2] * scale3[2] + verts4->v[2] * scale4[2] + translate[2];
- n1 = m_bytenormals[verts1->lightnormalindex];
- n2 = m_bytenormals[verts2->lightnormalindex];
- n3 = m_bytenormals[verts3->lightnormalindex];
- n4 = m_bytenormals[verts4->lightnormalindex];
- avn[0] = n1[0] * lerp1 + n2[0] * lerp2 + n3[0] * lerp3 + n4[0] * lerp4;
- avn[1] = n1[1] * lerp1 + n2[1] * lerp2 + n3[1] * lerp3 + n4[1] * lerp4;
- avn[2] = n1[2] * lerp1 + n2[2] * lerp2 + n3[2] * lerp3 + n4[2] * lerp4;
- av += 3;
- avn += 3;
- verts1++;verts2++;verts3++;verts4++;
- }
- }
- else
- {
- translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2 + translate3[0] * lerp3;
- translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2 + translate3[1] * lerp3;
- translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2 + translate3[2] * lerp3;
- // generate vertices
- for (i = 0;i < vertcount;i++)
- {
- av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + verts3->v[0] * scale3[0] + translate[0];
- av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + verts3->v[1] * scale3[1] + translate[1];
- av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + verts3->v[2] * scale3[2] + translate[2];
- n1 = m_bytenormals[verts1->lightnormalindex];
- n2 = m_bytenormals[verts2->lightnormalindex];
- n3 = m_bytenormals[verts3->lightnormalindex];
- avn[0] = n1[0] * lerp1 + n2[0] * lerp2 + n3[0] * lerp3;
- avn[1] = n1[1] * lerp1 + n2[1] * lerp2 + n3[1] * lerp3;
- avn[2] = n1[2] * lerp1 + n2[2] * lerp2 + n3[2] * lerp3;
- av += 3;
- avn += 3;
- verts1++;verts2++;verts3++;
- }
- }
- }
+ int s = ent->skinnum;
+ if ((unsigned int)s >= (unsigned int)model->numskins)
+ s = 0;
+ if (model->skinscenes[s].framecount > 1)
+ s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
else
- {
- translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2;
- translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2;
- translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2;
- // generate vertices
- for (i = 0;i < vertcount;i++)
- {
- av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + translate[0];
- av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + translate[1];
- av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + translate[2];
- n1 = m_bytenormals[verts1->lightnormalindex];
- n2 = m_bytenormals[verts2->lightnormalindex];
- avn[0] = n1[0] * lerp1 + n2[0] * lerp2;
- avn[1] = n1[1] * lerp1 + n2[1] * lerp2;
- avn[2] = n1[2] * lerp1 + n2[2] * lerp2;
- av += 3;
- avn += 3;
- verts1++;verts2++;
- }
- }
+ s = model->skinscenes[s].firstframe;
+ if (s >= mesh->num_skins)
+ s = 0;
+ return mesh->data_skins + s;
}
else
{
- translate[0] = translate1[0] * lerp1;
- translate[1] = translate1[1] * lerp1;
- translate[2] = translate1[2] * lerp1;
- // generate vertices
- if (lerp1 != 1)
- {
- // general but almost never used case
- for (i = 0;i < vertcount;i++)
- {
- av[0] = verts1->v[0] * scale1[0] + translate[0];
- av[1] = verts1->v[1] * scale1[1] + translate[1];
- av[2] = verts1->v[2] * scale1[2] + translate[2];
- n1 = m_bytenormals[verts1->lightnormalindex];
- avn[0] = n1[0] * lerp1;
- avn[1] = n1[1] * lerp1;
- avn[2] = n1[2] * lerp1;
- av += 3;
- avn += 3;
- verts1++;
- }
- }
- else
- {
- // fast normal case
- for (i = 0;i < vertcount;i++)
- {
- av[0] = verts1->v[0] * scale1[0] + translate[0];
- av[1] = verts1->v[1] * scale1[1] + translate[1];
- av[2] = verts1->v[2] * scale1[2] + translate[2];
- VectorCopy(m_bytenormals[verts1->lightnormalindex], avn);
- av += 3;
- avn += 3;
- verts1++;
- }
- }
+ memset(&r_aliasnotexture, 0, sizeof(r_aliasnotexture));
+ r_aliasnotexture.skin.base = r_texture_notexture;
+ return &r_aliasnotexture;
}
}
-void GL_DrawModelMesh(rtexture_t *skin, float *colors, float cred, float cgreen, float cblue)
-{
- aliasmeshinfo.tex[0] = R_GetTexture(skin);
- aliasmeshinfo.color = colors;
- if (colors == NULL)
- {
- aliasmeshinfo.cr = cred;
- aliasmeshinfo.cg = cgreen;
- aliasmeshinfo.cb = cblue;
- aliasmeshinfo.ca = currentrenderentity->alpha;
- }
-
- c_alias_polys += aliasmeshinfo.numtriangles;
- R_Mesh_Draw(&aliasmeshinfo);
-
- // leave it in a state for additional passes
- aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
- aliasmeshinfo.blendfunc2 = GL_ONE;
-}
-
-void R_TintModel(float *in, float *out, int verts, float r, float g, float b)
+static void R_DrawAliasModelCallback (const void *calldata1, int calldata2)
{
- int i;
- for (i = 0;i < verts;i++)
- {
- out[0] = in[0] * r;
- out[1] = in[1] * g;
- out[2] = in[2] * b;
- out[3] = in[3];
- in += 4;
- out += 4;
- }
-}
-
-void R_SetupMDLMD2Frames(skinframe_t **skinframe)
-{
- md2frame_t *frame1, *frame2, *frame3, *frame4;
- trivertx_t *frame1verts, *frame2verts, *frame3verts, *frame4verts;
- model_t *model;
- model = currentrenderentity->model;
-
- if (model->skinscenes[currentrenderentity->skinnum].framecount > 1)
- *skinframe = &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe + (int) (cl.time * 10) % model->skinscenes[currentrenderentity->skinnum].framecount];
- else
- *skinframe = &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe];
-
- softwaretransformforentity(currentrenderentity);
-
- frame1 = &model->mdlmd2data_frames[currentrenderentity->frameblend[0].frame];
- frame2 = &model->mdlmd2data_frames[currentrenderentity->frameblend[1].frame];
- frame3 = &model->mdlmd2data_frames[currentrenderentity->frameblend[2].frame];
- frame4 = &model->mdlmd2data_frames[currentrenderentity->frameblend[3].frame];
- frame1verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[0].frame * model->numverts];
- frame2verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[1].frame * model->numverts];
- frame3verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[2].frame * model->numverts];
- frame4verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[3].frame * model->numverts];
- /*
- if (currentrenderentity->frameblend[0].lerp)
- Con_Printf("frame1: %i/%i %s scale %f %f %f translate %f %f %f\n", currentrenderentity->frameblend[0].frame, model->numframes, frame1->name, frame1->scale[0], frame1->scale[1], frame1->scale[2], frame1->translate[0], frame1->translate[1], frame1->translate[2]);
- if (currentrenderentity->frameblend[1].lerp)
- Con_Printf("frame2: %i/%i %s scale %f %f %f translate %f %f %f\n", currentrenderentity->frameblend[0].frame, model->numframes, frame2->name, frame2->scale[0], frame2->scale[1], frame2->scale[2], frame2->translate[0], frame2->translate[1], frame2->translate[2]);
- if (currentrenderentity->frameblend[2].lerp)
- Con_Printf("frame3: %i/%i %s scale %f %f %f translate %f %f %f\n", currentrenderentity->frameblend[0].frame, model->numframes, frame3->name, frame3->scale[0], frame3->scale[1], frame3->scale[2], frame3->translate[0], frame3->translate[1], frame3->translate[2]);
- if (currentrenderentity->frameblend[3].lerp)
- Con_Printf("frame4: %i/%i %s scale %f %f %f translate %f %f %f\n", currentrenderentity->frameblend[0].frame, model->numframes, frame4->name, frame4->scale[0], frame4->scale[1], frame4->scale[2], frame4->translate[0], frame4->translate[1], frame4->translate[2]);
- */
- R_AliasLerpVerts(model->numverts,
- currentrenderentity->frameblend[0].lerp, frame1verts, frame1->scale, frame1->translate,
- currentrenderentity->frameblend[1].lerp, frame2verts, frame2->scale, frame2->translate,
- currentrenderentity->frameblend[2].lerp, frame3verts, frame3->scale, frame3->translate,
- currentrenderentity->frameblend[3].lerp, frame4verts, frame4->scale, frame4->translate);
- R_AliasTransformVerts(model->numverts);
-
- R_LightModel(model->numverts);
-}
-
-void R_DrawQ1AliasModel (void)
-{
- float fog;
+ int c, fbbase, fbpants, fbshirt, doglow;
+ float tint[3], fog, ifog, colorscale, ambientcolor4f[4], diffusecolor[3], diffusenormal[3], colorbase[3], colorpants[3], colorshirt[3];
+ float *vertex3f, *normal3f;
vec3_t diff;
- model_t *model;
- skinframe_t *skinframe;
-
- model = currentrenderentity->model;
+ qbyte *bcolor;
+ rmeshstate_t m;
+ const entity_render_t *ent = calldata1;
+ aliasmesh_t *mesh = ent->model->alias.aliasdata_meshes + calldata2;
+ texture_t *texture;
- R_SetupMDLMD2Frames(&skinframe);
-
- memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo));
-
- aliasmeshinfo.vertex = aliasvert;
- aliasmeshinfo.vertexstep = sizeof(float[3]);
- aliasmeshinfo.numverts = model->numverts;
- aliasmeshinfo.numtriangles = model->numtris;
- aliasmeshinfo.index = model->mdldata_indices;
- aliasmeshinfo.colorstep = sizeof(float[4]);
- aliasmeshinfo.texcoords[0] = model->mdldata_texcoords;
- aliasmeshinfo.texcoordstep[0] = sizeof(float[2]);
+ R_Mesh_Matrix(&ent->matrix);
fog = 0;
if (fogenabled)
{
- VectorSubtract(currentrenderentity->origin, r_origin, diff);
+ VectorSubtract(ent->origin, r_vieworigin, diff);
fog = DotProduct(diff,diff);
if (fog < 0.01f)
fog = 0.01f;
// 1. render model as normal, scaled by inverse of fog alpha (darkens it)
// 2. render fog as additive
}
+ ifog = 1 - fog;
+
+ VectorScale(ent->colormod, ifog, colorbase);
+ VectorClear(colorpants);
+ VectorClear(colorshirt);
+ fbbase = ent->effects & EF_FULLBRIGHT;
+ fbpants = fbbase;
+ fbshirt = fbbase;
+ if (ent->colormap >= 0)
+ {
+ // 128-224 are backwards ranges
+ c = (ent->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12;
+ if (c >= 224)
+ fbpants = true;
+ bcolor = (qbyte *) (&palette_complete[c]);
+ colorpants[0] = colorbase[0] * bcolor[0] * (1.0f / 255.0f);
+ colorpants[1] = colorbase[1] * bcolor[1] * (1.0f / 255.0f);
+ colorpants[2] = colorbase[2] * bcolor[2] * (1.0f / 255.0f);
+ // 128-224 are backwards ranges
+ c = (ent->colormap & 0xF0);c += (c >= 128 && c < 224) ? 4 : 12;
+ if (c >= 224)
+ fbshirt = true;
+ bcolor = (qbyte *) (&palette_complete[c]);
+ colorshirt[0] = colorbase[0] * bcolor[0] * (1.0f / 255.0f);
+ colorshirt[1] = colorbase[1] * bcolor[1] * (1.0f / 255.0f);
+ colorshirt[2] = colorbase[2] * bcolor[2] * (1.0f / 255.0f);
+ }
- if (currentrenderentity->effects & EF_ADDITIVE)
+ texture = R_FetchAliasSkin(ent, mesh);
+
+ if ((ent->effects & EF_ADDITIVE))
{
- aliasmeshinfo.transparent = true;
- aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
- aliasmeshinfo.blendfunc2 = GL_ONE;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
}
- else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL)
+ else if (texture->skin.fog || ent->alpha != 1.0)
{
- aliasmeshinfo.transparent = true;
- aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
- aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ GL_DepthMask(false);
}
else
{
- aliasmeshinfo.transparent = false;
- aliasmeshinfo.blendfunc1 = GL_ONE;
- aliasmeshinfo.blendfunc2 = GL_ZERO;
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
}
-
- // darken source
- if (fog)
- R_TintModel(aliasvertcolor, aliasvertcolor, model->numverts, 1 - fog, 1 - fog, 1 - fog);
-
- if (skinframe->base || skinframe->pants || skinframe->shirt || skinframe->glow || skinframe->merged)
+ GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
+ colorscale = 1.0f;
+ if (ent->frameblend[0].frame == 0 && ent->frameblend[0].lerp == 1)
{
- if (currentrenderentity->colormap >= 0 && (skinframe->base || skinframe->pants || skinframe->shirt))
- {
- int c;
- byte *color;
- if (skinframe->base)
- GL_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
- if (skinframe->pants)
- {
- c = (currentrenderentity->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
- color = (byte *) (&d_8to24table[c]);
- if (c >= 224) // fullbright ranges
- GL_DrawModelMesh(skinframe->pants, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
- else
- {
- R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
- GL_DrawModelMesh(skinframe->pants, aliasvertcolor2, 0, 0, 0);
- }
- }
- if (skinframe->shirt)
- {
- c = currentrenderentity->colormap & 0xF0 ;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
- color = (byte *) (&d_8to24table[c]);
- if (c >= 224) // fullbright ranges
- GL_DrawModelMesh(skinframe->shirt, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
- else
- {
- R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
- GL_DrawModelMesh(skinframe->shirt, aliasvertcolor2, 0, 0, 0);
- }
- }
- }
- else
- {
- if (skinframe->merged)
- GL_DrawModelMesh(skinframe->merged, aliasvertcolor, 0, 0, 0);
- else
- {
- if (skinframe->base) GL_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
- if (skinframe->pants) GL_DrawModelMesh(skinframe->pants, aliasvertcolor, 0, 0, 0);
- if (skinframe->shirt) GL_DrawModelMesh(skinframe->shirt, aliasvertcolor, 0, 0, 0);
- }
- }
- if (skinframe->glow) GL_DrawModelMesh(skinframe->glow, NULL, 1 - fog, 1 - fog, 1 - fog);
+ vertex3f = mesh->data_basevertex3f;
+ normal3f = mesh->data_basenormal3f;
}
else
- GL_DrawModelMesh(0, NULL, 1 - fog, 1 - fog, 1 - fog);
-
- if (fog)
{
- aliasmeshinfo.tex[0] = R_GetTexture(skinframe->fog);
- aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
- aliasmeshinfo.blendfunc2 = GL_ONE;
- aliasmeshinfo.color = NULL;
-
- aliasmeshinfo.cr = fogcolor[0];
- aliasmeshinfo.cg = fogcolor[1];
- aliasmeshinfo.cb = fogcolor[2];
- aliasmeshinfo.ca = currentrenderentity->alpha * fog;
-
- c_alias_polys += aliasmeshinfo.numtriangles;
- R_Mesh_Draw(&aliasmeshinfo);
+ vertex3f = varray_vertex3f;
+ Mod_Alias_GetMesh_Vertex3f(ent->model, ent->frameblend, mesh, vertex3f);
+ normal3f = NULL;
}
-}
-
-void R_DrawQ2AliasModel (void)
-{
- int *order, count;
- vec3_t diff;
- skinframe_t *skinframe;
- model_t *model;
-
- model = currentrenderentity->model;
-
- R_SetupMDLMD2Frames(&skinframe);
-
- if (!r_render.integer)
- return;
- // FIXME FIXME FIXME rewrite loader to convert to triangle mesh
- glBindTexture(GL_TEXTURE_2D, R_GetTexture(skinframe->base));
+ doglow = texture->skin.glow != NULL;
- if (currentrenderentity->effects & EF_ADDITIVE)
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = vertex3f;
+ m.pointer_texcoord[0] = mesh->data_texcoord2f;
+ if (gl_combine.integer)
{
- glBlendFunc(GL_SRC_ALPHA, GL_ONE); // additive rendering
- glEnable(GL_BLEND);
- glDepthMask(0);
+ colorscale *= 0.25f;
+ m.texrgbscale[0] = 4;
}
- else if (currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(skinframe->base))
+
+ m.tex[0] = R_GetTexture((ent->colormap >= 0 || !texture->skin.merged) ? texture->skin.base : texture->skin.merged);
+ VectorScale(colorbase, colorscale, tint);
+ m.pointer_color = NULL;
+ if (fbbase)
+ GL_Color(tint[0], tint[1], tint[2], ent->alpha);
+ else if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, tint[0], tint[1], tint[2], ent->alpha, false))
{
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glDepthMask(0);
+ m.pointer_color = varray_color4f;
+ if (normal3f == NULL)
+ {
+ normal3f = varray_normal3f;
+ Mod_BuildNormals(0, mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_element3i, normal3f);
+ }
+ R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, mesh->num_vertices, vertex3f, normal3f, varray_color4f);
}
else
+ GL_Color(ambientcolor4f[0], ambientcolor4f[1], ambientcolor4f[2], ambientcolor4f[3]);
+ if (gl_combine.integer && doglow)
{
- glDisable(GL_BLEND);
- glDepthMask(1);
+ doglow = false;
+ m.tex[1] = R_GetTexture(texture->skin.glow);
+ m.pointer_texcoord[1] = mesh->data_texcoord2f;
+ m.texcombinergb[1] = GL_ADD;
}
-
- // LordHavoc: big mess...
- // using vertex arrays only slightly, although it is enough to prevent duplicates
- // (saving half the transforms)
- glVertexPointer(3, GL_FLOAT, sizeof(float[3]), aliasvert);
- glColorPointer(4, GL_FLOAT, sizeof(float[4]), aliasvertcolor);
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_COLOR_ARRAY);
-
- GL_LockArray(0, model->numverts);
-
- order = model->md2data_glcmds;
- while(1)
+ R_Mesh_State(&m);
+ c_alias_polys += mesh->num_triangles;
+ GL_LockArrays(0, mesh->num_vertices);
+ R_Mesh_Draw(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i);
+ GL_LockArrays(0, 0);
+ m.tex[1] = 0;
+ m.pointer_texcoord[1] = NULL;
+ m.texcombinergb[1] = 0;
+
+ VectorScale(colorpants, colorscale, tint);
+ if (ent->colormap >= 0 && texture->skin.pants && VectorLength2(tint) >= 0.001)
{
- if (!(count = *order++))
- break;
- if (count > 0)
- glBegin(GL_TRIANGLE_STRIP);
- else
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ m.tex[0] = R_GetTexture(texture->skin.pants);
+ m.pointer_color = NULL;
+ if (fbpants)
+ GL_Color(tint[0], tint[1], tint[2], ent->alpha);
+ else if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, tint[0], tint[1], tint[2], ent->alpha, false))
{
- glBegin(GL_TRIANGLE_FAN);
- count = -count;
- }
- do
- {
- glTexCoord2f(((float *)order)[0], ((float *)order)[1]);
- glArrayElement(order[2]);
- order += 3;
+ m.pointer_color = varray_color4f;
+ if (normal3f == NULL)
+ {
+ normal3f = varray_normal3f;
+ Mod_BuildNormals(0, mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_element3i, normal3f);
+ }
+ R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, mesh->num_vertices, vertex3f, normal3f, varray_color4f);
}
- while (count--);
+ else
+ GL_Color(ambientcolor4f[0], ambientcolor4f[1], ambientcolor4f[2], ambientcolor4f[3]);
+ R_Mesh_State(&m);
+ c_alias_polys += mesh->num_triangles;
+ GL_LockArrays(0, mesh->num_vertices);
+ R_Mesh_Draw(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i);
+ GL_LockArrays(0, 0);
}
- GL_UnlockArray();
-
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_VERTEX_ARRAY);
-
- if (fogenabled)
+ VectorScale(colorshirt, colorscale, tint);
+ if (ent->colormap >= 0 && texture->skin.shirt && VectorLength2(tint) >= 0.001)
{
- glDisable (GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable (GL_BLEND);
- glDepthMask(0); // disable zbuffer updates
-
- VectorSubtract(currentrenderentity->origin, r_origin, diff);
- glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff)));
-
- // LordHavoc: big mess...
- // using vertex arrays only slightly, although it is enough to prevent duplicates
- // (saving half the transforms)
- glVertexPointer(3, GL_FLOAT, sizeof(float[3]), aliasvert);
- glEnableClientState(GL_VERTEX_ARRAY);
-
- GL_LockArray(0, model->numverts);
-
- order = model->md2data_glcmds;
- while(1)
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ m.tex[0] = R_GetTexture(texture->skin.shirt);
+ m.pointer_color = NULL;
+ if (fbshirt)
+ GL_Color(tint[0], tint[1], tint[2], ent->alpha);
+ else if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, tint[0], tint[1], tint[2], ent->alpha, false))
{
- if (!(count = *order++))
- break;
- if (count > 0)
- glBegin(GL_TRIANGLE_STRIP);
- else
- {
- glBegin(GL_TRIANGLE_FAN);
- count = -count;
- }
- do
+ m.pointer_color = varray_color4f;
+ if (normal3f == NULL)
{
- glArrayElement(order[2]);
- order += 3;
+ normal3f = varray_normal3f;
+ Mod_BuildNormals(0, mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_element3i, normal3f);
}
- while (count--);
+ R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, mesh->num_vertices, vertex3f, normal3f, varray_color4f);
}
+ else
+ GL_Color(ambientcolor4f[0], ambientcolor4f[1], ambientcolor4f[2], ambientcolor4f[3]);
+ R_Mesh_State(&m);
+ c_alias_polys += mesh->num_triangles;
+ GL_LockArrays(0, mesh->num_vertices);
+ R_Mesh_Draw(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i);
+ GL_LockArrays(0, 0);
+ }
- GL_UnlockArray();
-
- glDisableClientState(GL_VERTEX_ARRAY);
+ colorscale = 1;
+ m.texrgbscale[0] = 0;
- glEnable (GL_TEXTURE_2D);
- glColor3f (1,1,1);
+ if (texture->skin.glow)
+ {
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ m.tex[0] = R_GetTexture(texture->skin.glow);
+ m.pointer_color = NULL;
+ GL_Color(1, 1, 1, ent->alpha);
+ R_Mesh_State(&m);
+ c_alias_polys += mesh->num_triangles;
+ GL_LockArrays(0, mesh->num_vertices);
+ R_Mesh_Draw(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i);
+ GL_LockArrays(0, 0);
}
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable (GL_BLEND);
- glDepthMask(1);
+ if (fog > 0)
+ {
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ GL_DepthMask(false);
+ m.tex[0] = R_GetTexture(texture->skin.fog);
+ m.pointer_color = NULL;
+ GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], fog * ent->alpha);
+ R_Mesh_State(&m);
+ c_alias_polys += mesh->num_triangles;
+ GL_LockArrays(0, mesh->num_vertices);
+ R_Mesh_Draw(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i);
+ GL_LockArrays(0, 0);
+ }
}
-void ZymoticLerpBones(int count, zymbonematrix *bonebase, frameblend_t *blend, zymbone_t *bone, float rootorigin[3], float rootangles[3], float rootscale)
+void R_Model_Alias_Draw(entity_render_t *ent)
{
- float lerp1, lerp2, lerp3, lerp4;
- zymbonematrix *out, rootmatrix, m, *bone1, *bone2, *bone3, *bone4;
- out = zymbonepose;
- AngleVectors(rootangles, rootmatrix.m[0], rootmatrix.m[1], rootmatrix.m[2]);
- VectorScale(rootmatrix.m[0], rootscale, rootmatrix.m[0]);
- VectorScale(rootmatrix.m[1], rootscale, rootmatrix.m[1]);
- VectorScale(rootmatrix.m[2], rootscale, rootmatrix.m[2]);
- rootmatrix.m[0][3] = rootorigin[0];
- rootmatrix.m[1][3] = rootorigin[1];
- rootmatrix.m[2][3] = rootorigin[2];
- bone1 = bonebase + blend[0].frame * count;
- lerp1 = blend[0].lerp;
- if (blend[1].lerp)
- {
- bone2 = bonebase + blend[1].frame * count;
- lerp2 = blend[1].lerp;
- if (blend[2].lerp)
- {
- bone3 = bonebase + blend[2].frame * count;
- lerp3 = blend[2].lerp;
- if (blend[3].lerp)
- {
- // 4 poses
- bone4 = bonebase + blend[3].frame * count;
- lerp4 = blend[3].lerp;
- while(count--)
- {
- // interpolate matrices
- m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3 + bone4->m[0][0] * lerp4;
- m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3 + bone4->m[0][1] * lerp4;
- m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3 + bone4->m[0][2] * lerp4;
- m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3 + bone4->m[0][3] * lerp4;
- m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3 + bone4->m[1][0] * lerp4;
- m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3 + bone4->m[1][1] * lerp4;
- m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3 + bone4->m[1][2] * lerp4;
- m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3 + bone4->m[1][3] * lerp4;
- m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3 + bone4->m[2][0] * lerp4;
- m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3 + bone4->m[2][1] * lerp4;
- m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3 + bone4->m[2][2] * lerp4;
- m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3 + bone4->m[2][3] * lerp4;
- if (bone->parent >= 0)
- R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
- bone1++;
- bone2++;
- bone3++;
- bone4++;
- bone++;
- out++;
- }
- }
- else
- {
- // 3 poses
- while(count--)
- {
- // interpolate matrices
- m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3;
- m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3;
- m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3;
- m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3;
- m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3;
- m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3;
- m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3;
- m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3;
- m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3;
- m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3;
- m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3;
- m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3;
- if (bone->parent >= 0)
- R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
- bone1++;
- bone2++;
- bone3++;
- bone++;
- out++;
- }
- }
- }
- else
- {
- // 2 poses
- while(count--)
- {
- // interpolate matrices
- m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2;
- m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2;
- m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2;
- m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2;
- m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2;
- m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2;
- m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2;
- m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2;
- m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2;
- m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2;
- m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2;
- m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2;
- if (bone->parent >= 0)
- R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
- bone1++;
- bone2++;
- bone++;
- out++;
- }
- }
- }
- else
+ int meshnum;
+ aliasmesh_t *mesh;
+ if (ent->alpha < (1.0f / 64.0f))
+ return; // basically completely transparent
+
+ c_models++;
+
+ for (meshnum = 0, mesh = ent->model->alias.aliasdata_meshes;meshnum < ent->model->alias.aliasnum_meshes;meshnum++, mesh++)
{
- // 1 pose
- if (lerp1 != 1)
- {
- // lerp != 1.0
- while(count--)
- {
- // interpolate matrices
- m.m[0][0] = bone1->m[0][0] * lerp1;
- m.m[0][1] = bone1->m[0][1] * lerp1;
- m.m[0][2] = bone1->m[0][2] * lerp1;
- m.m[0][3] = bone1->m[0][3] * lerp1;
- m.m[1][0] = bone1->m[1][0] * lerp1;
- m.m[1][1] = bone1->m[1][1] * lerp1;
- m.m[1][2] = bone1->m[1][2] * lerp1;
- m.m[1][3] = bone1->m[1][3] * lerp1;
- m.m[2][0] = bone1->m[2][0] * lerp1;
- m.m[2][1] = bone1->m[2][1] * lerp1;
- m.m[2][2] = bone1->m[2][2] * lerp1;
- m.m[2][3] = bone1->m[2][3] * lerp1;
- if (bone->parent >= 0)
- R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
- bone1++;
- bone++;
- out++;
- }
- }
+ if (ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || R_FetchAliasSkin(ent, mesh)->skin.fog)
+ R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawAliasModelCallback, ent, meshnum);
else
- {
- // lerp == 1.0
- while(count--)
- {
- if (bone->parent >= 0)
- R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &bone1->m[0], &out->m[0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0], &bone1->m[0], &out->m[0]);
- bone1++;
- bone++;
- out++;
- }
- }
+ R_DrawAliasModelCallback(ent, meshnum);
}
}
-void ZymoticTransformVerts(int vertcount, int *bonecounts, zymvertex_t *vert)
+void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist, const vec3_t lightmins, const vec3_t lightmaxs)
{
- int c;
- float *out = aliasvert;
- zymbonematrix *matrix;
- while(vertcount--)
+ int meshnum;
+ aliasmesh_t *mesh;
+ texture_t *texture;
+ float projectdistance, *vertex3f;
+ if (!(ent->flags & RENDER_SHADOW))
+ return;
+ // check the box in modelspace, it was already checked in worldspace
+ if (!BoxesOverlap(ent->model->normalmins, ent->model->normalmaxs, lightmins, lightmaxs))
+ return;
+ projectdistance = lightradius + ent->model->radius;// - sqrt(DotProduct(relativelightorigin, relativelightorigin));
+ if (projectdistance > 0.1)
{
- c = *bonecounts++;
- // FIXME: validate bonecounts at load time (must be >= 1)
- if (c == 1)
+ R_Mesh_Matrix(&ent->matrix);
+ for (meshnum = 0, mesh = ent->model->alias.aliasdata_meshes;meshnum < ent->model->alias.aliasnum_meshes;meshnum++, mesh++)
{
- matrix = &zymbonepose[vert->bonenum];
- out[0] = vert->origin[0] * matrix->m[0][0] + vert->origin[1] * matrix->m[0][1] + vert->origin[2] * matrix->m[0][2] + matrix->m[0][3];
- out[1] = vert->origin[0] * matrix->m[1][0] + vert->origin[1] * matrix->m[1][1] + vert->origin[2] * matrix->m[1][2] + matrix->m[1][3];
- out[2] = vert->origin[0] * matrix->m[2][0] + vert->origin[1] * matrix->m[2][1] + vert->origin[2] * matrix->m[2][2] + matrix->m[2][3];
- vert++;
- }
- else
- {
- VectorClear(out);
- while(c--)
+ texture = R_FetchAliasSkin(ent, mesh);
+ if (texture->skin.fog)
+ continue;
+ if (ent->frameblend[0].frame == 0 && ent->frameblend[0].lerp == 1)
+ vertex3f = mesh->data_basevertex3f;
+ else
{
- matrix = &zymbonepose[vert->bonenum];
- out[0] += vert->origin[0] * matrix->m[0][0] + vert->origin[1] * matrix->m[0][1] + vert->origin[2] * matrix->m[0][2] + matrix->m[0][3];
- out[1] += vert->origin[0] * matrix->m[1][0] + vert->origin[1] * matrix->m[1][1] + vert->origin[2] * matrix->m[1][2] + matrix->m[1][3];
- out[2] += vert->origin[0] * matrix->m[2][0] + vert->origin[1] * matrix->m[2][1] + vert->origin[2] * matrix->m[2][2] + matrix->m[2][3];
- vert++;
+ vertex3f = varray_vertex3f;
+ Mod_Alias_GetMesh_Vertex3f(ent->model, ent->frameblend, mesh, vertex3f);
}
+ // identify lit faces within the bounding box
+ R_Shadow_PrepareShadowMark(mesh->num_triangles);
+ R_Shadow_MarkVolumeFromBox(0, mesh->num_triangles, vertex3f, mesh->data_element3i, relativelightorigin, lightmins, lightmaxs, ent->model->normalmins, ent->model->normalmaxs);
+ R_Shadow_VolumeFromList(mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_element3i, mesh->data_neighbor3i, relativelightorigin, projectdistance, numshadowmark, shadowmarklist);
}
- out += 3;
}
}
-void ZymoticCalcNormals(int vertcount, int shadercount, int *renderlist)
+void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int numsurfaces, const int *surfacelist)
{
- int a, b, c, d;
- float *out, v1[3], v2[3], normal[3];
- int *u;
- // clear normals
- memset(aliasvertnorm, 0, sizeof(float[3]) * vertcount);
- memset(aliasvertusage, 0, sizeof(int) * vertcount);
- // parse render list and accumulate surface normals
- while(shadercount--)
+ int c, meshnum;
+ float fog, ifog, lightcolorbase[3], lightcolorpants[3], lightcolorshirt[3];
+ float *vertex3f, *svector3f, *tvector3f, *normal3f;
+ vec3_t diff;
+ qbyte *bcolor;
+ aliasmesh_t *mesh;
+ texture_t *texture;
+
+ R_Mesh_Matrix(&ent->matrix);
+
+ fog = 0;
+ if (fogenabled)
{
- d = *renderlist++;
- while (d--)
- {
- a = renderlist[0]*3;
- b = renderlist[1]*3;
- c = renderlist[2]*3;
- v1[0] = aliasvert[a+0] - aliasvert[b+0];
- v1[1] = aliasvert[a+1] - aliasvert[b+1];
- v1[2] = aliasvert[a+2] - aliasvert[b+2];
- v2[0] = aliasvert[c+0] - aliasvert[b+0];
- v2[1] = aliasvert[c+1] - aliasvert[b+1];
- v2[2] = aliasvert[c+2] - aliasvert[b+2];
- CrossProduct(v1, v2, normal);
- VectorNormalizeFast(normal);
- // add surface normal to vertices
- aliasvertnorm[a+0] += normal[0];
- aliasvertnorm[a+1] += normal[1];
- aliasvertnorm[a+2] += normal[2];
- aliasvertusage[a]++;
- aliasvertnorm[b+0] += normal[0];
- aliasvertnorm[b+1] += normal[1];
- aliasvertnorm[b+2] += normal[2];
- aliasvertusage[b]++;
- aliasvertnorm[c+0] += normal[0];
- aliasvertnorm[c+1] += normal[1];
- aliasvertnorm[c+2] += normal[2];
- aliasvertusage[c]++;
- renderlist += 3;
- }
+ VectorSubtract(ent->origin, r_vieworigin, diff);
+ fog = DotProduct(diff,diff);
+ if (fog < 0.01f)
+ fog = 0.01f;
+ fog = exp(fogdensity/fog);
+ if (fog > 1)
+ fog = 1;
+ if (fog < 0.01f)
+ fog = 0;
+ // fog method: darken, additive fog
+ // 1. render model as normal, scaled by inverse of fog alpha (darkens it)
+ // 2. render fog as additive
}
- // average surface normals
- out = aliasvertnorm;
- u = aliasvertusage;
- while(vertcount--)
+ ifog = 1 - fog;
+
+ VectorScale(lightcolor, ifog, lightcolorbase);
+ if (VectorLength2(lightcolorbase) < 0.001)
+ return;
+ VectorClear(lightcolorpants);
+ VectorClear(lightcolorshirt);
+ if (ent->colormap >= 0)
{
- if (*u > 1)
+ // 128-224 are backwards ranges
+ c = (ent->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12;
+ // fullbright passes were already taken care of, so skip them in realtime lighting passes
+ if (c < 224)
+ {
+ bcolor = (qbyte *) (&palette_complete[c]);
+ lightcolorpants[0] = lightcolorbase[0] * bcolor[0] * (1.0f / 255.0f);
+ lightcolorpants[1] = lightcolorbase[1] * bcolor[1] * (1.0f / 255.0f);
+ lightcolorpants[2] = lightcolorbase[2] * bcolor[2] * (1.0f / 255.0f);
+ }
+ // 128-224 are backwards ranges
+ c = (ent->colormap & 0xF0);c += (c >= 128 && c < 224) ? 4 : 12;
+ // fullbright passes were already taken care of, so skip them in realtime lighting passes
+ if (c < 224)
{
- a = ixtable[*u];
- out[0] *= a;
- out[1] *= a;
- out[2] *= a;
+ bcolor = (qbyte *) (&palette_complete[c]);
+ lightcolorshirt[0] = lightcolorbase[0] * bcolor[0] * (1.0f / 255.0f);
+ lightcolorshirt[1] = lightcolorbase[1] * bcolor[1] * (1.0f / 255.0f);
+ lightcolorshirt[2] = lightcolorbase[2] * bcolor[2] * (1.0f / 255.0f);
}
- u++;
- out += 3;
}
-}
-
-void GL_DrawZymoticModelMesh(zymtype1header_t *m)
-{
- int i, *renderlist;
- rtexture_t **texture;
-
- // FIXME: do better fog
- renderlist = (int *)(m->lump_render.start + (int) m);
- texture = (rtexture_t **)(m->lump_shaders.start + (int) m);
- aliasmeshinfo.vertex = aliasvert;
- aliasmeshinfo.vertexstep = sizeof(float[3]);
- aliasmeshinfo.color = aliasvertcolor;
- aliasmeshinfo.colorstep = sizeof(float[4]);
- aliasmeshinfo.texcoords[0] = (float *)(m->lump_texcoords.start + (int) m);
- aliasmeshinfo.texcoordstep[0] = sizeof(float[2]);
-
- for (i = 0;i < m->numshaders;i++)
+ for (meshnum = 0, mesh = ent->model->alias.aliasdata_meshes;meshnum < ent->model->alias.aliasnum_meshes;meshnum++, mesh++)
{
- aliasmeshinfo.tex[0] = R_GetTexture(*texture);
- aliasmeshinfo.tex[1] = 0;
- if (currentrenderentity->effects & EF_ADDITIVE)
+ texture = R_FetchAliasSkin(ent, mesh);
+ // FIXME: transparent skins need to be lit during the transparent render
+ if (texture->skin.fog)
+ continue;
+ if (ent->frameblend[0].frame == 0 && ent->frameblend[0].lerp == 1)
{
- aliasmeshinfo.transparent = true;
- aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
- aliasmeshinfo.blendfunc2 = GL_ONE;
+ vertex3f = mesh->data_basevertex3f;
+ svector3f = mesh->data_basesvector3f;
+ tvector3f = mesh->data_basetvector3f;
+ normal3f = mesh->data_basenormal3f;
}
- else if (currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(*texture))
+ else
{
- aliasmeshinfo.transparent = true;
- aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
- aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
+ vertex3f = varray_vertex3f;
+ svector3f = varray_svector3f;
+ tvector3f = varray_tvector3f;
+ normal3f = varray_normal3f;
+ Mod_Alias_GetMesh_Vertex3f(ent->model, ent->frameblend, mesh, vertex3f);
+ Mod_BuildTextureVectorsAndNormals(0, mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_texcoord2f, mesh->data_element3i, svector3f, tvector3f, normal3f);
}
- else
+ c_alias_polys += mesh->num_triangles;
+ R_Shadow_RenderLighting(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, vertex3f, svector3f, tvector3f, normal3f, mesh->data_texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorbase, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, (ent->colormap >= 0 || !texture->skin.merged) ? texture->skin.base : texture->skin.merged, texture->skin.nmap, texture->skin.gloss, lightcubemap, ambientscale, diffusescale, specularscale);
+ if (ent->colormap >= 0)
{
- aliasmeshinfo.transparent = false;
- aliasmeshinfo.blendfunc1 = GL_ONE;
- aliasmeshinfo.blendfunc2 = GL_ZERO;
+ if (texture->skin.pants && VectorLength2(lightcolorpants) >= 0.001)
+ R_Shadow_RenderLighting(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, vertex3f, svector3f, tvector3f, normal3f, mesh->data_texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorpants, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, texture->skin.pants, texture->skin.nmap, NULL, lightcubemap, ambientscale, diffusescale, 0);
+ if (texture->skin.shirt && VectorLength2(lightcolorshirt) >= 0.001)
+ R_Shadow_RenderLighting(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, vertex3f, svector3f, tvector3f, normal3f, mesh->data_texcoord2f, relativelightorigin, relativeeyeorigin, lightcolorshirt, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, texture->skin.shirt, texture->skin.nmap, NULL, lightcubemap, ambientscale, diffusescale, 0);
}
- aliasmeshinfo.numtriangles = *renderlist++;
- aliasmeshinfo.index = renderlist;
- c_alias_polys += aliasmeshinfo.numtriangles;
- R_Mesh_Draw(&aliasmeshinfo);
- renderlist += aliasmeshinfo.numtriangles * 3;
}
}
-void GL_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m)
-{
- int i, *renderlist;
- vec3_t diff;
-
- // FIXME: do better fog
- renderlist = (int *)(m->lump_render.start + (int) m);
-
- aliasmeshinfo.tex[0] = 0;
- aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
- aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
-
- VectorSubtract(org, r_origin, diff);
- aliasmeshinfo.cr = fogcolor[0];
- aliasmeshinfo.cg = fogcolor[1];
- aliasmeshinfo.cb = fogcolor[2];
- aliasmeshinfo.ca = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff));
-
- for (i = 0;i < m->numshaders;i++)
- {
- aliasmeshinfo.numtriangles = *renderlist++;
- aliasmeshinfo.index = renderlist;
- c_alias_polys += aliasmeshinfo.numtriangles;
- R_Mesh_Draw(&aliasmeshinfo);
- renderlist += aliasmeshinfo.numtriangles * 3;
- }
-}
-
-void R_DrawZymoticModel (void)
-{
- zymtype1header_t *m;
-
- // FIXME: do better fog
- m = currentrenderentity->model->zymdata_header;
- ZymoticLerpBones(m->numbones, (zymbonematrix *)(m->lump_poses.start + (int) m), currentrenderentity->frameblend, (zymbone_t *)(m->lump_bones.start + (int) m), currentrenderentity->origin, currentrenderentity->angles, currentrenderentity->scale);
- ZymoticTransformVerts(m->numverts, (int *)(m->lump_vertbonecounts.start + (int) m), (zymvertex_t *)(m->lump_verts.start + (int) m));
- ZymoticCalcNormals(m->numverts, m->numshaders, (int *)(m->lump_render.start + (int) m));
-
- R_LightModel(m->numverts);
-
- memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo));
- aliasmeshinfo.numverts = m->numverts;
-
- GL_DrawZymoticModelMesh(m);
-
- if (fogenabled)
- GL_DrawZymoticModelMeshFog(currentrenderentity->origin, m);
-}
-
-void R_DrawAliasModel (void)
-{
- if (currentrenderentity->alpha < (1.0f / 64.0f))
- return; // basically completely transparent
-
- c_models++;
-
- if (currentrenderentity->model->aliastype == ALIASTYPE_ZYM)
- R_DrawZymoticModel ();
- else if (currentrenderentity->model->aliastype == ALIASTYPE_MD2)
- R_DrawQ2AliasModel ();
- else
- R_DrawQ1AliasModel ();
-}