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 R_Mesh_Draw(&aliasmeshinfo);
282 // leave it in a state for additional passes
283 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
284 aliasmeshinfo.blendfunc2 = GL_ONE;
287 void R_TintModel(float *in, float *out, int verts, float r, float g, float b)
290 for (i = 0;i < verts;i++)
301 void R_SetupMDLMD2Frames(skinframe_t **skinframe)
303 md2frame_t *frame1, *frame2, *frame3, *frame4;
304 trivertx_t *frame1verts, *frame2verts, *frame3verts, *frame4verts;
306 model = currentrenderentity->model;
308 if (model->skinscenes[currentrenderentity->skinnum].framecount > 1)
309 *skinframe = &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe + (int) (cl.time * 10) % model->skinscenes[currentrenderentity->skinnum].framecount];
311 *skinframe = &model->skinframes[model->skinscenes[currentrenderentity->skinnum].firstframe];
313 softwaretransformforentity(currentrenderentity);
315 frame1 = &model->mdlmd2data_frames[currentrenderentity->frameblend[0].frame];
316 frame2 = &model->mdlmd2data_frames[currentrenderentity->frameblend[1].frame];
317 frame3 = &model->mdlmd2data_frames[currentrenderentity->frameblend[2].frame];
318 frame4 = &model->mdlmd2data_frames[currentrenderentity->frameblend[3].frame];
319 frame1verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[0].frame * model->numverts];
320 frame2verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[1].frame * model->numverts];
321 frame3verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[2].frame * model->numverts];
322 frame4verts = &model->mdlmd2data_pose[currentrenderentity->frameblend[3].frame * model->numverts];
324 if (currentrenderentity->frameblend[0].lerp)
325 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]);
326 if (currentrenderentity->frameblend[1].lerp)
327 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]);
328 if (currentrenderentity->frameblend[2].lerp)
329 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]);
330 if (currentrenderentity->frameblend[3].lerp)
331 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]);
333 R_AliasLerpVerts(model->numverts,
334 currentrenderentity->frameblend[0].lerp, frame1verts, frame1->scale, frame1->translate,
335 currentrenderentity->frameblend[1].lerp, frame2verts, frame2->scale, frame2->translate,
336 currentrenderentity->frameblend[2].lerp, frame3verts, frame3->scale, frame3->translate,
337 currentrenderentity->frameblend[3].lerp, frame4verts, frame4->scale, frame4->translate);
338 R_AliasTransformVerts(model->numverts);
340 R_LightModel(model->numverts);
343 void R_DrawQ1AliasModel (void)
348 skinframe_t *skinframe;
350 model = currentrenderentity->model;
352 R_SetupMDLMD2Frames(&skinframe);
354 memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo));
356 aliasmeshinfo.vertex = aliasvert;
357 aliasmeshinfo.vertexstep = sizeof(float[3]);
358 aliasmeshinfo.numverts = model->numverts;
359 aliasmeshinfo.numtriangles = model->numtris;
360 aliasmeshinfo.index = model->mdldata_indices;
361 aliasmeshinfo.colorstep = sizeof(float[4]);
362 aliasmeshinfo.texcoords[0] = model->mdldata_texcoords;
363 aliasmeshinfo.texcoordstep[0] = sizeof(float[2]);
368 VectorSubtract(currentrenderentity->origin, r_origin, diff);
369 fog = exp(fogdensity/DotProduct(diff,diff));
374 // fog method: darken, additive fog
375 // 1. render model as normal, scaled by inverse of fog alpha (darkens it)
376 // 2. render fog as additive
379 if (currentrenderentity->effects & EF_ADDITIVE)
381 aliasmeshinfo.transparent = true;
382 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
383 aliasmeshinfo.blendfunc2 = GL_ONE;
385 else if (currentrenderentity->alpha != 1.0 || skinframe->fog != NULL)
387 aliasmeshinfo.transparent = true;
388 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
389 aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
393 aliasmeshinfo.transparent = false;
394 aliasmeshinfo.blendfunc1 = GL_ONE;
395 aliasmeshinfo.blendfunc2 = GL_ZERO;
400 R_TintModel(aliasvertcolor, aliasvertcolor, model->numverts, 1 - fog, 1 - fog, 1 - fog);
402 if (skinframe->base || skinframe->pants || skinframe->shirt || skinframe->glow || skinframe->merged)
404 if (currentrenderentity->colormap >= 0 && (skinframe->base || skinframe->pants || skinframe->shirt))
409 GL_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
410 if (skinframe->pants)
412 c = (currentrenderentity->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
413 color = (byte *) (&d_8to24table[c]);
414 if (c >= 224) // fullbright ranges
415 GL_DrawModelMesh(skinframe->pants, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
418 R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
419 GL_DrawModelMesh(skinframe->pants, aliasvertcolor2, 0, 0, 0);
422 if (skinframe->shirt)
424 c = currentrenderentity->colormap & 0xF0 ;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
425 color = (byte *) (&d_8to24table[c]);
426 if (c >= 224) // fullbright ranges
427 GL_DrawModelMesh(skinframe->shirt, NULL, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
430 R_TintModel(aliasvertcolor, aliasvertcolor2, model->numverts, color[0] * (1.0f / 255.0f), color[1] * (1.0f / 255.0f), color[2] * (1.0f / 255.0f));
431 GL_DrawModelMesh(skinframe->shirt, aliasvertcolor2, 0, 0, 0);
437 if (skinframe->merged)
438 GL_DrawModelMesh(skinframe->merged, aliasvertcolor, 0, 0, 0);
441 if (skinframe->base) GL_DrawModelMesh(skinframe->base, aliasvertcolor, 0, 0, 0);
442 if (skinframe->pants) GL_DrawModelMesh(skinframe->pants, aliasvertcolor, 0, 0, 0);
443 if (skinframe->shirt) GL_DrawModelMesh(skinframe->shirt, aliasvertcolor, 0, 0, 0);
446 if (skinframe->glow) GL_DrawModelMesh(skinframe->glow, NULL, 1 - fog, 1 - fog, 1 - fog);
449 GL_DrawModelMesh(0, NULL, 1 - fog, 1 - fog, 1 - fog);
453 aliasmeshinfo.tex[0] = R_GetTexture(skinframe->fog);
454 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
455 aliasmeshinfo.blendfunc2 = GL_ONE;
456 aliasmeshinfo.color = NULL;
458 aliasmeshinfo.cr = fogcolor[0];
459 aliasmeshinfo.cg = fogcolor[1];
460 aliasmeshinfo.cb = fogcolor[2];
461 aliasmeshinfo.ca = currentrenderentity->alpha * fog;
463 R_Mesh_Draw(&aliasmeshinfo);
467 void R_DrawQ2AliasModel (void)
471 skinframe_t *skinframe;
474 model = currentrenderentity->model;
476 R_SetupMDLMD2Frames(&skinframe);
478 if (!r_render.integer)
481 // FIXME FIXME FIXME rewrite loader to convert to triangle mesh
482 glBindTexture(GL_TEXTURE_2D, R_GetTexture(skinframe->base));
484 if (currentrenderentity->effects & EF_ADDITIVE)
486 glBlendFunc(GL_SRC_ALPHA, GL_ONE); // additive rendering
490 else if (currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(skinframe->base))
492 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
502 // LordHavoc: big mess...
503 // using vertex arrays only slightly, although it is enough to prevent duplicates
504 // (saving half the transforms)
505 glVertexPointer(3, GL_FLOAT, sizeof(float[3]), aliasvert);
506 glColorPointer(4, GL_FLOAT, sizeof(float[4]), aliasvertcolor);
507 glEnableClientState(GL_VERTEX_ARRAY);
508 glEnableClientState(GL_COLOR_ARRAY);
510 GL_LockArray(0, model->numverts);
512 order = model->md2data_glcmds;
515 if (!(count = *order++))
518 glBegin(GL_TRIANGLE_STRIP);
521 glBegin(GL_TRIANGLE_FAN);
526 glTexCoord2f(((float *)order)[0], ((float *)order)[1]);
527 glArrayElement(order[2]);
535 glDisableClientState(GL_COLOR_ARRAY);
536 glDisableClientState(GL_VERTEX_ARRAY);
540 glDisable (GL_TEXTURE_2D);
541 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
543 glDepthMask(0); // disable zbuffer updates
545 VectorSubtract(currentrenderentity->origin, r_origin, diff);
546 glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff)));
548 // LordHavoc: big mess...
549 // using vertex arrays only slightly, although it is enough to prevent duplicates
550 // (saving half the transforms)
551 glVertexPointer(3, GL_FLOAT, sizeof(float[3]), aliasvert);
552 glEnableClientState(GL_VERTEX_ARRAY);
554 GL_LockArray(0, model->numverts);
556 order = model->md2data_glcmds;
559 if (!(count = *order++))
562 glBegin(GL_TRIANGLE_STRIP);
565 glBegin(GL_TRIANGLE_FAN);
570 glArrayElement(order[2]);
578 glDisableClientState(GL_VERTEX_ARRAY);
580 glEnable (GL_TEXTURE_2D);
584 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
589 void ZymoticLerpBones(int count, zymbonematrix *bonebase, frameblend_t *blend, zymbone_t *bone, float rootorigin[3], float rootangles[3], float rootscale)
591 float lerp1, lerp2, lerp3, lerp4;
592 zymbonematrix *out, rootmatrix, m, *bone1, *bone2, *bone3, *bone4;
594 AngleVectors(rootangles, rootmatrix.m[0], rootmatrix.m[1], rootmatrix.m[2]);
595 VectorScale(rootmatrix.m[0], rootscale, rootmatrix.m[0]);
596 VectorScale(rootmatrix.m[1], rootscale, rootmatrix.m[1]);
597 VectorScale(rootmatrix.m[2], rootscale, rootmatrix.m[2]);
598 rootmatrix.m[0][3] = rootorigin[0];
599 rootmatrix.m[1][3] = rootorigin[1];
600 rootmatrix.m[2][3] = rootorigin[2];
601 bone1 = bonebase + blend[0].frame * count;
602 lerp1 = blend[0].lerp;
605 bone2 = bonebase + blend[1].frame * count;
606 lerp2 = blend[1].lerp;
609 bone3 = bonebase + blend[2].frame * count;
610 lerp3 = blend[2].lerp;
614 bone4 = bonebase + blend[3].frame * count;
615 lerp4 = blend[3].lerp;
618 // interpolate matrices
619 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3 + bone4->m[0][0] * lerp4;
620 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3 + bone4->m[0][1] * lerp4;
621 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3 + bone4->m[0][2] * lerp4;
622 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3 + bone4->m[0][3] * lerp4;
623 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3 + bone4->m[1][0] * lerp4;
624 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3 + bone4->m[1][1] * lerp4;
625 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3 + bone4->m[1][2] * lerp4;
626 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3 + bone4->m[1][3] * lerp4;
627 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3 + bone4->m[2][0] * lerp4;
628 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3 + bone4->m[2][1] * lerp4;
629 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3 + bone4->m[2][2] * lerp4;
630 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3 + bone4->m[2][3] * lerp4;
631 if (bone->parent >= 0)
632 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
634 R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
648 // interpolate matrices
649 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3;
650 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3;
651 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3;
652 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3;
653 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3;
654 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3;
655 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3;
656 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3;
657 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3;
658 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3;
659 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3;
660 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3;
661 if (bone->parent >= 0)
662 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
664 R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
678 // interpolate matrices
679 m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2;
680 m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2;
681 m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2;
682 m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2;
683 m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2;
684 m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2;
685 m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2;
686 m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2;
687 m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2;
688 m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2;
689 m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2;
690 m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2;
691 if (bone->parent >= 0)
692 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
694 R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
710 // interpolate matrices
711 m.m[0][0] = bone1->m[0][0] * lerp1;
712 m.m[0][1] = bone1->m[0][1] * lerp1;
713 m.m[0][2] = bone1->m[0][2] * lerp1;
714 m.m[0][3] = bone1->m[0][3] * lerp1;
715 m.m[1][0] = bone1->m[1][0] * lerp1;
716 m.m[1][1] = bone1->m[1][1] * lerp1;
717 m.m[1][2] = bone1->m[1][2] * lerp1;
718 m.m[1][3] = bone1->m[1][3] * lerp1;
719 m.m[2][0] = bone1->m[2][0] * lerp1;
720 m.m[2][1] = bone1->m[2][1] * lerp1;
721 m.m[2][2] = bone1->m[2][2] * lerp1;
722 m.m[2][3] = bone1->m[2][3] * lerp1;
723 if (bone->parent >= 0)
724 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &m.m[0], &out->m[0]);
726 R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
737 if (bone->parent >= 0)
738 R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &bone1->m[0], &out->m[0]);
740 R_ConcatTransforms(&rootmatrix.m[0], &bone1->m[0], &out->m[0]);
749 void ZymoticTransformVerts(int vertcount, int *bonecounts, zymvertex_t *vert)
752 float *out = aliasvert;
753 zymbonematrix *matrix;
757 // FIXME: validate bonecounts at load time (must be >= 1)
760 matrix = &zymbonepose[vert->bonenum];
761 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];
762 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];
763 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];
771 matrix = &zymbonepose[vert->bonenum];
772 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];
773 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];
774 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];
782 void ZymoticCalcNormals(int vertcount, int shadercount, int *renderlist)
785 float *out, v1[3], v2[3], normal[3];
788 memset(aliasvertnorm, 0, sizeof(float[3]) * vertcount);
789 memset(aliasvertusage, 0, sizeof(int) * vertcount);
790 // parse render list and accumulate surface normals
799 v1[0] = aliasvert[a+0] - aliasvert[b+0];
800 v1[1] = aliasvert[a+1] - aliasvert[b+1];
801 v1[2] = aliasvert[a+2] - aliasvert[b+2];
802 v2[0] = aliasvert[c+0] - aliasvert[b+0];
803 v2[1] = aliasvert[c+1] - aliasvert[b+1];
804 v2[2] = aliasvert[c+2] - aliasvert[b+2];
805 CrossProduct(v1, v2, normal);
806 VectorNormalizeFast(normal);
807 // add surface normal to vertices
808 aliasvertnorm[a+0] += normal[0];
809 aliasvertnorm[a+1] += normal[1];
810 aliasvertnorm[a+2] += normal[2];
812 aliasvertnorm[b+0] += normal[0];
813 aliasvertnorm[b+1] += normal[1];
814 aliasvertnorm[b+2] += normal[2];
816 aliasvertnorm[c+0] += normal[0];
817 aliasvertnorm[c+1] += normal[1];
818 aliasvertnorm[c+2] += normal[2];
823 // average surface normals
840 void GL_DrawZymoticModelMesh(zymtype1header_t *m)
843 rtexture_t **texture;
845 // FIXME: do better fog
846 renderlist = (int *)(m->lump_render.start + (int) m);
847 texture = (rtexture_t **)(m->lump_shaders.start + (int) m);
849 aliasmeshinfo.vertex = aliasvert;
850 aliasmeshinfo.vertexstep = sizeof(float[3]);
851 aliasmeshinfo.color = aliasvertcolor;
852 aliasmeshinfo.colorstep = sizeof(float[4]);
853 aliasmeshinfo.texcoords[0] = (float *)(m->lump_texcoords.start + (int) m);
854 aliasmeshinfo.texcoordstep[0] = sizeof(float[2]);
856 for (i = 0;i < m->numshaders;i++)
858 aliasmeshinfo.tex[0] = R_GetTexture(*texture);
859 aliasmeshinfo.tex[1] = 0;
860 if (currentrenderentity->effects & EF_ADDITIVE)
862 aliasmeshinfo.transparent = true;
863 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
864 aliasmeshinfo.blendfunc2 = GL_ONE;
866 else if (currentrenderentity->alpha != 1.0 || R_TextureHasAlpha(*texture))
868 aliasmeshinfo.transparent = true;
869 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
870 aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
874 aliasmeshinfo.transparent = false;
875 aliasmeshinfo.blendfunc1 = GL_ONE;
876 aliasmeshinfo.blendfunc2 = GL_ZERO;
878 aliasmeshinfo.numtriangles = *renderlist++;
879 aliasmeshinfo.index = renderlist;
880 R_Mesh_Draw(&aliasmeshinfo);
881 renderlist += aliasmeshinfo.numtriangles * 3;
885 void GL_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m)
890 // FIXME: do better fog
891 renderlist = (int *)(m->lump_render.start + (int) m);
893 aliasmeshinfo.tex[0] = 0;
894 aliasmeshinfo.blendfunc1 = GL_SRC_ALPHA;
895 aliasmeshinfo.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
897 VectorSubtract(org, r_origin, diff);
898 aliasmeshinfo.cr = fogcolor[0];
899 aliasmeshinfo.cg = fogcolor[1];
900 aliasmeshinfo.cb = fogcolor[2];
901 aliasmeshinfo.ca = currentrenderentity->alpha * exp(fogdensity/DotProduct(diff,diff));
903 for (i = 0;i < m->numshaders;i++)
905 aliasmeshinfo.numtriangles = *renderlist++;
906 aliasmeshinfo.index = renderlist;
907 R_Mesh_Draw(&aliasmeshinfo);
908 renderlist += aliasmeshinfo.numtriangles * 3;
912 void R_DrawZymoticModel (void)
916 // FIXME: do better fog
917 m = currentrenderentity->model->zymdata_header;
918 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);
919 ZymoticTransformVerts(m->numverts, (int *)(m->lump_vertbonecounts.start + (int) m), (zymvertex_t *)(m->lump_verts.start + (int) m));
920 ZymoticCalcNormals(m->numverts, m->numshaders, (int *)(m->lump_render.start + (int) m));
922 R_LightModel(m->numverts);
924 memset(&aliasmeshinfo, 0, sizeof(aliasmeshinfo));
925 aliasmeshinfo.numverts = m->numverts;
927 GL_DrawZymoticModelMesh(m);
930 GL_DrawZymoticModelMeshFog(currentrenderentity->origin, m);
933 void R_DrawAliasModel (void)
935 if (currentrenderentity->alpha < (1.0f / 64.0f))
936 return; // basically completely transparent
940 c_alias_polys += currentrenderentity->model->numtris;
941 if (currentrenderentity->model->aliastype == ALIASTYPE_ZYM)
942 R_DrawZymoticModel ();
943 else if (currentrenderentity->model->aliastype == ALIASTYPE_MD2)
944 R_DrawQ2AliasModel ();
946 R_DrawQ1AliasModel ();