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][3]));
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 += 3;
123 VectorCopy(av, point);softwaretransform(point, av);av += 3;
124 VectorCopy(av, point);softwaretransform(point, av);av += 3;
125 VectorCopy(av, point);softwaretransform(point, av);av += 3;
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 += 3;
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 GL_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 softwaretransformforentity(currentrenderentity);
316 frame1 = &model->mdlmd2data_frames[currentrenderentity->frameblend[0].frame];
317 frame2 = &model->mdlmd2data_frames[currentrenderentity->frameblend[1].frame];
318 frame3 = &model->mdlmd2data_frames[currentrenderentity->frameblend[2].frame];
319 frame4 = &model->mdlmd2data_frames[currentrenderentity->frameblend[3].frame];
320 frame1verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[0].frame * model->numverts];
321 frame2verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[1].frame * model->numverts];
322 frame3verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[2].frame * model->numverts];
323 frame4verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[3].frame * model->numverts];
325 if (currentrenderentity->frameblend[0].lerp)
326 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]);
327 if (currentrenderentity->frameblend[1].lerp)
328 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]);
329 if (currentrenderentity->frameblend[2].lerp)
330 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]);
331 if (currentrenderentity->frameblend[3].lerp)
332 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]);
334 R_AliasLerpVerts(model->numverts,
335 currentrenderentity->frameblend[0].lerp, frame1verts, frame1->scale, frame1->translate,
336 currentrenderentity->frameblend[1].lerp, frame2verts, frame2->scale, frame2->translate,
337 currentrenderentity->frameblend[2].lerp, frame3verts, frame3->scale, frame3->translate,
338 currentrenderentity->frameblend[3].lerp, frame4verts, frame4->scale, frame4->translate);
339 R_AliasTransformVerts(model->numverts);
341 R_LightModel(model->numverts);
344 void R_DrawQ1AliasModel (void)
349 skinframe_t *skinframe;
351 model = currentrenderentity->model;
353 R_SetupMDLMD2Frames(&skinframe);
355 memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo));
357 aliasmeshinfo.vertex = aliasvert;
358 aliasmeshinfo.vertexstep = sizeof(float[3]);
359 aliasmeshinfo.numverts = model->numverts;
360 aliasmeshinfo.numtriangles = model->numtris;
361 aliasmeshinfo.index = model->mdldata_indices;
362 aliasmeshinfo.colorstep = sizeof(float[4]);
363 aliasmeshinfo.texcoords[0] = model->mdldata_texcoords;
364 aliasmeshinfo.texcoordstep[0] = sizeof(float[2]);
369 VectorSubtract(currentrenderentity->origin, r_origin, diff);
370 fog = DotProduct(diff,diff);
373 fog = exp(fogdensity/fog);
378 // fog method: darken, additive fog
379 // 1. render model as normal, scaled by inverse of fog alpha (darkens it)
380 // 2. render fog as additive
383 if (currentrenderentity->effects & EF_ADDITIVE)
385 aliasmeshinfo.transparent = true;
386 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
387 aliasmeshinfo.blendfunc2 = GL_ONE;
389 else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL)
391 aliasmeshinfo.transparent = true;
392 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
393 aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
397 aliasmeshinfo.transparent = false;
398 aliasmeshinfo.blendfunc1 = GL_ONE;
399 aliasmeshinfo.blendfunc2 = GL_ZERO;
404 R_TintModel(aliasvertcolor, aliasvertcolor, model->numverts, 1 - fog, 1 - fog, 1 - fog);
406 if (skinframe->base || skinframe->pants || skinframe->shirt || skinframe->glow || skinframe->merged)
408 if (currentrenderentity->colormap >= 0 && (skinframe->base || skinframe->pants || skinframe->shirt))
413 GL_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
414 if (skinframe->pants)
416 c = (currentrenderentity->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
417 color = (byte *) (&d_8to24table[c]);
418 if (c >= 224) // fullbright ranges
419 GL_DrawModelMesh(skinframe->pants, 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 GL_DrawModelMesh(skinframe->pants, aliasvertcolor2, 0, 0, 0);
426 if (skinframe->shirt)
428 c = currentrenderentity->colormap & 0xF0 ;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
429 color = (byte *) (&d_8to24table[c]);
430 if (c >= 224) // fullbright ranges
431 GL_DrawModelMesh(skinframe->shirt, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
434 R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
435 GL_DrawModelMesh(skinframe->shirt, aliasvertcolor2, 0, 0, 0);
441 if (skinframe->merged)
442 GL_DrawModelMesh(skinframe->merged, aliasvertcolor, 0, 0, 0);
445 if (skinframe->base) GL_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
446 if (skinframe->pants) GL_DrawModelMesh(skinframe->pants, aliasvertcolor, 0, 0, 0);
447 if (skinframe->shirt) GL_DrawModelMesh(skinframe->shirt, aliasvertcolor, 0, 0, 0);
450 if (skinframe->glow) GL_DrawModelMesh(skinframe->glow, NULL, 1 - fog, 1 - fog, 1 - fog);
453 GL_DrawModelMesh(0, NULL, 1 - fog, 1 - fog, 1 - fog);
457 aliasmeshinfo.tex[0] = R_GetTexture(skinframe->fog);
458 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
459 aliasmeshinfo.blendfunc2 = GL_ONE;
460 aliasmeshinfo.color = NULL;
462 aliasmeshinfo.cr = fogcolor[0];
463 aliasmeshinfo.cg = fogcolor[1];
464 aliasmeshinfo.cb = fogcolor[2];
465 aliasmeshinfo.ca = currentrenderentity->alpha * fog;
467 c_alias_polys += aliasmeshinfo.numtriangles;
468 R_Mesh_Draw(&aliasmeshinfo);
472 void R_DrawQ2AliasModel (void)
476 skinframe_t *skinframe;
479 model = currentrenderentity->model;
481 R_SetupMDLMD2Frames(&skinframe);
483 if (!r_render.integer)
486 // FIXME FIXME FIXME rewrite loader to convert to triangle mesh
487 glBindTexture(GL_TEXTURE_2D, R_GetTexture(skinframe->base));
489 if (currentrenderentity->effects & EF_ADDITIVE)
491 glBlendFunc(GL_SRC_ALPHA, GL_ONE); // additive rendering
495 else if (currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(skinframe->base))
497 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
507 // LordHavoc: big mess...
508 // using vertex arrays only slightly, although it is enough to prevent duplicates
509 // (saving half the transforms)
510 glVertexPointer(3, GL_FLOAT, sizeof(float[3]), aliasvert);
511 glColorPointer(4, GL_FLOAT, sizeof(float[4]), aliasvertcolor);
512 glEnableClientState(GL_VERTEX_ARRAY);
513 glEnableClientState(GL_COLOR_ARRAY);
515 GL_LockArray(0, model->numverts);
517 order = model->md2data_glcmds;
520 if (!(count = *order++))
523 glBegin(GL_TRIANGLE_STRIP);
526 glBegin(GL_TRIANGLE_FAN);
531 glTexCoord2f(((float *)order)[0], ((float *)order)[1]);
532 glArrayElement(order[2]);
540 glDisableClientState(GL_COLOR_ARRAY);
541 glDisableClientState(GL_VERTEX_ARRAY);
545 glDisable (GL_TEXTURE_2D);
546 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
548 glDepthMask(0); // disable zbuffer updates
550 VectorSubtract(currentrenderentity->origin, r_origin, diff);
551 glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff)));
553 // LordHavoc: big mess...
554 // using vertex arrays only slightly, although it is enough to prevent duplicates
555 // (saving half the transforms)
556 glVertexPointer(3, GL_FLOAT, sizeof(float[3]), aliasvert);
557 glEnableClientState(GL_VERTEX_ARRAY);
559 GL_LockArray(0, model->numverts);
561 order = model->md2data_glcmds;
564 if (!(count = *order++))
567 glBegin(GL_TRIANGLE_STRIP);
570 glBegin(GL_TRIANGLE_FAN);
575 glArrayElement(order[2]);
583 glDisableClientState(GL_VERTEX_ARRAY);
585 glEnable (GL_TEXTURE_2D);
589 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
594 void ZymoticLerpBones(int count, zymbonematrix *bonebase, frameblend_t *blend, zymbone_t *bone, float rootorigin[3], float rootangles[3], float rootscale)
596 float lerp1, lerp2, lerp3, lerp4;
597 zymbonematrix *out, rootmatrix, m, *bone1, *bone2, *bone3, *bone4;
599 AngleVectors(rootangles, rootmatrix.m[0], rootmatrix.m[1], rootmatrix.m[2]);
600 VectorScale(rootmatrix.m[0], rootscale, rootmatrix.m[0]);
601 VectorScale(rootmatrix.m[1], rootscale, rootmatrix.m[1]);
602 VectorScale(rootmatrix.m[2], rootscale, rootmatrix.m[2]);
603 rootmatrix.m[0][3] = rootorigin[0];
604 rootmatrix.m[1][3] = rootorigin[1];
605 rootmatrix.m[2][3] = rootorigin[2];
606 bone1 = bonebase + blend[0].frame * count;
607 lerp1 = blend[0].lerp;
610 bone2 = bonebase + blend[1].frame * count;
611 lerp2 = blend[1].lerp;
614 bone3 = bonebase + blend[2].frame * count;
615 lerp3 = blend[2].lerp;
619 bone4 = bonebase + blend[3].frame * count;
620 lerp4 = blend[3].lerp;
623 // interpolate matrices
624 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3 + bone4->m[0][0] * lerp4;
625 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3 + bone4->m[0][1] * lerp4;
626 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3 + bone4->m[0][2] * lerp4;
627 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3 + bone4->m[0][3] * lerp4;
628 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3 + bone4->m[1][0] * lerp4;
629 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3 + bone4->m[1][1] * lerp4;
630 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3 + bone4->m[1][2] * lerp4;
631 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3 + bone4->m[1][3] * lerp4;
632 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3 + bone4->m[2][0] * lerp4;
633 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3 + bone4->m[2][1] * lerp4;
634 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3 + bone4->m[2][2] * lerp4;
635 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3 + bone4->m[2][3] * lerp4;
636 if (bone->parent >= 0)
637 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
639 R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
653 // interpolate matrices
654 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3;
655 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3;
656 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3;
657 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3;
658 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3;
659 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3;
660 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3;
661 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3;
662 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3;
663 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3;
664 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3;
665 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3;
666 if (bone->parent >= 0)
667 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
669 R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
683 // interpolate matrices
684 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2;
685 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2;
686 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2;
687 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2;
688 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2;
689 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2;
690 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2;
691 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2;
692 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2;
693 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2;
694 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2;
695 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2;
696 if (bone->parent >= 0)
697 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
699 R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
715 // interpolate matrices
716 m.m[0][0] = bone1->m[0][0] * lerp1;
717 m.m[0][1] = bone1->m[0][1] * lerp1;
718 m.m[0][2] = bone1->m[0][2] * lerp1;
719 m.m[0][3] = bone1->m[0][3] * lerp1;
720 m.m[1][0] = bone1->m[1][0] * lerp1;
721 m.m[1][1] = bone1->m[1][1] * lerp1;
722 m.m[1][2] = bone1->m[1][2] * lerp1;
723 m.m[1][3] = bone1->m[1][3] * lerp1;
724 m.m[2][0] = bone1->m[2][0] * lerp1;
725 m.m[2][1] = bone1->m[2][1] * lerp1;
726 m.m[2][2] = bone1->m[2][2] * lerp1;
727 m.m[2][3] = bone1->m[2][3] * lerp1;
728 if (bone->parent >= 0)
729 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
731 R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
742 if (bone->parent >= 0)
743 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &bone1->m[0], &out->m[0]);
745 R_ConcatTransforms(&rootmatrix.m[0], &bone1->m[0], &out->m[0]);
754 void ZymoticTransformVerts(int vertcount, int *bonecounts, zymvertex_t *vert)
757 float *out = aliasvert;
758 zymbonematrix *matrix;
762 // FIXME: validate bonecounts at load time (must be >= 1)
765 matrix = &zymbonepose[vert->bonenum];
766 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];
767 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];
768 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];
776 matrix = &zymbonepose[vert->bonenum];
777 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];
778 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];
779 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];
787 void ZymoticCalcNormals(int vertcount, int shadercount, int *renderlist)
790 float *out, v1[3], v2[3], normal[3];
793 memset(aliasvertnorm, 0, sizeof(float[3]) * vertcount);
794 memset(aliasvertusage, 0, sizeof(int) * vertcount);
795 // parse render list and accumulate surface normals
804 v1[0] = aliasvert[a+0] - aliasvert[b+0];
805 v1[1] = aliasvert[a+1] - aliasvert[b+1];
806 v1[2] = aliasvert[a+2] - aliasvert[b+2];
807 v2[0] = aliasvert[c+0] - aliasvert[b+0];
808 v2[1] = aliasvert[c+1] - aliasvert[b+1];
809 v2[2] = aliasvert[c+2] - aliasvert[b+2];
810 CrossProduct(v1, v2, normal);
811 VectorNormalizeFast(normal);
812 // add surface normal to vertices
813 aliasvertnorm[a+0] += normal[0];
814 aliasvertnorm[a+1] += normal[1];
815 aliasvertnorm[a+2] += normal[2];
817 aliasvertnorm[b+0] += normal[0];
818 aliasvertnorm[b+1] += normal[1];
819 aliasvertnorm[b+2] += normal[2];
821 aliasvertnorm[c+0] += normal[0];
822 aliasvertnorm[c+1] += normal[1];
823 aliasvertnorm[c+2] += normal[2];
828 // average surface normals
845 void GL_DrawZymoticModelMesh(zymtype1header_t *m)
848 rtexture_t **texture;
850 // FIXME: do better fog
851 renderlist = (int *)(m->lump_render.start + (int) m);
852 texture = (rtexture_t **)(m->lump_shaders.start + (int) m);
854 aliasmeshinfo.vertex = aliasvert;
855 aliasmeshinfo.vertexstep = sizeof(float[3]);
856 aliasmeshinfo.color = aliasvertcolor;
857 aliasmeshinfo.colorstep = sizeof(float[4]);
858 aliasmeshinfo.texcoords[0] = (float *)(m->lump_texcoords.start + (int) m);
859 aliasmeshinfo.texcoordstep[0] = sizeof(float[2]);
861 for (i = 0;i < m->numshaders;i++)
863 aliasmeshinfo.tex[0] = R_GetTexture(*texture);
864 aliasmeshinfo.tex[1] = 0;
865 if (currentrenderentity->effects & EF_ADDITIVE)
867 aliasmeshinfo.transparent = true;
868 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
869 aliasmeshinfo.blendfunc2 = GL_ONE;
871 else if (currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(*texture))
873 aliasmeshinfo.transparent = true;
874 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
875 aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
879 aliasmeshinfo.transparent = false;
880 aliasmeshinfo.blendfunc1 = GL_ONE;
881 aliasmeshinfo.blendfunc2 = GL_ZERO;
883 aliasmeshinfo.numtriangles = *renderlist++;
884 aliasmeshinfo.index = renderlist;
885 c_alias_polys += aliasmeshinfo.numtriangles;
886 R_Mesh_Draw(&aliasmeshinfo);
887 renderlist += aliasmeshinfo.numtriangles * 3;
891 void GL_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m)
896 // FIXME: do better fog
897 renderlist = (int *)(m->lump_render.start + (int) m);
899 aliasmeshinfo.tex[0] = 0;
900 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
901 aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
903 VectorSubtract(org, r_origin, diff);
904 aliasmeshinfo.cr = fogcolor[0];
905 aliasmeshinfo.cg = fogcolor[1];
906 aliasmeshinfo.cb = fogcolor[2];
907 aliasmeshinfo.ca = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff));
909 for (i = 0;i < m->numshaders;i++)
911 aliasmeshinfo.numtriangles = *renderlist++;
912 aliasmeshinfo.index = renderlist;
913 c_alias_polys += aliasmeshinfo.numtriangles;
914 R_Mesh_Draw(&aliasmeshinfo);
915 renderlist += aliasmeshinfo.numtriangles * 3;
919 void R_DrawZymoticModel (void)
923 // FIXME: do better fog
924 m = currentrenderentity->model->zymdata_header;
925 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);
926 ZymoticTransformVerts(m->numverts, (int *)(m->lump_vertbonecounts.start + (int) m), (zymvertex_t *)(m->lump_verts.start + (int) m));
927 ZymoticCalcNormals(m->numverts, m->numshaders, (int *)(m->lump_render.start + (int) m));
929 R_LightModel(m->numverts);
931 memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo));
932 aliasmeshinfo.numverts = m->numverts;
934 GL_DrawZymoticModelMesh(m);
937 GL_DrawZymoticModelMeshFog(currentrenderentity->origin, m);
940 void R_DrawAliasModel (void)
942 if (currentrenderentity->alpha < (1.0f / 64.0f))
943 return; // basically completely transparent
947 if (currentrenderentity->model->aliastype == ALIASTYPE_ZYM)
948 R_DrawZymoticModel ();
949 else if (currentrenderentity->model->aliastype == ALIASTYPE_MD2)
950 R_DrawQ2AliasModel ();
952 R_DrawQ1AliasModel ();