4 //cvar_t gl_transform = {0, "gl_transform", "1"};
5 cvar_t gl_lockarrays = {0, "gl_lockarrays", "1"};
12 // LordHavoc: vertex array
15 float *aliasvertcolor;
16 float *aliasvertcolor2;
17 zymbonematrix *zymbonepose;
20 rmeshinfo_t aliasmeshinfo;
22 rtexture_t *chrometexture;
24 int arraylocked = false;
25 void GL_LockArray(int first, int count)
27 if (gl_supportslockarrays && gl_lockarrays.integer)
29 qglLockArraysEXT(first, count);
34 void GL_UnlockArray(void)
44 void GL_SetupModelTransform (vec3_t origin, vec3_t angles, vec_t scale)
46 glTranslatef (origin[0], origin[1], origin[2]);
49 glScalef (scale, scale, scale);
51 glRotatef (angles[1], 0, 0, 1);
53 glRotatef (-angles[0], 0, 1, 0);
55 glRotatef (angles[2], 1, 0, 0);
59 rtexturepool_t *chrometexturepool;
61 // currently unused reflection effect texture
62 void makechrometexture(void)
68 fractalnoise(noise, 64, 8);
70 // convert to RGBA data
71 for (i = 0;i < 64*64;i++)
73 data[i][0] = data[i][1] = data[i][2] = noise[i];
77 chrometexture = R_LoadTexture (chrometexturepool, "chrometexture", 64, 64, &data[0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_PRECACHE);
80 mempool_t *gl_models_mempool;
82 void gl_models_start(void)
84 // allocate vertex processing arrays
85 gl_models_mempool = Mem_AllocPool("GL_Models");
86 aliasvert = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4]));
87 aliasvertnorm = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][3]));
88 aliasvertcolor = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4]));
89 aliasvertcolor2 = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); // used temporarily for tinted coloring
90 zymbonepose = Mem_Alloc(gl_models_mempool, sizeof(zymbonematrix[256]));
91 aliasvertusage = Mem_Alloc(gl_models_mempool, sizeof(int[MD2MAX_VERTS]));
92 chrometexturepool = R_AllocTexturePool();
96 void gl_models_shutdown(void)
98 R_FreeTexturePool(&chrometexturepool);
99 Mem_FreePool(&gl_models_mempool);
102 void gl_models_newmap(void)
106 void GL_Models_Init(void)
108 // Cvar_RegisterVariable(&gl_transform);
109 Cvar_RegisterVariable(&gl_lockarrays);
111 R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown, gl_models_newmap);
114 void R_AliasTransformVerts(int vertcount)
120 while (vertcount >= 4)
122 VectorCopy(av, point);softwaretransform(point, av);av += 4;
123 VectorCopy(av, point);softwaretransform(point, av);av += 4;
124 VectorCopy(av, point);softwaretransform(point, av);av += 4;
125 VectorCopy(av, point);softwaretransform(point, av);av += 4;
126 VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
127 VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
128 VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
129 VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
134 VectorCopy(av, point);softwaretransform(point, av);av += 4;
135 VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
140 void R_AliasLerpVerts(int vertcount,
141 float lerp1, trivertx_t *verts1, vec3_t fscale1, vec3_t translate1,
142 float lerp2, trivertx_t *verts2, vec3_t fscale2, vec3_t translate2,
143 float lerp3, trivertx_t *verts3, vec3_t fscale3, vec3_t translate3,
144 float lerp4, trivertx_t *verts4, vec3_t fscale4, vec3_t translate4)
147 vec3_t scale1, scale2, scale3, scale4, translate;
148 float *n1, *n2, *n3, *n4;
152 VectorScale(fscale1, lerp1, scale1);
155 VectorScale(fscale2, lerp2, scale2);
158 VectorScale(fscale3, lerp3, scale3);
161 VectorScale(fscale4, lerp4, scale4);
162 translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2 + translate3[0] * lerp3 + translate4[0] * lerp4;
163 translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2 + translate3[1] * lerp3 + translate4[1] * lerp4;
164 translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2 + translate3[2] * lerp3 + translate4[2] * lerp4;
166 for (i = 0;i < vertcount;i++)
168 av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + verts3->v[0] * scale3[0] + verts4->v[0] * scale4[0] + translate[0];
169 av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + verts3->v[1] * scale3[1] + verts4->v[1] * scale4[1] + translate[1];
170 av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + verts3->v[2] * scale3[2] + verts4->v[2] * scale4[2] + translate[2];
171 n1 = m_bytenormals[verts1->lightnormalindex];
172 n2 = m_bytenormals[verts2->lightnormalindex];
173 n3 = m_bytenormals[verts3->lightnormalindex];
174 n4 = m_bytenormals[verts4->lightnormalindex];
175 avn[0] = n1[0] * lerp1 + n2[0] * lerp2 + n3[0] * lerp3 + n4[0] * lerp4;
176 avn[1] = n1[1] * lerp1 + n2[1] * lerp2 + n3[1] * lerp3 + n4[1] * lerp4;
177 avn[2] = n1[2] * lerp1 + n2[2] * lerp2 + n3[2] * lerp3 + n4[2] * lerp4;
180 verts1++;verts2++;verts3++;verts4++;
185 translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2 + translate3[0] * lerp3;
186 translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2 + translate3[1] * lerp3;
187 translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2 + translate3[2] * lerp3;
189 for (i = 0;i < vertcount;i++)
191 av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + verts3->v[0] * scale3[0] + translate[0];
192 av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + verts3->v[1] * scale3[1] + translate[1];
193 av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + verts3->v[2] * scale3[2] + translate[2];
194 n1 = m_bytenormals[verts1->lightnormalindex];
195 n2 = m_bytenormals[verts2->lightnormalindex];
196 n3 = m_bytenormals[verts3->lightnormalindex];
197 avn[0] = n1[0] * lerp1 + n2[0] * lerp2 + n3[0] * lerp3;
198 avn[1] = n1[1] * lerp1 + n2[1] * lerp2 + n3[1] * lerp3;
199 avn[2] = n1[2] * lerp1 + n2[2] * lerp2 + n3[2] * lerp3;
202 verts1++;verts2++;verts3++;
208 translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2;
209 translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2;
210 translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2;
212 for (i = 0;i < vertcount;i++)
214 av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + translate[0];
215 av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + translate[1];
216 av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + translate[2];
217 n1 = m_bytenormals[verts1->lightnormalindex];
218 n2 = m_bytenormals[verts2->lightnormalindex];
219 avn[0] = n1[0] * lerp1 + n2[0] * lerp2;
220 avn[1] = n1[1] * lerp1 + n2[1] * lerp2;
221 avn[2] = n1[2] * lerp1 + n2[2] * lerp2;
230 translate[0] = translate1[0] * lerp1;
231 translate[1] = translate1[1] * lerp1;
232 translate[2] = translate1[2] * lerp1;
236 // general but almost never used case
237 for (i = 0;i < vertcount;i++)
239 av[0] = verts1->v[0] * scale1[0] + translate[0];
240 av[1] = verts1->v[1] * scale1[1] + translate[1];
241 av[2] = verts1->v[2] * scale1[2] + translate[2];
242 n1 = m_bytenormals[verts1->lightnormalindex];
243 avn[0] = n1[0] * lerp1;
244 avn[1] = n1[1] * lerp1;
245 avn[2] = n1[2] * lerp1;
254 for (i = 0;i < vertcount;i++)
256 av[0] = verts1->v[0] * scale1[0] + translate[0];
257 av[1] = verts1->v[1] * scale1[1] + translate[1];
258 av[2] = verts1->v[2] * scale1[2] + translate[2];
259 VectorCopy(m_bytenormals[verts1->lightnormalindex], avn);
268 void R_DrawModelMesh(rtexture_t *skin, float *colors, float cred, float cgreen, float cblue)
270 aliasmeshinfo.tex[0] = R_GetTexture(skin);
271 aliasmeshinfo.color = colors;
274 aliasmeshinfo.cr = cred;
275 aliasmeshinfo.cg = cgreen;
276 aliasmeshinfo.cb = cblue;
277 aliasmeshinfo.ca = currentrenderentity->alpha;
280 c_alias_polys += aliasmeshinfo.numtriangles;
281 R_Mesh_Draw(&aliasmeshinfo);
283 // leave it in a state for additional passes
284 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
285 aliasmeshinfo.blendfunc2 = GL_ONE;
288 void R_TintModel(float *in, float *out, int verts, float r, float g, float b)
291 for (i = 0;i < verts;i++)
302 void R_SetupMDLMD2Frames(skinframe_t **skinframe)
304 md2frame_t *frame1, *frame2, *frame3, *frame4;
305 trivertx_t *frame1verts, *frame2verts, *frame3verts, *frame4verts;
307 model = currentrenderentity->model;
309 if (model->skinscenes[currentrenderentity->skinnum].framecount > 1)
310 *skinframe = &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe + (int) (cl.time * 10) % model->skinscenes[currentrenderentity->skinnum].framecount];
312 *skinframe = &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe];
314 frame1 = &model->mdlmd2data_frames[currentrenderentity->frameblend[0].frame];
315 frame2 = &model->mdlmd2data_frames[currentrenderentity->frameblend[1].frame];
316 frame3 = &model->mdlmd2data_frames[currentrenderentity->frameblend[2].frame];
317 frame4 = &model->mdlmd2data_frames[currentrenderentity->frameblend[3].frame];
318 frame1verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[0].frame * model->numverts];
319 frame2verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[1].frame * model->numverts];
320 frame3verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[2].frame * model->numverts];
321 frame4verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[3].frame * model->numverts];
322 R_AliasLerpVerts(model->numverts,
323 currentrenderentity->frameblend[0].lerp, frame1verts, frame1->scale, frame1->translate,
324 currentrenderentity->frameblend[1].lerp, frame2verts, frame2->scale, frame2->translate,
325 currentrenderentity->frameblend[2].lerp, frame3verts, frame3->scale, frame3->translate,
326 currentrenderentity->frameblend[3].lerp, frame4verts, frame4->scale, frame4->translate);
327 R_AliasTransformVerts(model->numverts);
329 R_LightModel(model->numverts);
332 void R_DrawQ1Q2AliasModel (void)
337 skinframe_t *skinframe;
339 model = currentrenderentity->model;
341 R_SetupMDLMD2Frames(&skinframe);
343 memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo));
345 aliasmeshinfo.vertex = aliasvert;
346 aliasmeshinfo.vertexstep = sizeof(float[4]);
347 aliasmeshinfo.numverts = model->numverts;
348 aliasmeshinfo.numtriangles = model->numtris;
349 aliasmeshinfo.index = model->mdlmd2data_indices;
350 aliasmeshinfo.colorstep = sizeof(float[4]);
351 aliasmeshinfo.texcoords[0] = model->mdlmd2data_texcoords;
352 aliasmeshinfo.texcoordstep[0] = sizeof(float[2]);
357 VectorSubtract(currentrenderentity->origin, r_origin, diff);
358 fog = DotProduct(diff,diff);
361 fog = exp(fogdensity/fog);
366 // fog method: darken, additive fog
367 // 1. render model as normal, scaled by inverse of fog alpha (darkens it)
368 // 2. render fog as additive
371 if (currentrenderentity->effects & EF_ADDITIVE)
373 aliasmeshinfo.transparent = true;
374 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
375 aliasmeshinfo.blendfunc2 = GL_ONE;
377 else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL)
379 aliasmeshinfo.transparent = true;
380 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
381 aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
385 aliasmeshinfo.transparent = false;
386 aliasmeshinfo.blendfunc1 = GL_ONE;
387 aliasmeshinfo.blendfunc2 = GL_ZERO;
392 R_TintModel(aliasvertcolor, aliasvertcolor, model->numverts, 1 - fog, 1 - fog, 1 - fog);
394 if (skinframe->base || skinframe->pants || skinframe->shirt || skinframe->glow || skinframe->merged)
396 if (currentrenderentity->colormap >= 0 && (skinframe->base || skinframe->pants || skinframe->shirt))
401 R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
402 if (skinframe->pants)
404 c = (currentrenderentity->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
405 color = (qbyte *) (&d_8to24table[c]);
406 if (c >= 224) // fullbright ranges
407 R_DrawModelMesh(skinframe->pants, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
410 R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
411 R_DrawModelMesh(skinframe->pants, aliasvertcolor2, 0, 0, 0);
414 if (skinframe->shirt)
416 c = currentrenderentity->colormap & 0xF0 ;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
417 color = (qbyte *) (&d_8to24table[c]);
418 if (c >= 224) // fullbright ranges
419 R_DrawModelMesh(skinframe->shirt, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
422 R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
423 R_DrawModelMesh(skinframe->shirt, aliasvertcolor2, 0, 0, 0);
429 if (skinframe->merged)
430 R_DrawModelMesh(skinframe->merged, aliasvertcolor, 0, 0, 0);
433 if (skinframe->base) R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
434 if (skinframe->pants) R_DrawModelMesh(skinframe->pants, aliasvertcolor, 0, 0, 0);
435 if (skinframe->shirt) R_DrawModelMesh(skinframe->shirt, aliasvertcolor, 0, 0, 0);
438 if (skinframe->glow) R_DrawModelMesh(skinframe->glow, NULL, 1 - fog, 1 - fog, 1 - fog);
441 R_DrawModelMesh(0, NULL, 1 - fog, 1 - fog, 1 - fog);
443 if (fog && aliasmeshinfo.blendfunc2 != GL_ONE)
445 aliasmeshinfo.tex[0] = R_GetTexture(skinframe->fog);
446 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
447 aliasmeshinfo.blendfunc2 = GL_ONE;
448 aliasmeshinfo.color = NULL;
450 aliasmeshinfo.cr = fogcolor[0];
451 aliasmeshinfo.cg = fogcolor[1];
452 aliasmeshinfo.cb = fogcolor[2];
453 aliasmeshinfo.ca = currentrenderentity->alpha * fog;
455 c_alias_polys += aliasmeshinfo.numtriangles;
456 R_Mesh_Draw(&aliasmeshinfo);
460 int ZymoticLerpBones(int count, zymbonematrix *bonebase, frameblend_t *blend, zymbone_t *bone)
463 float lerp1, lerp2, lerp3, lerp4;
464 zymbonematrix *out, rootmatrix, m, *bone1, *bone2, *bone3, *bone4;
479 R_ConcatTransforms(&softwaretransform_matrix[0], &m.m[0], &rootmatrix.m[0]);
482 // LordHavoc: combine transform from zym coordinate space to quake coordinate space with model to world transform matrix
483 rootmatrix.m[0][0] = softwaretransform_matrix[0][1];
484 rootmatrix.m[0][1] = -softwaretransform_matrix[0][0];
485 rootmatrix.m[0][2] = softwaretransform_matrix[0][2];
486 rootmatrix.m[0][3] = softwaretransform_matrix[0][3];
487 rootmatrix.m[1][0] = softwaretransform_matrix[1][1];
488 rootmatrix.m[1][1] = -softwaretransform_matrix[1][0];
489 rootmatrix.m[1][2] = softwaretransform_matrix[1][2];
490 rootmatrix.m[1][3] = softwaretransform_matrix[1][3];
491 rootmatrix.m[2][0] = softwaretransform_matrix[2][1];
492 rootmatrix.m[2][1] = -softwaretransform_matrix[2][0];
493 rootmatrix.m[2][2] = softwaretransform_matrix[2][2];
494 rootmatrix.m[2][3] = softwaretransform_matrix[2][3];
496 bone1 = bonebase + blend[0].frame * count;
497 lerp1 = blend[0].lerp;
500 bone2 = bonebase + blend[1].frame * count;
501 lerp2 = blend[1].lerp;
504 bone3 = bonebase + blend[2].frame * count;
505 lerp3 = blend[2].lerp;
509 bone4 = bonebase + blend[3].frame * count;
510 lerp4 = blend[3].lerp;
511 for (i = 0, out = zymbonepose;i < count;i++, out++)
513 // interpolate matrices
514 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3 + bone4->m[0][0] * lerp4;
515 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3 + bone4->m[0][1] * lerp4;
516 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3 + bone4->m[0][2] * lerp4;
517 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3 + bone4->m[0][3] * lerp4;
518 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3 + bone4->m[1][0] * lerp4;
519 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3 + bone4->m[1][1] * lerp4;
520 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3 + bone4->m[1][2] * lerp4;
521 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3 + bone4->m[1][3] * lerp4;
522 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3 + bone4->m[2][0] * lerp4;
523 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3 + bone4->m[2][1] * lerp4;
524 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3 + bone4->m[2][2] * lerp4;
525 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3 + bone4->m[2][3] * lerp4;
526 if (bone->parent >= 0)
527 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
529 R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
540 for (i = 0, out = zymbonepose;i < count;i++, out++)
542 // interpolate matrices
543 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3;
544 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3;
545 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3;
546 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3;
547 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3;
548 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3;
549 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3;
550 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3;
551 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3;
552 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3;
553 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3;
554 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3;
555 if (bone->parent >= 0)
556 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
558 R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
569 for (i = 0, out = zymbonepose;i < count;i++, out++)
571 // interpolate matrices
572 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2;
573 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2;
574 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2;
575 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2;
576 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2;
577 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2;
578 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2;
579 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2;
580 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2;
581 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2;
582 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2;
583 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2;
584 if (bone->parent >= 0)
585 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
587 R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
600 for (i = 0, out = zymbonepose;i < count;i++, out++)
602 // interpolate matrices
603 m.m[0][0] = bone1->m[0][0] * lerp1;
604 m.m[0][1] = bone1->m[0][1] * lerp1;
605 m.m[0][2] = bone1->m[0][2] * lerp1;
606 m.m[0][3] = bone1->m[0][3] * lerp1;
607 m.m[1][0] = bone1->m[1][0] * lerp1;
608 m.m[1][1] = bone1->m[1][1] * lerp1;
609 m.m[1][2] = bone1->m[1][2] * lerp1;
610 m.m[1][3] = bone1->m[1][3] * lerp1;
611 m.m[2][0] = bone1->m[2][0] * lerp1;
612 m.m[2][1] = bone1->m[2][1] * lerp1;
613 m.m[2][2] = bone1->m[2][2] * lerp1;
614 m.m[2][3] = bone1->m[2][3] * lerp1;
615 if (bone->parent >= 0)
616 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
618 R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
626 for (i = 0, out = zymbonepose;i < count;i++, out++)
628 if (bone->parent >= 0)
629 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &bone1->m[0], &out->m[0]);
631 R_ConcatTransforms(&rootmatrix.m[0], &bone1->m[0], &out->m[0]);
640 void ZymoticTransformVerts(int vertcount, int *bonecounts, zymvertex_t *vert)
643 float *out = aliasvert;
644 zymbonematrix *matrix;
648 // FIXME: validate bonecounts at load time (must be >= 1)
649 // FIXME: need 4th component in origin, for how much of the translate to blend in
652 matrix = &zymbonepose[vert->bonenum];
653 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];
654 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];
655 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];
663 matrix = &zymbonepose[vert->bonenum];
664 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];
665 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];
666 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];
674 void ZymoticCalcNormals(int vertcount, int shadercount, int *renderlist)
677 float *out, v1[3], v2[3], normal[3], s;
680 memset(aliasvertnorm, 0, sizeof(float) * vertcount * 3);
681 memset(aliasvertusage, 0, sizeof(int) * vertcount);
682 // parse render list and accumulate surface normals
691 v1[0] = aliasvert[a+0] - aliasvert[b+0];
692 v1[1] = aliasvert[a+1] - aliasvert[b+1];
693 v1[2] = aliasvert[a+2] - aliasvert[b+2];
694 v2[0] = aliasvert[c+0] - aliasvert[b+0];
695 v2[1] = aliasvert[c+1] - aliasvert[b+1];
696 v2[2] = aliasvert[c+2] - aliasvert[b+2];
697 CrossProduct(v1, v2, normal);
698 VectorNormalizeFast(normal);
699 // add surface normal to vertices
700 a = renderlist[0] * 3;
701 aliasvertnorm[a+0] += normal[0];
702 aliasvertnorm[a+1] += normal[1];
703 aliasvertnorm[a+2] += normal[2];
704 aliasvertusage[renderlist[0]]++;
705 a = renderlist[1] * 3;
706 aliasvertnorm[a+0] += normal[0];
707 aliasvertnorm[a+1] += normal[1];
708 aliasvertnorm[a+2] += normal[2];
709 aliasvertusage[renderlist[1]]++;
710 a = renderlist[2] * 3;
711 aliasvertnorm[a+0] += normal[0];
712 aliasvertnorm[a+1] += normal[1];
713 aliasvertnorm[a+2] += normal[2];
714 aliasvertusage[renderlist[2]]++;
718 // FIXME: precalc this
719 // average surface normals
736 void R_DrawZymoticModelMesh(zymtype1header_t *m)
739 rtexture_t **texture;
741 // FIXME: do better fog
742 renderlist = (int *)(m->lump_render.start + (int) m);
743 texture = (rtexture_t **)(m->lump_shaders.start + (int) m);
745 aliasmeshinfo.vertex = aliasvert;
746 aliasmeshinfo.vertexstep = sizeof(float[4]);
747 aliasmeshinfo.color = aliasvertcolor;
748 aliasmeshinfo.colorstep = sizeof(float[4]);
749 aliasmeshinfo.texcoords[0] = (float *)(m->lump_texcoords.start + (int) m);
750 aliasmeshinfo.texcoordstep[0] = sizeof(float[2]);
752 for (i = 0;i < m->numshaders;i++)
754 aliasmeshinfo.tex[0] = R_GetTexture(texture[i]);
755 if (currentrenderentity->effects & EF_ADDITIVE)
757 aliasmeshinfo.transparent = true;
758 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
759 aliasmeshinfo.blendfunc2 = GL_ONE;
761 else if (currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(texture[i]))
763 aliasmeshinfo.transparent = true;
764 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
765 aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
769 aliasmeshinfo.transparent = false;
770 aliasmeshinfo.blendfunc1 = GL_ONE;
771 aliasmeshinfo.blendfunc2 = GL_ZERO;
773 aliasmeshinfo.numtriangles = *renderlist++;
774 aliasmeshinfo.index = renderlist;
775 c_alias_polys += aliasmeshinfo.numtriangles;
776 R_Mesh_Draw(&aliasmeshinfo);
777 renderlist += aliasmeshinfo.numtriangles * 3;
781 void R_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m)
786 // FIXME: do better fog
787 renderlist = (int *)(m->lump_render.start + (int) m);
789 aliasmeshinfo.tex[0] = 0;
790 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
791 aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
793 VectorSubtract(org, r_origin, diff);
794 aliasmeshinfo.cr = fogcolor[0];
795 aliasmeshinfo.cg = fogcolor[1];
796 aliasmeshinfo.cb = fogcolor[2];
797 aliasmeshinfo.ca = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff));
799 for (i = 0;i < m->numshaders;i++)
801 aliasmeshinfo.numtriangles = *renderlist++;
802 aliasmeshinfo.index = renderlist;
803 c_alias_polys += aliasmeshinfo.numtriangles;
804 R_Mesh_Draw(&aliasmeshinfo);
805 renderlist += aliasmeshinfo.numtriangles * 3;
809 void R_DrawZymoticModel (void)
813 // FIXME: do better fog
814 m = currentrenderentity->model->zymdata_header;
815 ZymoticLerpBones(m->numbones, (zymbonematrix *)(m->lump_poses.start + (int) m), currentrenderentity->frameblend, (zymbone_t *)(m->lump_bones.start + (int) m));
816 ZymoticTransformVerts(m->numverts, (int *)(m->lump_vertbonecounts.start + (int) m), (zymvertex_t *)(m->lump_verts.start + (int) m));
817 ZymoticCalcNormals(m->numverts, m->numshaders, (int *)(m->lump_render.start + (int) m));
819 R_LightModel(m->numverts);
821 memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo));
822 aliasmeshinfo.numverts = m->numverts;
824 R_DrawZymoticModelMesh(m);
827 R_DrawZymoticModelMeshFog(currentrenderentity->origin, m);
830 void R_DrawAliasModel (void)
832 if (currentrenderentity->alpha < (1.0f / 64.0f))
833 return; // basically completely transparent
837 softwaretransformforentity(currentrenderentity);
839 if (currentrenderentity->model->aliastype == ALIASTYPE_ZYM)
840 R_DrawZymoticModel();
842 R_DrawQ1Q2AliasModel();