4 //cvar_t gl_transform = {0, "gl_transform", "1"};
5 cvar_t gl_lockarrays = {0, "gl_lockarrays", "1"};
6 cvar_t r_zymdebug = {0, "r_zymdebug", "0"};
7 cvar_t r_zymdebug_dist = {0, "r_zymdebug_dist", "4"};
14 // LordHavoc: vertex array
17 float *aliasvertcolor;
18 float *aliasvertcolor2;
19 zymbonematrix *zymbonepose;
22 rmeshinfo_t aliasmeshinfo;
24 rtexture_t *chrometexture;
26 int arraylocked = false;
27 void GL_LockArray(int first, int count)
29 if (gl_supportslockarrays && gl_lockarrays.integer)
31 qglLockArraysEXT(first, count);
36 void GL_UnlockArray(void)
46 void GL_SetupModelTransform (vec3_t origin, vec3_t angles, vec_t scale)
48 glTranslatef (origin[0], origin[1], origin[2]);
51 glScalef (scale, scale, scale);
53 glRotatef (angles[1], 0, 0, 1);
55 glRotatef (-angles[0], 0, 1, 0);
57 glRotatef (angles[2], 1, 0, 0);
61 rtexturepool_t *chrometexturepool;
63 // currently unused reflection effect texture
64 void makechrometexture(void)
70 fractalnoise(noise, 64, 8);
72 // convert to RGBA data
73 for (i = 0;i < 64*64;i++)
75 data[i][0] = data[i][1] = data[i][2] = noise[i];
79 chrometexture = R_LoadTexture (chrometexturepool, "chrometexture", 64, 64, &data[0][0], TEXTYPE_RGBA, TEXF_MIPMAP | TEXF_PRECACHE);
82 mempool_t *gl_models_mempool;
84 void gl_models_start(void)
86 // allocate vertex processing arrays
87 gl_models_mempool = Mem_AllocPool("GL_Models");
88 aliasvert = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][3]));
89 aliasvertnorm = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][3]));
90 aliasvertcolor = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4]));
91 aliasvertcolor2 = Mem_Alloc(gl_models_mempool, sizeof(float[MD2MAX_VERTS][4])); // used temporarily for tinted coloring
92 zymbonepose = Mem_Alloc(gl_models_mempool, sizeof(zymbonematrix[256]));
93 aliasvertusage = Mem_Alloc(gl_models_mempool, sizeof(int[MD2MAX_VERTS]));
94 chrometexturepool = R_AllocTexturePool();
98 void gl_models_shutdown(void)
100 R_FreeTexturePool(&chrometexturepool);
101 Mem_FreePool(&gl_models_mempool);
104 void gl_models_newmap(void)
108 void GL_Models_Init(void)
110 // Cvar_RegisterVariable(&gl_transform);
111 Cvar_RegisterVariable(&gl_lockarrays);
112 Cvar_RegisterVariable(&r_zymdebug);
113 Cvar_RegisterVariable(&r_zymdebug_dist);
115 R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown, gl_models_newmap);
118 void R_AliasTransformVerts(int vertcount)
124 while (vertcount >= 4)
126 VectorCopy(av, point);softwaretransform(point, av);av += 3;
127 VectorCopy(av, point);softwaretransform(point, av);av += 3;
128 VectorCopy(av, point);softwaretransform(point, av);av += 3;
129 VectorCopy(av, point);softwaretransform(point, av);av += 3;
130 VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
131 VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
132 VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
133 VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
138 VectorCopy(av, point);softwaretransform(point, av);av += 3;
139 VectorCopy(avn, point);softwaretransformdirection(point, avn);avn += 3;
144 void R_AliasLerpVerts(int vertcount,
145 float lerp1, trivertx_t *verts1, vec3_t fscale1, vec3_t translate1,
146 float lerp2, trivertx_t *verts2, vec3_t fscale2, vec3_t translate2,
147 float lerp3, trivertx_t *verts3, vec3_t fscale3, vec3_t translate3,
148 float lerp4, trivertx_t *verts4, vec3_t fscale4, vec3_t translate4)
151 vec3_t scale1, scale2, scale3, scale4, translate;
152 float *n1, *n2, *n3, *n4;
156 VectorScale(fscale1, lerp1, scale1);
159 VectorScale(fscale2, lerp2, scale2);
162 VectorScale(fscale3, lerp3, scale3);
165 VectorScale(fscale4, lerp4, scale4);
166 translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2 + translate3[0] * lerp3 + translate4[0] * lerp4;
167 translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2 + translate3[1] * lerp3 + translate4[1] * lerp4;
168 translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2 + translate3[2] * lerp3 + translate4[2] * lerp4;
170 for (i = 0;i < vertcount;i++)
172 av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + verts3->v[0] * scale3[0] + verts4->v[0] * scale4[0] + translate[0];
173 av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + verts3->v[1] * scale3[1] + verts4->v[1] * scale4[1] + translate[1];
174 av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + verts3->v[2] * scale3[2] + verts4->v[2] * scale4[2] + translate[2];
175 n1 = m_bytenormals[verts1->lightnormalindex];
176 n2 = m_bytenormals[verts2->lightnormalindex];
177 n3 = m_bytenormals[verts3->lightnormalindex];
178 n4 = m_bytenormals[verts4->lightnormalindex];
179 avn[0] = n1[0] * lerp1 + n2[0] * lerp2 + n3[0] * lerp3 + n4[0] * lerp4;
180 avn[1] = n1[1] * lerp1 + n2[1] * lerp2 + n3[1] * lerp3 + n4[1] * lerp4;
181 avn[2] = n1[2] * lerp1 + n2[2] * lerp2 + n3[2] * lerp3 + n4[2] * lerp4;
184 verts1++;verts2++;verts3++;verts4++;
189 translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2 + translate3[0] * lerp3;
190 translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2 + translate3[1] * lerp3;
191 translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2 + translate3[2] * lerp3;
193 for (i = 0;i < vertcount;i++)
195 av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + verts3->v[0] * scale3[0] + translate[0];
196 av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + verts3->v[1] * scale3[1] + translate[1];
197 av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + verts3->v[2] * scale3[2] + translate[2];
198 n1 = m_bytenormals[verts1->lightnormalindex];
199 n2 = m_bytenormals[verts2->lightnormalindex];
200 n3 = m_bytenormals[verts3->lightnormalindex];
201 avn[0] = n1[0] * lerp1 + n2[0] * lerp2 + n3[0] * lerp3;
202 avn[1] = n1[1] * lerp1 + n2[1] * lerp2 + n3[1] * lerp3;
203 avn[2] = n1[2] * lerp1 + n2[2] * lerp2 + n3[2] * lerp3;
206 verts1++;verts2++;verts3++;
212 translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2;
213 translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2;
214 translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2;
216 for (i = 0;i < vertcount;i++)
218 av[0] = verts1->v[0] * scale1[0] + verts2->v[0] * scale2[0] + translate[0];
219 av[1] = verts1->v[1] * scale1[1] + verts2->v[1] * scale2[1] + translate[1];
220 av[2] = verts1->v[2] * scale1[2] + verts2->v[2] * scale2[2] + translate[2];
221 n1 = m_bytenormals[verts1->lightnormalindex];
222 n2 = m_bytenormals[verts2->lightnormalindex];
223 avn[0] = n1[0] * lerp1 + n2[0] * lerp2;
224 avn[1] = n1[1] * lerp1 + n2[1] * lerp2;
225 avn[2] = n1[2] * lerp1 + n2[2] * lerp2;
234 translate[0] = translate1[0] * lerp1;
235 translate[1] = translate1[1] * lerp1;
236 translate[2] = translate1[2] * lerp1;
240 // general but almost never used case
241 for (i = 0;i < vertcount;i++)
243 av[0] = verts1->v[0] * scale1[0] + translate[0];
244 av[1] = verts1->v[1] * scale1[1] + translate[1];
245 av[2] = verts1->v[2] * scale1[2] + translate[2];
246 n1 = m_bytenormals[verts1->lightnormalindex];
247 avn[0] = n1[0] * lerp1;
248 avn[1] = n1[1] * lerp1;
249 avn[2] = n1[2] * lerp1;
258 for (i = 0;i < vertcount;i++)
260 av[0] = verts1->v[0] * scale1[0] + translate[0];
261 av[1] = verts1->v[1] * scale1[1] + translate[1];
262 av[2] = verts1->v[2] * scale1[2] + translate[2];
263 VectorCopy(m_bytenormals[verts1->lightnormalindex], avn);
272 void R_DrawModelMesh(rtexture_t *skin, float *colors, float cred, float cgreen, float cblue)
274 aliasmeshinfo.tex[0] = R_GetTexture(skin);
275 aliasmeshinfo.color = colors;
278 aliasmeshinfo.cr = cred;
279 aliasmeshinfo.cg = cgreen;
280 aliasmeshinfo.cb = cblue;
281 aliasmeshinfo.ca = currentrenderentity->alpha;
284 c_alias_polys += aliasmeshinfo.numtriangles;
285 R_Mesh_Draw(&aliasmeshinfo);
287 // leave it in a state for additional passes
288 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
289 aliasmeshinfo.blendfunc2 = GL_ONE;
292 void R_TintModel(float *in, float *out, int verts, float r, float g, float b)
295 for (i = 0;i < verts;i++)
306 void R_SetupMDLMD2Frames(skinframe_t **skinframe)
308 md2frame_t *frame1, *frame2, *frame3, *frame4;
309 trivertx_t *frame1verts, *frame2verts, *frame3verts, *frame4verts;
311 model = currentrenderentity->model;
313 if (model->skinscenes[currentrenderentity->skinnum].framecount > 1)
314 *skinframe = &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe + (int) (cl.time * 10) % model->skinscenes[currentrenderentity->skinnum].framecount];
316 *skinframe = &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe];
318 frame1 = &model->mdlmd2data_frames[currentrenderentity->frameblend[0].frame];
319 frame2 = &model->mdlmd2data_frames[currentrenderentity->frameblend[1].frame];
320 frame3 = &model->mdlmd2data_frames[currentrenderentity->frameblend[2].frame];
321 frame4 = &model->mdlmd2data_frames[currentrenderentity->frameblend[3].frame];
322 frame1verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[0].frame * model->numverts];
323 frame2verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[1].frame * model->numverts];
324 frame3verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[2].frame * model->numverts];
325 frame4verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[3].frame * model->numverts];
327 if (currentrenderentity->frameblend[0].lerp)
328 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]);
329 if (currentrenderentity->frameblend[1].lerp)
330 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]);
331 if (currentrenderentity->frameblend[2].lerp)
332 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]);
333 if (currentrenderentity->frameblend[3].lerp)
334 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]);
336 R_AliasLerpVerts(model->numverts,
337 currentrenderentity->frameblend[0].lerp, frame1verts, frame1->scale, frame1->translate,
338 currentrenderentity->frameblend[1].lerp, frame2verts, frame2->scale, frame2->translate,
339 currentrenderentity->frameblend[2].lerp, frame3verts, frame3->scale, frame3->translate,
340 currentrenderentity->frameblend[3].lerp, frame4verts, frame4->scale, frame4->translate);
341 R_AliasTransformVerts(model->numverts);
343 R_LightModel(model->numverts);
346 void R_DrawQ1AliasModel (void)
351 skinframe_t *skinframe;
353 model = currentrenderentity->model;
355 R_SetupMDLMD2Frames(&skinframe);
357 memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo));
359 aliasmeshinfo.vertex = aliasvert;
360 aliasmeshinfo.vertexstep = sizeof(float[3]);
361 aliasmeshinfo.numverts = model->numverts;
362 aliasmeshinfo.numtriangles = model->numtris;
363 aliasmeshinfo.index = model->mdldata_indices;
364 aliasmeshinfo.colorstep = sizeof(float[4]);
365 aliasmeshinfo.texcoords[0] = model->mdldata_texcoords;
366 aliasmeshinfo.texcoordstep[0] = sizeof(float[2]);
371 VectorSubtract(currentrenderentity->origin, r_origin, diff);
372 fog = DotProduct(diff,diff);
375 fog = exp(fogdensity/fog);
380 // fog method: darken, additive fog
381 // 1. render model as normal, scaled by inverse of fog alpha (darkens it)
382 // 2. render fog as additive
385 if (currentrenderentity->effects & EF_ADDITIVE)
387 aliasmeshinfo.transparent = true;
388 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
389 aliasmeshinfo.blendfunc2 = GL_ONE;
391 else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL)
393 aliasmeshinfo.transparent = true;
394 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
395 aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
399 aliasmeshinfo.transparent = false;
400 aliasmeshinfo.blendfunc1 = GL_ONE;
401 aliasmeshinfo.blendfunc2 = GL_ZERO;
406 R_TintModel(aliasvertcolor, aliasvertcolor, model->numverts, 1 - fog, 1 - fog, 1 - fog);
408 if (skinframe->base || skinframe->pants || skinframe->shirt || skinframe->glow || skinframe->merged)
410 if (currentrenderentity->colormap >= 0 && (skinframe->base || skinframe->pants || skinframe->shirt))
415 R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
416 if (skinframe->pants)
418 c = (currentrenderentity->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
419 color = (byte *) (&d_8to24table[c]);
420 if (c >= 224) // fullbright ranges
421 R_DrawModelMesh(skinframe->pants, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
424 R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
425 R_DrawModelMesh(skinframe->pants, aliasvertcolor2, 0, 0, 0);
428 if (skinframe->shirt)
430 c = currentrenderentity->colormap & 0xF0 ;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
431 color = (byte *) (&d_8to24table[c]);
432 if (c >= 224) // fullbright ranges
433 R_DrawModelMesh(skinframe->shirt, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
436 R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
437 R_DrawModelMesh(skinframe->shirt, aliasvertcolor2, 0, 0, 0);
443 if (skinframe->merged)
444 R_DrawModelMesh(skinframe->merged, aliasvertcolor, 0, 0, 0);
447 if (skinframe->base) R_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
448 if (skinframe->pants) R_DrawModelMesh(skinframe->pants, aliasvertcolor, 0, 0, 0);
449 if (skinframe->shirt) R_DrawModelMesh(skinframe->shirt, aliasvertcolor, 0, 0, 0);
452 if (skinframe->glow) R_DrawModelMesh(skinframe->glow, NULL, 1 - fog, 1 - fog, 1 - fog);
455 R_DrawModelMesh(0, NULL, 1 - fog, 1 - fog, 1 - fog);
459 aliasmeshinfo.tex[0] = R_GetTexture(skinframe->fog);
460 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
461 aliasmeshinfo.blendfunc2 = GL_ONE;
462 aliasmeshinfo.color = NULL;
464 aliasmeshinfo.cr = fogcolor[0];
465 aliasmeshinfo.cg = fogcolor[1];
466 aliasmeshinfo.cb = fogcolor[2];
467 aliasmeshinfo.ca = currentrenderentity->alpha * fog;
469 c_alias_polys += aliasmeshinfo.numtriangles;
470 R_Mesh_Draw(&aliasmeshinfo);
474 void R_DrawQ2AliasModel (void)
478 skinframe_t *skinframe;
481 model = currentrenderentity->model;
483 R_SetupMDLMD2Frames(&skinframe);
485 if (!r_render.integer)
488 // FIXME FIXME FIXME rewrite loader to convert to triangle mesh
489 glBindTexture(GL_TEXTURE_2D, R_GetTexture(skinframe->base));
491 if (currentrenderentity->effects & EF_ADDITIVE)
493 glBlendFunc(GL_SRC_ALPHA, GL_ONE); // additive rendering
497 else if (currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(skinframe->base))
499 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
509 // LordHavoc: big mess...
510 // using vertex arrays only slightly, although it is enough to prevent duplicates
511 // (saving half the transforms)
512 glVertexPointer(3, GL_FLOAT, sizeof(float[3]), aliasvert);
513 glColorPointer(4, GL_FLOAT, sizeof(float[4]), aliasvertcolor);
514 glEnableClientState(GL_VERTEX_ARRAY);
515 glEnableClientState(GL_COLOR_ARRAY);
517 GL_LockArray(0, model->numverts);
519 order = model->md2data_glcmds;
522 if (!(count = *order++))
525 glBegin(GL_TRIANGLE_STRIP);
528 glBegin(GL_TRIANGLE_FAN);
533 glTexCoord2f(((float *)order)[0], ((float *)order)[1]);
534 glArrayElement(order[2]);
542 glDisableClientState(GL_COLOR_ARRAY);
543 glDisableClientState(GL_VERTEX_ARRAY);
547 glDisable (GL_TEXTURE_2D);
548 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
550 glDepthMask(0); // disable zbuffer updates
552 VectorSubtract(currentrenderentity->origin, r_origin, diff);
553 glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff)));
555 // LordHavoc: big mess...
556 // using vertex arrays only slightly, although it is enough to prevent duplicates
557 // (saving half the transforms)
558 glVertexPointer(3, GL_FLOAT, sizeof(float[3]), aliasvert);
559 glEnableClientState(GL_VERTEX_ARRAY);
561 GL_LockArray(0, model->numverts);
563 order = model->md2data_glcmds;
566 if (!(count = *order++))
569 glBegin(GL_TRIANGLE_STRIP);
572 glBegin(GL_TRIANGLE_FAN);
577 glArrayElement(order[2]);
585 glDisableClientState(GL_VERTEX_ARRAY);
587 glEnable (GL_TEXTURE_2D);
591 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
597 static float bestdist;
599 int ZymoticLerpBones(int count, zymbonematrix *bonebase, frameblend_t *blend, zymbone_t *bone/*, float rootorigin[3], float rootangles[3], float rootscale*/)
602 float lerp1, lerp2, lerp3, lerp4/*, ang[3]*/;
603 zymbonematrix *out, modelmatrix, swapmatrix, m, *bone1, *bone2, *bone3, *bone4;
606 memset(&swapmatrix, 0, sizeof(zymbonematrix));
608 //ang[0] = (zymdebug & 3) * 90;zymdebug /= 4;
609 //ang[1] = (zymdebug & 3) * 90;zymdebug /= 4;
610 //ang[2] = (zymdebug & 3) * 90;zymdebug /= 4;
615 AngleVectorsFLU(ang, swapmatrix.m[0], swapmatrix.m[1], swapmatrix.m[2]);
618 i = zymdebug % 3;zymdebug /= 3;
619 j = zymdebug % 3;zymdebug /= 3;
620 lerp1 = (zymdebug & 1) ? -1 : 1;zymdebug /= 2;
621 if (swapmatrix.m[i][j])
623 swapmatrix.m[i][j] = lerp1;
624 i = zymdebug % 3;zymdebug /= 3;
625 j = zymdebug % 3;zymdebug /= 3;
626 lerp1 = (zymdebug & 1) ? -1 : 1;zymdebug /= 2;
627 if (swapmatrix.m[i][j])
629 swapmatrix.m[i][j] = lerp1;
630 i = zymdebug % 3;zymdebug /= 3;
631 j = zymdebug % 3;zymdebug /= 3;
632 lerp1 = (zymdebug & 1) ? -1 : 1;zymdebug /= 2;
633 if (swapmatrix.m[i][j])
635 swapmatrix.m[i][j] = lerp1;
638 lerp1 = (zymdebug & 1) ? -1 : 1;zymdebug /= 2;
639 swapmatrix.m[0][zymdebug % 3] = lerp1;zymdebug /= 3;
640 lerp1 = (zymdebug & 1) ? -1 : 1;zymdebug /= 2;
641 swapmatrix.m[1][zymdebug % 3] = lerp1;zymdebug /= 3;
642 lerp1 = (zymdebug & 1) ? -1 : 1;zymdebug /= 2;
643 swapmatrix.m[2][zymdebug % 3] = lerp1;zymdebug /= 3;
646 for (i = 0;i < 3;i++)
648 for (j = 0;j < 3;j++)
650 swapmatrix.m[i][j] = (zymdebug % 3) - 1;
656 for (i = 0;i < 3;i++)
658 if (fabs(swapmatrix.m[i][0] * swapmatrix.m[i][0] + swapmatrix.m[i][1] * swapmatrix.m[i][1] + swapmatrix.m[i][2] * swapmatrix.m[i][2] - 1) > 0.01f)
660 if (fabs(swapmatrix.m[0][i] * swapmatrix.m[0][i] + swapmatrix.m[1][i] * swapmatrix.m[1][i] + swapmatrix.m[2][i] * swapmatrix.m[2][i] - 1) > 0.01f)
664 //if (fabs(DotProduct(swapmatrix.m[0], swapmatrix.m[0]) + DotProduct(swapmatrix.m[0], swapmatrix.m[0]) + DotProduct(swapmatrix.m[0], swapmatrix.m[0]) - 3) > 0.01f)
667 swapmatrix.m[0][1] = -1;
668 swapmatrix.m[1][0] = 1;
669 swapmatrix.m[2][2] = 1;
671 memset(&modelmatrix, 0, sizeof(zymbonematrix));
675 switch (zymdebug % 6)
677 case 0: a = 0;b = 1;c = 2;break;
678 case 1: a = 1;b = 0;c = 2;break;
679 case 2: a = 2;b = 0;c = 1;break;
680 case 3: a = 0;b = 2;c = 1;break;
681 case 4: a = 1;b = 2;c = 0;break;
682 case 5: a = 2;b = 1;c = 0;break;
685 AngleVectors(rootangles, m.m[a], m.m[b], m.m[c]);
687 VectorNegate(m.m[0], m.m[0]);
690 VectorNegate(m.m[1], m.m[1]);
693 VectorNegate(m.m[2], m.m[2]);
697 for (a = 0;a < 3;a++)
698 for (b = 0;b < 3;b++)
699 modelmatrix.m[a][b] = m.m[b][a];
703 for (a = 0;a < 3;a++)
704 for (b = 0;b < 3;b++)
705 modelmatrix.m[a][b] = m.m[a][b];
708 VectorScale(modelmatrix.m[0], rootscale, modelmatrix.m[0]);
709 VectorScale(modelmatrix.m[1], rootscale, modelmatrix.m[1]);
710 VectorScale(modelmatrix.m[2], rootscale, modelmatrix.m[2]);
714 AngleVectors(rootangles, modelmatrix.m[0], modelmatrix.m[1], modelmatrix.m[2]);
715 VectorScale(modelmatrix.m[0], rootscale, modelmatrix.m[0]);
716 VectorScale(modelmatrix.m[1], rootscale, modelmatrix.m[1]);
717 VectorScale(modelmatrix.m[2], rootscale, modelmatrix.m[2]);
718 modelmatrix.m[0][3] = rootorigin[0];
719 modelmatrix.m[1][3] = rootorigin[1];
720 modelmatrix.m[2][3] = rootorigin[2];
722 memcpy(&m, &swapmatrix, sizeof(zymbonematrix));
724 R_ConcatTransforms(&m.m[0], &modelmatrix.m[0], &swapmatrix.m[0]);
726 R_ConcatTransforms(&modelmatrix.m[0], &m.m[0], &swapmatrix.m[0]);
730 memcpy(&m, &swapmatrix, sizeof(zymbonematrix));
731 R_ConcatTransforms(&softwaretransform_matrix[0], &m.m[0], &swapmatrix.m[0]);
733 bone1 = bonebase + blend[0].frame * count;
734 lerp1 = blend[0].lerp;
737 bone2 = bonebase + blend[1].frame * count;
738 lerp2 = blend[1].lerp;
741 bone3 = bonebase + blend[2].frame * count;
742 lerp3 = blend[2].lerp;
746 bone4 = bonebase + blend[3].frame * count;
747 lerp4 = blend[3].lerp;
748 for (i = 0, out = zymbonepose;i < count;i++, out++)
750 // interpolate matrices
751 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3 + bone4->m[0][0] * lerp4;
752 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3 + bone4->m[0][1] * lerp4;
753 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3 + bone4->m[0][2] * lerp4;
754 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3 + bone4->m[0][3] * lerp4;
755 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3 + bone4->m[1][0] * lerp4;
756 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3 + bone4->m[1][1] * lerp4;
757 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3 + bone4->m[1][2] * lerp4;
758 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3 + bone4->m[1][3] * lerp4;
759 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3 + bone4->m[2][0] * lerp4;
760 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3 + bone4->m[2][1] * lerp4;
761 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3 + bone4->m[2][2] * lerp4;
762 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3 + bone4->m[2][3] * lerp4;
763 if (bone->parent >= 0)
764 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
766 R_ConcatTransforms(&swapmatrix.m[0], &m.m[0], &out->m[0]);
777 for (i = 0, out = zymbonepose;i < count;i++, out++)
779 // interpolate matrices
780 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3;
781 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3;
782 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3;
783 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3;
784 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3;
785 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3;
786 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3;
787 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3;
788 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3;
789 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3;
790 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3;
791 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3;
792 if (bone->parent >= 0)
793 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
795 R_ConcatTransforms(&swapmatrix.m[0], &m.m[0], &out->m[0]);
806 for (i = 0, out = zymbonepose;i < count;i++, out++)
808 // interpolate matrices
809 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2;
810 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2;
811 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2;
812 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2;
813 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2;
814 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2;
815 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2;
816 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2;
817 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2;
818 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2;
819 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2;
820 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2;
821 if (bone->parent >= 0)
822 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
824 R_ConcatTransforms(&swapmatrix.m[0], &m.m[0], &out->m[0]);
837 for (i = 0, out = zymbonepose;i < count;i++, out++)
839 // interpolate matrices
840 m.m[0][0] = bone1->m[0][0] * lerp1;
841 m.m[0][1] = bone1->m[0][1] * lerp1;
842 m.m[0][2] = bone1->m[0][2] * lerp1;
843 m.m[0][3] = bone1->m[0][3] * lerp1;
844 m.m[1][0] = bone1->m[1][0] * lerp1;
845 m.m[1][1] = bone1->m[1][1] * lerp1;
846 m.m[1][2] = bone1->m[1][2] * lerp1;
847 m.m[1][3] = bone1->m[1][3] * lerp1;
848 m.m[2][0] = bone1->m[2][0] * lerp1;
849 m.m[2][1] = bone1->m[2][1] * lerp1;
850 m.m[2][2] = bone1->m[2][2] * lerp1;
851 m.m[2][3] = bone1->m[2][3] * lerp1;
852 if (bone->parent >= 0)
853 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
855 R_ConcatTransforms(&swapmatrix.m[0], &m.m[0], &out->m[0]);
863 for (i = 0, out = zymbonepose;i < count;i++, out++)
865 if (bone->parent >= 0)
866 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &bone1->m[0], &out->m[0]);
868 R_ConcatTransforms(&swapmatrix.m[0], &bone1->m[0], &out->m[0]);
877 void ZymoticTransformVerts(int vertcount, int *bonecounts, zymvertex_t *vert)
880 float *out = aliasvert;
883 zymbonematrix *matrix;
887 // FIXME: validate bonecounts at load time (must be >= 1)
888 // FIXME: need 4th component in origin, for how much of the translate to blend in
891 matrix = &zymbonepose[vert->bonenum];
892 v[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];
893 v[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];
894 v[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];
902 matrix = &zymbonepose[vert->bonenum];
903 v[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];
904 v[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];
905 v[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];
909 //softwaretransform(v, out);
911 dist = DotProduct(out, vpn) - DotProduct(r_origin, vpn);
918 void ZymoticCalcNormals(int vertcount, int shadercount, int *renderlist)
921 float *out, v1[3], v2[3], normal[3];
924 memset(aliasvertnorm, 0, sizeof(float[3]) * vertcount);
925 memset(aliasvertusage, 0, sizeof(int) * vertcount);
926 // parse render list and accumulate surface normals
935 v1[0] = aliasvert[a+0] - aliasvert[b+0];
936 v1[1] = aliasvert[a+1] - aliasvert[b+1];
937 v1[2] = aliasvert[a+2] - aliasvert[b+2];
938 v2[0] = aliasvert[c+0] - aliasvert[b+0];
939 v2[1] = aliasvert[c+1] - aliasvert[b+1];
940 v2[2] = aliasvert[c+2] - aliasvert[b+2];
941 CrossProduct(v1, v2, normal);
942 VectorNormalizeFast(normal);
943 // add surface normal to vertices
944 aliasvertnorm[a+0] += normal[0];
945 aliasvertnorm[a+1] += normal[1];
946 aliasvertnorm[a+2] += normal[2];
948 aliasvertnorm[b+0] += normal[0];
949 aliasvertnorm[b+1] += normal[1];
950 aliasvertnorm[b+2] += normal[2];
952 aliasvertnorm[c+0] += normal[0];
953 aliasvertnorm[c+1] += normal[1];
954 aliasvertnorm[c+2] += normal[2];
959 // average surface normals
976 void R_DrawZymoticModelMesh(zymtype1header_t *m)
979 rtexture_t **texture;
981 // FIXME: do better fog
982 renderlist = (int *)(m->lump_render.start + (int) m);
983 texture = (rtexture_t **)(m->lump_shaders.start + (int) m);
985 aliasmeshinfo.vertex = aliasvert;
986 aliasmeshinfo.vertexstep = sizeof(float[3]);
987 aliasmeshinfo.color = aliasvertcolor;
988 aliasmeshinfo.colorstep = sizeof(float[4]);
989 aliasmeshinfo.texcoords[0] = (float *)(m->lump_texcoords.start + (int) m);
990 aliasmeshinfo.texcoordstep[0] = sizeof(float[2]);
992 for (i = 0;i < m->numshaders;i++)
994 aliasmeshinfo.tex[0] = R_GetTexture(texture[i]);
995 if (currentrenderentity->effects & EF_ADDITIVE)
997 aliasmeshinfo.transparent = true;
998 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
999 aliasmeshinfo.blendfunc2 = GL_ONE;
1001 else if (currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(texture[i]))
1003 aliasmeshinfo.transparent = true;
1004 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
1005 aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
1009 aliasmeshinfo.transparent = false;
1010 aliasmeshinfo.blendfunc1 = GL_ONE;
1011 aliasmeshinfo.blendfunc2 = GL_ZERO;
1013 aliasmeshinfo.numtriangles = *renderlist++;
1014 aliasmeshinfo.index = renderlist;
1015 c_alias_polys += aliasmeshinfo.numtriangles;
1016 R_Mesh_Draw(&aliasmeshinfo);
1017 renderlist += aliasmeshinfo.numtriangles * 3;
1021 void R_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m)
1026 // FIXME: do better fog
1027 renderlist = (int *)(m->lump_render.start + (int) m);
1029 aliasmeshinfo.tex[0] = 0;
1030 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
1031 aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
1033 VectorSubtract(org, r_origin, diff);
1034 aliasmeshinfo.cr = fogcolor[0];
1035 aliasmeshinfo.cg = fogcolor[1];
1036 aliasmeshinfo.cb = fogcolor[2];
1037 aliasmeshinfo.ca = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff));
1039 for (i = 0;i < m->numshaders;i++)
1041 aliasmeshinfo.numtriangles = *renderlist++;
1042 aliasmeshinfo.index = renderlist;
1043 c_alias_polys += aliasmeshinfo.numtriangles;
1044 R_Mesh_Draw(&aliasmeshinfo);
1045 renderlist += aliasmeshinfo.numtriangles * 3;
1049 void R_DrawZymoticModel (void)
1053 zymtype1header_t *m;
1056 // FIXME: do better fog
1057 m = currentrenderentity->model->zymdata_header;
1062 zymdebug = r_zymdebug.integer;
1064 angles[0] = currentrenderentity->angles[1];
1065 angles[1] = currentrenderentity->angles[0] + 180;
1066 angles[2] = -currentrenderentity->angles[2];
1069 angles[0] = currentrenderentity->angles[0];
1070 angles[1] = currentrenderentity->angles[1];
1071 angles[2] = currentrenderentity->angles[2];
1075 switch (zymdebug % 6)
1077 case 0: a = 0;b = 1;c = 2;break;
1078 case 1: a = 1;b = 0;c = 2;break;
1079 case 2: a = 2;b = 0;c = 1;break;
1080 case 3: a = 0;b = 2;c = 1;break;
1081 case 4: a = 1;b = 2;c = 0;break;
1082 case 5: a = 2;b = 1;c = 0;break;
1085 angles[0] = currentrenderentity->angles[a];
1086 angles[1] = currentrenderentity->angles[b];
1087 angles[2] = currentrenderentity->angles[c];
1089 angles[0] = -angles[0];
1092 angles[1] = -angles[1];
1095 angles[2] = -angles[2];
1097 angles[0] += (zymdebug & 3) * 90;
1099 angles[1] += (zymdebug & 3) * 90;
1101 angles[2] += (zymdebug & 3) * 90;
1105 if (ZymoticLerpBones(m->numbones, (zymbonematrix *)(m->lump_poses.start + (int) m), currentrenderentity->frameblend, (zymbone_t *)(m->lump_bones.start + (int) m)/*, currentrenderentity->origin, angles, currentrenderentity->scale*/))
1106 ZymoticTransformVerts(m->numverts, (int *)(m->lump_vertbonecounts.start + (int) m), (zymvertex_t *)(m->lump_verts.start + (int) m));
1107 if (bestdist < r_zymdebug_dist.value)
1109 Cvar_SetValueQuick(&r_zymdebug, r_zymdebug.integer + 1);
1110 if (zymdebug) // if there is some leftover, unclaimed, don't repeat
1111 Cvar_SetValueQuick(&r_zymdebug, 0);
1114 Con_Printf("trying %i, bestdist was: %f\n", r_zymdebug.integer, bestdist);
1117 ZymoticCalcNormals(m->numverts, m->numshaders, (int *)(m->lump_render.start + (int) m));
1119 R_LightModel(m->numverts);
1121 memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo));
1122 aliasmeshinfo.numverts = m->numverts;
1124 R_DrawZymoticModelMesh(m);
1127 R_DrawZymoticModelMeshFog(currentrenderentity->origin, m);
1130 void R_DrawAliasModel (void)
1132 if (currentrenderentity->alpha < (1.0f / 64.0f))
1133 return; // basically completely transparent
1137 softwaretransformforentity(currentrenderentity);
1139 if (currentrenderentity->model->aliastype == ALIASTYPE_ZYM)
1140 R_DrawZymoticModel();
1141 else if (currentrenderentity->model->aliastype == ALIASTYPE_MD2)
1142 R_DrawQ2AliasModel();
1144 R_DrawQ1AliasModel();