]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - gl_models.c
updated to version 1.50, build 75.
[xonotic/darkplaces.git] / gl_models.c
1
2 #include "quakedef.h"
3
4 // LordHavoc: vertex array
5 float *aliasvert;
6 float *aliasvertnorm;
7 byte *aliasvertcolor;
8 byte *aliasvertcolor2;
9
10 int chrometexture;
11
12 void makechrometexture()
13 {
14         int i;
15         byte noise[64*64];
16         byte data[64*64][4];
17
18         fractalnoise(noise, 64);
19
20         // convert to RGBA data
21         for (i = 0;i < 64*64;i++)
22         {
23                 data[i][0] = data[i][1] = data[i][2] = noise[i];
24                 data[i][3] = 255;
25         }
26
27         chrometexture = GL_LoadTexture ("chrometexture", 64, 64, &data[0][0], true, false, 4);
28 }
29
30 void gl_models_start()
31 {
32         // allocate vertex processing arrays
33         aliasvert = malloc(sizeof(float[MD2MAX_VERTS][3]));
34         aliasvertnorm = malloc(sizeof(float[MD2MAX_VERTS][3]));
35         aliasvertcolor = malloc(sizeof(byte[MD2MAX_VERTS][4]));
36         aliasvertcolor2 = malloc(sizeof(byte[MD2MAX_VERTS][4])); // used temporarily for tinted coloring
37         makechrometexture();
38 }
39
40 void gl_models_shutdown()
41 {
42         free(aliasvert);
43         free(aliasvertnorm);
44         free(aliasvertcolor);
45         free(aliasvertcolor2);
46 }
47
48 void GL_Models_Init()
49 {
50         R_RegisterModule("GL_Models", gl_models_start, gl_models_shutdown);
51 }
52
53 extern vec3_t softwaretransform_x;
54 extern vec3_t softwaretransform_y;
55 extern vec3_t softwaretransform_z;
56 extern vec_t softwaretransform_scale;
57 extern vec3_t softwaretransform_offset;
58 void R_AliasLerpVerts(int vertcount, float lerp, trivert2 *verts1, vec3_t scale1, vec3_t translate1, trivert2 *verts2, vec3_t scale2, vec3_t translate2)
59 {
60         int i;
61         vec3_t point, matrix_x, matrix_y, matrix_z;
62         float *av, *avn;
63         av = aliasvert;
64         avn = aliasvertnorm;
65         VectorScale(softwaretransform_x, softwaretransform_scale, matrix_x);
66         VectorScale(softwaretransform_y, softwaretransform_scale, matrix_y);
67         VectorScale(softwaretransform_z, softwaretransform_scale, matrix_z);
68         if (lerp < 0) lerp = 0;
69         if (lerp > 1) lerp = 1;
70         if (lerp != 0)
71         {
72                 float ilerp, ilerp127, lerp127, scalex1, scalex2, translatex, scaley1, scaley2, translatey, scalez1, scalez2, translatez;
73                 if (lerp < 0) lerp = 0;
74                 if (lerp > 1) lerp = 1;
75                 ilerp = 1 - lerp;
76                 ilerp127 = ilerp * (1.0 / 127.0);
77                 lerp127 = lerp * (1.0 / 127.0);
78                 // calculate combined interpolation variables
79                 scalex1 = scale1[0] * ilerp;scalex2 = scale2[0] *  lerp;translatex = translate1[0] * ilerp + translate2[0] *  lerp;
80                 scaley1 = scale1[1] * ilerp;scaley2 = scale2[1] *  lerp;translatey = translate1[1] * ilerp + translate2[1] *  lerp;
81                 scalez1 = scale1[2] * ilerp;scalez2 = scale2[2] *  lerp;translatez = translate1[2] * ilerp + translate2[2] *  lerp;
82                 // generate vertices
83                 for (i = 0;i < vertcount;i++)
84                 {
85                         // rotate, scale, and translate the vertex locations
86                         point[0] = verts1->v[0] * scalex1 + verts2->v[0] * scalex2 + translatex;
87                         point[1] = verts1->v[1] * scaley1 + verts2->v[1] * scaley2 + translatey;
88                         point[2] = verts1->v[2] * scalez1 + verts2->v[2] * scalez2 + translatez;
89                         *av++ = point[0] * matrix_x[0] + point[1] * matrix_y[0] + point[2] * matrix_z[0] + softwaretransform_offset[0];
90                         *av++ = point[0] * matrix_x[1] + point[1] * matrix_y[1] + point[2] * matrix_z[1] + softwaretransform_offset[1];
91                         *av++ = point[0] * matrix_x[2] + point[1] * matrix_y[2] + point[2] * matrix_z[2] + softwaretransform_offset[2];
92                         // rotate the normals
93                         point[0] = verts1->n[0] * ilerp127 + verts2->n[0] * lerp127;
94                         point[1] = verts1->n[1] * ilerp127 + verts2->n[1] * lerp127;
95                         point[2] = verts1->n[2] * ilerp127 + verts2->n[2] * lerp127;
96                         *avn++ = point[0] * softwaretransform_x[0] + point[1] * softwaretransform_y[0] + point[2] * softwaretransform_z[0];
97                         *avn++ = point[0] * softwaretransform_x[1] + point[1] * softwaretransform_y[1] + point[2] * softwaretransform_z[1];
98                         *avn++ = point[0] * softwaretransform_x[2] + point[1] * softwaretransform_y[2] + point[2] * softwaretransform_z[2];
99                         verts1++;verts2++;
100                 }
101         }
102         else
103         {
104                 // generate vertices
105                 for (i = 0;i < vertcount;i++)
106                 {
107                         // rotate, scale, and translate the vertex locations
108                         point[0] = verts1->v[0] * scale1[0] + translate1[0];
109                         point[1] = verts1->v[1] * scale1[1] + translate1[1];
110                         point[2] = verts1->v[2] * scale1[2] + translate1[2];
111                         *av++ = point[0] * matrix_x[0] + point[1] * matrix_y[0] + point[2] * matrix_z[0] + softwaretransform_offset[0];
112                         *av++ = point[0] * matrix_x[1] + point[1] * matrix_y[1] + point[2] * matrix_z[1] + softwaretransform_offset[1];
113                         *av++ = point[0] * matrix_x[2] + point[1] * matrix_y[2] + point[2] * matrix_z[2] + softwaretransform_offset[2];
114                         // rotate the normals
115                         point[0] = verts1->n[0] * (1.0f / 127.0f);
116                         point[1] = verts1->n[1] * (1.0f / 127.0f);
117                         point[2] = verts1->n[2] * (1.0f / 127.0f);
118                         *avn++ = point[0] * softwaretransform_x[0] + point[1] * softwaretransform_y[0] + point[2] * softwaretransform_z[0];
119                         *avn++ = point[0] * softwaretransform_x[1] + point[1] * softwaretransform_y[1] + point[2] * softwaretransform_z[1];
120                         *avn++ = point[0] * softwaretransform_x[2] + point[1] * softwaretransform_y[2] + point[2] * softwaretransform_z[2];
121                         verts1++;
122                 }
123         }
124 }
125
126 float R_CalcAnimLerp(entity_t *ent, int pose, float lerpscale)
127 {
128         if (ent->draw_lastmodel == ent->model && ent->draw_lerpstart <= cl.time)
129         {
130                 if (pose != ent->draw_pose)
131                 {
132                         ent->draw_lastpose = ent->draw_pose;
133                         ent->draw_pose = pose;
134                         ent->draw_lerpstart = cl.time;
135                         return 0;
136                 }
137                 else
138                         return ((cl.time - ent->draw_lerpstart) * lerpscale);
139         }
140         else // uninitialized
141         {
142                 ent->draw_lastmodel = ent->model;
143                 ent->draw_lastpose = ent->draw_pose = pose;
144                 ent->draw_lerpstart = cl.time;
145                 return 0;
146         }
147 }
148
149 extern cvar_t gl_vertexarrays;
150 extern qboolean lighthalf;
151 void GL_DrawModelMesh(int skin, byte *colors, maliashdr_t *maliashdr)
152 {
153         int i;
154         glBindTexture(GL_TEXTURE_2D, skin);
155         if (!colors)
156         {
157                 if (lighthalf)
158                         glColor3f(0.5f, 0.5f, 0.5f);
159                 else
160                         glColor3f(1.0f, 1.0f, 1.0f);
161         }
162         if (gl_vertexarrays.value)
163         {
164 //              qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
165 //              glEnableClientState(GL_VERTEX_ARRAY);
166                 if (colors)
167                 {
168                         qglColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
169                         glEnableClientState(GL_COLOR_ARRAY);
170                 }
171
172                 qglTexCoordPointer(2, GL_FLOAT, 0, (void *)((int) maliashdr->texdata + (int) maliashdr));
173                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
174
175                 qglDrawElements(GL_TRIANGLES, maliashdr->numtris * 3, GL_UNSIGNED_SHORT, (void *)((int) maliashdr + maliashdr->tridata));
176
177                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
178                 /*
179                 // draw the front faces
180                 qglTexCoordPointer(2, GL_FLOAT, 0, (void *)((int) paliashdr->texcoords + (int) paliashdr));
181                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
182                 qglDrawElements(GL_TRIANGLES, paliashdr->frontfaces * 3, GL_UNSIGNED_SHORT, (void *)((int) paliashdr->vertindices + (int) paliashdr));
183                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
184
185                 // draw the back faces
186                 qglTexCoordPointer(2, GL_FLOAT, 0, (void *)((int) paliashdr->texcoords + sizeof(float[2]) * paliashdr->numverts + (int) paliashdr));
187                 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
188                 qglDrawElements(GL_TRIANGLES, paliashdr->backfaces * 3, GL_UNSIGNED_SHORT, (void *)((int) paliashdr->vertindices + sizeof(unsigned short[3]) * paliashdr->frontfaces + (int) paliashdr));
189                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
190                 */
191
192                 if (colors)
193                         glDisableClientState(GL_COLOR_ARRAY);
194 //              glDisableClientState(GL_VERTEX_ARRAY);
195         }
196         else
197         {
198                 unsigned short *in, index;
199                 float *tex;
200                 in = (void *)((int) maliashdr + maliashdr->tridata);
201                 glBegin(GL_TRIANGLES);
202                 tex = (void *)((int) maliashdr + maliashdr->texdata);
203                 for (i = 0;i < maliashdr->numtris * 3;i++)
204                 {
205                         index = *in++;
206                         glTexCoord2f(tex[index*2], tex[index*2+1]);
207                         if (colors)
208                                 glColor4f(colors[index*4] * (1.0f / 255.0f), colors[index*4+1] * (1.0f / 255.0f), colors[index*4+2] * (1.0f / 255.0f), colors[index*4+3] * (1.0f / 255.0f));
209                         glVertex3fv(&aliasvert[index*3]);
210                 }
211                 glEnd();
212                 /*
213                 in = (void *)((int) paliashdr->vertindices + (int) paliashdr);
214                 glBegin(GL_TRIANGLES);
215                 // draw the front faces
216                 tex = (void *)((int) paliashdr->texcoords + (int) paliashdr);
217                 //if (isG200)
218                 //{
219                         for (i = 0;i < paliashdr->frontfaces * 3;i++)
220                         {
221                                 index = *in++;
222                                 glTexCoord2f(tex[index*2], tex[index*2+1]);
223                                 if (colors)
224                                         glColor4f(colors[index*4] * (1.0f / 255.0f), colors[index*4+1] * (1.0f / 255.0f), colors[index*4+2] * (1.0f / 255.0f), colors[index*4+3] * (1.0f / 255.0f));
225                                 glVertex3fv(&aliasvert[index*3]);
226                         }
227                 */
228                 /*
229                 }
230                 else
231                 {
232                         for (i = 0;i < paliashdr->frontfaces * 3;i++)
233                         {
234                                 index = *in++;
235                                 glTexCoord2f(tex[index*2], tex[index*2+1]);
236                                 glColor4ub(colors[index*4], colors[index*4+1], colors[index*4+2], colors[index*4+3]);
237                                 glVertex3fv(&aliasvert[index*3]);
238                         }
239                 }
240                 */
241                 /*
242                 // draw the back faces
243                 tex += 2 * paliashdr->numverts;
244                 //if (isG200)
245                 //{
246                         for (i = 0;i < paliashdr->backfaces * 3;i++)
247                         {
248                                 index = *in++;
249                                 glTexCoord2f(tex[index*2], tex[index*2+1]);
250                                 if (colors)
251                                         glColor4f(colors[index*4] * (1.0f / 255.0f), colors[index*4+1] * (1.0f / 255.0f), colors[index*4+2] * (1.0f / 255.0f), colors[index*4+3] * (1.0f / 255.0f));
252                                 glVertex3fv(&aliasvert[index*3]);
253                         }
254                 */
255                 /*
256                 }
257                 else
258                 {
259                         for (i = 0;i < paliashdr->backfaces * 3;i++)
260                         {
261                                 index = *in++;
262                                 glTexCoord2f(tex[index*2], tex[index*2+1]);
263                                 glColor4ub(colors[index*4], colors[index*4+1], colors[index*4+2], colors[index*4+3]);
264                                 glVertex3fv(&aliasvert[index*3]);
265                         }
266                 }
267                 */
268                 /*
269                 glEnd();
270                 */
271         }
272         // leave it in a state for additional passes
273         glDepthMask(0);
274         glEnable(GL_BLEND);
275         glBlendFunc(GL_SRC_ALPHA, GL_ONE); // additive
276 }
277
278 void R_TintModel(byte *in, byte *out, int verts, byte *color)
279 {
280         int i;
281         byte r = color[0];
282         byte g = color[1];
283         byte b = color[2];
284         for (i = 0;i < verts;i++)
285         {
286                 out[0] = (byte) ((in[0] * r) >> 8);
287                 out[1] = (byte) ((in[1] * g) >> 8);
288                 out[2] = (byte) ((in[2] * b) >> 8);
289                 out[3] =          in[3];
290                 in += 4;
291                 out += 4;
292         }
293 }
294
295 /*
296 =================
297 R_DrawAliasFrame
298
299 =================
300 */
301 extern vec3_t lightspot;
302 void R_LightModel(int numverts, vec3_t center, vec3_t basecolor);
303 void R_DrawAliasFrame (maliashdr_t *maliashdr, float alpha, vec3_t color, entity_t *ent, int shadow, vec3_t org, int frame, int *skin, int colormap, int effects, int flags)
304 {
305         int             i, pose;
306         float   lerpscale, lerp;
307         maliasframe_t *frameinfo;
308
309         softwaretransformforentity(ent);
310
311         if ((frame >= maliashdr->numframes) || (frame < 0))
312         {
313                 Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame);
314                 frame = 0;
315         }
316
317         frameinfo = ((maliasframe_t *)((int) maliashdr + maliashdr->framedata)) + frame;
318         pose = frameinfo->start;
319
320         if (frameinfo->length > 1)
321         {
322                 lerpscale = frameinfo->rate;
323                 pose += (int)(cl.time * frameinfo->rate) % frameinfo->length;
324         }
325         else
326                 lerpscale = 10.0f;
327
328         lerp = R_CalcAnimLerp(ent, pose, lerpscale);
329
330         R_AliasLerpVerts(maliashdr->numverts, lerp, (trivert2 *)((int) maliashdr + maliashdr->posedata) + ent->draw_lastpose * maliashdr->numverts, maliashdr->scale, maliashdr->scale_origin, (trivert2 *)((int) maliashdr + maliashdr->posedata) + ent->draw_pose * maliashdr->numverts, maliashdr->scale, maliashdr->scale_origin);
331
332         // prep the vertex array as early as possible
333         if (gl_vertexarrays.value)
334         {
335                 qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
336                 glEnableClientState(GL_VERTEX_ARRAY);
337         }
338
339         R_LightModel(maliashdr->numverts, org, color);
340
341         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
342         glShadeModel(GL_SMOOTH);
343         if (effects & EF_ADDITIVE)
344         {
345                 glBlendFunc(GL_SRC_ALPHA, GL_ONE); // additive rendering
346                 glEnable(GL_BLEND);
347                 glDepthMask(0);
348         }
349         else if (alpha != 1.0)
350         {
351                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
352                 glEnable(GL_BLEND);
353                 glDepthMask(0);
354         }
355         else
356         {
357                 glDisable(GL_BLEND);
358                 glDepthMask(1);
359         }
360
361         if (colormap >= 0)
362         {
363                 if (!skin[0] && !skin[1] && !skin[2] && !skin[3])
364                         GL_DrawModelMesh(0, NULL, maliashdr);
365                 else
366                 {
367                         int c;
368                         if (skin[0])
369                                 GL_DrawModelMesh(skin[0], aliasvertcolor, maliashdr);
370                         if (skin[1])
371                         {
372                                 c = (colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
373                                 R_TintModel(aliasvertcolor, aliasvertcolor2, maliashdr->numverts, (byte *) (&d_8to24table[c]));
374                                 GL_DrawModelMesh(skin[1], aliasvertcolor2, maliashdr);
375                         }
376                         if (skin[2])
377                         {
378                                 c = colormap & 0xF0      ;c += (c >= 128 && c < 224) ? 4 : 12; // 128-224 are backwards ranges
379                                 R_TintModel(aliasvertcolor, aliasvertcolor2, maliashdr->numverts, (byte *) (&d_8to24table[c]));
380                                 GL_DrawModelMesh(skin[2], aliasvertcolor2, maliashdr);
381                         }
382                         if (skin[3]) GL_DrawModelMesh(skin[3], NULL, maliashdr);
383                 }
384         }
385         else
386         {
387                 if (!skin[3] && !skin[4])
388                         GL_DrawModelMesh(0, NULL, maliashdr);
389                 else
390                 {
391                         if (skin[4]) GL_DrawModelMesh(skin[4], aliasvertcolor, maliashdr);
392                         if (skin[3]) GL_DrawModelMesh(skin[3], NULL, maliashdr);
393                 }
394         }
395
396         if (fogenabled)
397         {
398                 vec3_t diff;
399                 glDisable (GL_TEXTURE_2D);
400                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
401                 glEnable (GL_BLEND);
402                 glDepthMask(0); // disable zbuffer updates
403
404                 VectorSubtract(org, r_refdef.vieworg, diff);
405                 glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
406
407                 if (gl_vertexarrays.value)
408                 {
409 //                      qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
410 //                      glEnableClientState(GL_VERTEX_ARRAY);
411                         qglDrawElements(GL_TRIANGLES, maliashdr->numtris * 3, GL_UNSIGNED_SHORT, (void *)((int) maliashdr + maliashdr->tridata));
412 //                      glDisableClientState(GL_VERTEX_ARRAY);
413                 }
414                 else
415                 {
416                         unsigned short *in;
417                         in = (void *)((int) maliashdr + maliashdr->tridata);
418                         glBegin(GL_TRIANGLES);
419                         for (i = 0;i < maliashdr->numtris * 3;i++)
420                                 glVertex3fv(&aliasvert[*in++ * 3]);
421                         glEnd();
422                 }
423
424                 glEnable (GL_TEXTURE_2D);
425                 glColor3f (1,1,1);
426         }
427         if (gl_vertexarrays.value)
428                 glDisableClientState(GL_VERTEX_ARRAY);
429
430         if (!fogenabled && r_shadows.value && !(effects & EF_ADDITIVE) && shadow)
431         {
432                 // flatten it to make a shadow
433                 float *av = aliasvert + 2, l = lightspot[2] + 0.125;
434                 av = aliasvert + 2;
435                 for (i = 0;i < maliashdr->numverts;i++, av+=3)
436                         if (*av > l)
437                                 *av = l;
438                 glDisable (GL_TEXTURE_2D);
439                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
440                 glEnable (GL_BLEND);
441                 glDepthMask(0); // disable zbuffer updates
442                 glColor4f (0,0,0,0.5 * alpha);
443
444                 if (gl_vertexarrays.value)
445                 {
446                         qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
447                         glEnableClientState(GL_VERTEX_ARRAY);
448                         qglDrawElements(GL_TRIANGLES, maliashdr->numtris * 3, GL_UNSIGNED_SHORT, (void *)((int) maliashdr + maliashdr->tridata));
449                         glDisableClientState(GL_VERTEX_ARRAY);
450                 }
451                 else
452                 {
453                         unsigned short *in;
454                         in = (void *)((int) maliashdr + maliashdr->tridata);
455                         glBegin(GL_TRIANGLES);
456                         for (i = 0;i < maliashdr->numtris * 3;i++)
457                                 glVertex3fv(&aliasvert[*in++ * 3]);
458                         glEnd();
459                 }
460
461                 glEnable (GL_TEXTURE_2D);
462                 glColor3f (1,1,1);
463         }
464
465         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
466         glEnable (GL_BLEND);
467         glDepthMask(1);
468 }
469
470 /*
471 =================
472 R_DrawQ2AliasFrame
473
474 =================
475 */
476 void R_DrawQ2AliasFrame (md2mem_t *pheader, float alpha, vec3_t color, entity_t *ent, int shadow, vec3_t org, int frame, int skin, int effects, int flags)
477 {
478         int *order, count;
479         float lerp;
480         md2memframe_t *frame1, *frame2;
481
482         glBindTexture(GL_TEXTURE_2D, skin);
483
484         softwaretransformforentity(ent);
485
486         if ((frame >= pheader->num_frames) || (frame < 0))
487         {
488                 Con_DPrintf ("R_SetupQ2AliasFrame: no such frame %d\n", frame);
489                 frame = 0;
490         }
491
492         lerp = R_CalcAnimLerp(ent, frame, 10);
493
494         frame1 = (void *)((int) pheader + pheader->ofs_frames + (pheader->framesize * ent->draw_lastpose));
495         frame2 = (void *)((int) pheader + pheader->ofs_frames + (pheader->framesize * ent->draw_pose));
496         R_AliasLerpVerts(pheader->num_xyz, lerp, frame1->verts, frame1->scale, frame1->translate, frame2->verts, frame2->scale, frame2->translate);
497
498         R_LightModel(pheader->num_xyz, org, color);
499
500         if (gl_vertexarrays.value)
501         {
502                 // LordHavoc: big mess...
503                 // using arrays only slightly, although it is enough to prevent duplicates
504                 // (saving half the transforms)
505                 qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
506                 qglColorPointer(4, GL_UNSIGNED_BYTE, 0, aliasvertcolor);
507                 glEnableClientState(GL_VERTEX_ARRAY);
508                 glEnableClientState(GL_COLOR_ARRAY);
509
510                 order = (int *)((int)pheader + pheader->ofs_glcmds);
511                 while(1)
512                 {
513                         if (!(count = *order++))
514                                 break;
515                         if (count > 0)
516                                 glBegin(GL_TRIANGLE_STRIP);
517                         else
518                         {
519                                 glBegin(GL_TRIANGLE_FAN);
520                                 count = -count;
521                         }
522                         do
523                         {
524                                 glTexCoord2f(((float *)order)[0], ((float *)order)[1]);
525                                 qglArrayElement(order[2]);
526                                 order += 3;
527                         }
528                         while (count--);
529                 }
530
531                 glDisableClientState(GL_COLOR_ARRAY);
532                 glDisableClientState(GL_VERTEX_ARRAY);
533         }
534         else
535         {
536                 order = (int *)((int)pheader + pheader->ofs_glcmds);
537                 while(1)
538                 {
539                         if (!(count = *order++))
540                                 break;
541                         if (count > 0)
542                                 glBegin(GL_TRIANGLE_STRIP);
543                         else
544                         {
545                                 glBegin(GL_TRIANGLE_FAN);
546                                 count = -count;
547                         }
548                         //if (isG200)
549                         //{
550                                 do
551                                 {
552                                         glTexCoord2f(((float *)order)[0], ((float *)order)[1]);
553                                         glColor4f(aliasvertcolor[order[2] * 4] * (1.0f / 255.0f), aliasvertcolor[order[2] * 4 + 1] * (1.0f / 255.0f), aliasvertcolor[order[2] * 4 + 2] * (1.0f / 255.0f), aliasvertcolor[order[2] * 4 + 3] * (1.0f / 255.0f));
554                                         glVertex3fv(&aliasvert[order[2] * 3]);
555                                         order += 3;
556                                 }
557                                 while (count--);
558                         /*
559                         }
560                         else
561                         {
562                                 do
563                                 {
564                                         glTexCoord2f(((float *)order)[0], ((float *)order)[1]);
565                                         glColor4ub(aliasvertcolor[order[2] * 4], aliasvertcolor[order[2] * 4 + 1], aliasvertcolor[order[2] * 4 + 2], aliasvertcolor[order[2] * 4 + 3]);
566                                         glVertex3fv(&aliasvert[order[2] * 3]);
567                                         order += 3;
568                                 }
569                                 while (count--);
570                         }
571                         */
572                 }
573         }
574
575         if (fogenabled)
576         {
577                 glDisable (GL_TEXTURE_2D);
578                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
579                 glEnable (GL_BLEND);
580                 glDepthMask(0); // disable zbuffer updates
581                 {
582                         vec3_t diff;
583                         VectorSubtract(org, r_refdef.vieworg, diff);
584                         glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
585                 }
586
587                 if (gl_vertexarrays.value)
588                 {
589                         // LordHavoc: big mess...
590                         // using arrays only slightly, although it is enough to prevent duplicates
591                         // (saving half the transforms)
592                         qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
593                         glEnableClientState(GL_VERTEX_ARRAY);
594
595                         order = (int *)((int)pheader + pheader->ofs_glcmds);
596                         while(1)
597                         {
598                                 if (!(count = *order++))
599                                         break;
600                                 if (count > 0)
601                                         glBegin(GL_TRIANGLE_STRIP);
602                                 else
603                                 {
604                                         glBegin(GL_TRIANGLE_FAN);
605                                         count = -count;
606                                 }
607                                 do
608                                 {
609                                         qglArrayElement(order[2]);
610                                         order += 3;
611                                 }
612                                 while (count--);
613                         }
614
615                         glDisableClientState(GL_VERTEX_ARRAY);
616                 }
617                 else
618                 {
619                         order = (int *)((int)pheader + pheader->ofs_glcmds);
620                         while(1)
621                         {
622                                 if (!(count = *order++))
623                                         break;
624                                 if (count > 0)
625                                         glBegin(GL_TRIANGLE_STRIP);
626                                 else
627                                 {
628                                         glBegin(GL_TRIANGLE_FAN);
629                                         count = -count;
630                                 }
631                                 do
632                                 {
633                                         glVertex3fv(&aliasvert[order[2] * 3]);
634                                         order += 3;
635                                 }
636                                 while (count--);
637                         }
638                 }
639
640                 glEnable (GL_TEXTURE_2D);
641                 glColor3f (1,1,1);
642         }
643
644         if (!fogenabled && r_shadows.value && !(effects & EF_ADDITIVE) && shadow)
645         {
646                 int i;
647                 float *av = aliasvert + 2, l = lightspot[2] + 0.125;
648                 av = aliasvert + 2;
649                 for (i = 0;i < pheader->num_xyz;i++, av+=3)
650                         if (*av > l)
651                                 *av = l;
652                 glDisable (GL_TEXTURE_2D);
653                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
654                 glEnable (GL_BLEND);
655                 glDepthMask(0); // disable zbuffer updates
656                 glColor4f (0,0,0,0.5 * alpha);
657
658                 if (gl_vertexarrays.value)
659                 {
660                         qglVertexPointer(3, GL_FLOAT, 0, aliasvert);
661                         glEnableClientState(GL_VERTEX_ARRAY);
662                                                 
663                         while(1)
664                         {
665                                 if (!(count = *order++))
666                                         break;
667                                 if (count > 0)
668                                         glBegin(GL_TRIANGLE_STRIP);
669                                 else
670                                 {
671                                         glBegin(GL_TRIANGLE_FAN);
672                                         count = -count;
673                                 }
674                                 do
675                                 {
676                                         qglArrayElement(order[2]);
677                                         order += 3;
678                                 }
679                                 while (count--);
680                         }
681
682                         glDisableClientState(GL_VERTEX_ARRAY);
683                 }
684                 else
685                 {
686                         while(1)
687                         {
688                                 if (!(count = *order++))
689                                         break;
690                                 if (count > 0)
691                                         glBegin(GL_TRIANGLE_STRIP);
692                                 else
693                                 {
694                                         glBegin(GL_TRIANGLE_FAN);
695                                         count = -count;
696                                 }
697                                 do
698                                 {
699                                         glVertex3fv(&aliasvert[order[2] * 3]);
700                                         order += 3;
701                                 }
702                                 while (count--);
703                         }
704                 }
705
706                 glEnable (GL_TEXTURE_2D);
707                 glColor3f (1,1,1);
708         }
709
710         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
711         glEnable (GL_BLEND);
712         glDepthMask(1);
713 }
714
715 int modeldlightbits[8];
716 extern int r_dlightframecount;
717 extern void R_LightPoint (vec3_t color, vec3_t p);
718
719 /*
720 =================
721 R_DrawAliasModel
722
723 =================
724 */
725 void R_DrawAliasModel (entity_t *ent, int cull, float alpha, model_t *clmodel, int frame, int skin, vec3_t org, int effects, int flags, int colormap)
726 {
727         int                     i;
728         vec3_t          mins, maxs, color;
729 //      aliashdr_t      *paliashdr = NULL;
730 //      md2mem_t        *pheader = NULL;
731         mleaf_t         *leaf;
732         void            *modelheader;
733         int                     *skinset;
734
735         if (alpha < (1.0 / 64.0))
736                 return; // basically completely transparent
737
738         VectorAdd (org, clmodel->mins, mins);
739         VectorAdd (org, clmodel->maxs, maxs);
740
741         if (cull && R_CullBox (mins, maxs))
742                 return;
743
744         leaf = Mod_PointInLeaf (org, cl.worldmodel);
745         if (leaf->dlightframe == r_dlightframecount)
746                 for (i = 0;i < 8;i++)
747                         modeldlightbits[i] = leaf->dlightbits[i];
748         else
749                 for (i = 0;i < 8;i++)
750                         modeldlightbits[i] = 0;
751
752         // get lighting information
753
754         if ((flags & EF_FULLBRIGHT) || (effects & EF_FULLBRIGHT))
755                 color[0] = color[1] = color[2] = 256;
756         else
757         {
758                 // HACK HACK HACK -- no fullbright colors, so make torches full light
759                 if (!strcmp (clmodel->name, "progs/flame2.mdl") || !strcmp (clmodel->name, "progs/flame.mdl") )
760                         color[0] = color[1] = color[2] = 128;
761                 else
762                         R_LightPoint (color, org);
763         }
764
765         glDisable(GL_ALPHA_TEST);
766
767         if (frame < 0 || frame >= clmodel->numframes)
768         {
769                 frame = 0;
770                 Con_DPrintf("invalid skin number %d for model %s\n", frame, clmodel->name);
771         }
772
773         if (skin < 0 || skin >= clmodel->numskins)
774         {
775                 skin = 0;
776                 Con_DPrintf("invalid skin number %d for model %s\n", skin, clmodel->name);
777         }
778
779         modelheader = Mod_Extradata (clmodel);
780
781         {
782 //              int *skinanimrange = (int *) (clmodel->skinanimrange + (int) modelheader) + skin * 2;
783 //              int *skinanim = (int *) (clmodel->skinanim + (int) modelheader);
784                 int *skinanimrange = clmodel->skinanimrange + skin * 2;
785                 int *skinanim = clmodel->skinanim;
786                 i = skinanimrange[0];
787                 if (skinanimrange[1] > 1) // animated
788                         i += ((int) (cl.time * 10) % skinanimrange[1]);
789                 skinset = skinanim + i*5;
790         }
791
792 //      glBindTexture(GL_TEXTURE_2D, paliashdr->gl_texturenum[skin][(int)(cl.time*10) & 3]);
793 //      glBindTexture(GL_TEXTURE_2D, pheader->gl_texturenum[skin]);
794
795         glEnable (GL_TEXTURE_2D);
796
797         c_alias_polys += clmodel->numtris;
798         if (clmodel->aliastype == ALIASTYPE_MD2)
799                 R_DrawQ2AliasFrame (modelheader, alpha, color, ent, ent != &cl.viewent, org, frame, skinset[0], effects, flags);
800         else
801                 R_DrawAliasFrame (modelheader, alpha, color, ent, ent != &cl.viewent, org, frame, skinset, colormap, effects, flags);
802 }