some whitespace changes
[xonotic/darkplaces.git] / gl_poly.c
1 #include "quakedef.h"
2
3 transvert_t *transvert;
4 transpoly_t *transpoly;
5 unsigned short *transpolyindex;
6 wallvert_t *wallvert;
7 wallvertcolor_t *wallvertcolor;
8 wallpoly_t *wallpoly;
9 skyvert_t *skyvert;
10 skypoly_t *skypoly;
11
12 int currenttranspoly;
13 int currenttransvert;
14 int currentwallpoly;
15 int currentwallvert;
16 int currentskypoly;
17 int currentskyvert;
18
19 cvar_t gl_multitexture = {"gl_multitexture", "1"};
20
21 typedef struct translistitem_s
22 {
23         transpoly_t *poly;
24         struct translistitem_s *next;
25 }
26 translistitem;
27
28 translistitem translist[MAX_TRANSPOLYS];
29 translistitem *currenttranslist;
30
31 translistitem *translisthash[4096];
32
33 float transviewdist; // distance of view origin along the view normal
34
35 float transreciptable[256];
36
37 void gl_poly_start()
38 {
39         int i;
40         transvert = qmalloc(MAX_TRANSVERTS * sizeof(transvert_t));
41         transpoly = qmalloc(MAX_TRANSPOLYS * sizeof(transpoly_t));
42         transpolyindex = qmalloc(MAX_TRANSPOLYS * sizeof(unsigned short));
43         wallvert = qmalloc(MAX_WALLVERTS * sizeof(wallvert_t));
44         wallvertcolor = qmalloc(MAX_WALLVERTS * sizeof(wallvertcolor_t));
45         wallpoly = qmalloc(MAX_WALLPOLYS * sizeof(wallpoly_t));
46         skyvert = qmalloc(MAX_SKYVERTS * sizeof(skyvert_t));
47         skypoly = qmalloc(MAX_SKYPOLYS * sizeof(skypoly_t));
48         transreciptable[0] = 0.0f;
49         for (i = 1;i < 256;i++)
50                 transreciptable[i] = 1.0f / i;
51 }
52
53 void gl_poly_shutdown()
54 {
55         qfree(transvert);
56         qfree(transpoly);
57         qfree(transpolyindex);
58         qfree(wallvert);
59         qfree(wallvertcolor);
60         qfree(wallpoly);
61         qfree(skyvert);
62         qfree(skypoly);
63 }
64
65 void gl_poly_newmap()
66 {
67 }
68
69 void GL_Poly_Init()
70 {
71         Cvar_RegisterVariable (&gl_multitexture);
72         R_RegisterModule("GL_Poly", gl_poly_start, gl_poly_shutdown, gl_poly_newmap);
73 }
74
75 void transpolyclear()
76 {
77         currenttranspoly = currenttransvert = 0;
78         currenttranslist = translist;
79         memset(translisthash, 0, sizeof(translisthash));
80         transviewdist = DotProduct(r_origin, vpn);
81 }
82
83 // turned into a #define
84 /*
85 void transpolybegin(int texnum, int glowtexnum, int fogtexnum, int transpolytype)
86 {
87         if (currenttranspoly >= MAX_TRANSPOLYS || currenttransvert >= MAX_TRANSVERTS)
88                 return;
89         transpoly[currenttranspoly].texnum = (unsigned short) texnum;
90         transpoly[currenttranspoly].glowtexnum = (unsigned short) glowtexnum;
91         transpoly[currenttranspoly].fogtexnum = (unsigned short) fogtexnum;
92         transpoly[currenttranspoly].transpolytype = (unsigned short) transpolytype;
93         transpoly[currenttranspoly].firstvert = currenttransvert;
94         transpoly[currenttranspoly].verts = 0;
95 //      transpoly[currenttranspoly].ndist = 0; // clear the normal
96 }
97 */
98
99 // turned into a #define
100 /*
101 void transpolyvert(float x, float y, float z, float s, float t, int r, int g, int b, int a)
102 {
103         int i;
104         if (currenttranspoly >= MAX_TRANSPOLYS || currenttransvert >= MAX_TRANSVERTS)
105                 return;
106         transvert[currenttransvert].s = s;
107         transvert[currenttransvert].t = t;
108         transvert[currenttransvert].r = bound(0, r, 255);
109         transvert[currenttransvert].g = bound(0, g, 255);
110         transvert[currenttransvert].b = bound(0, b, 255);
111         transvert[currenttransvert].a = bound(0, a, 255);
112         transvert[currenttransvert].v[0] = x;
113         transvert[currenttransvert].v[1] = y;
114         transvert[currenttransvert].v[2] = z;
115         currenttransvert++;
116         transpoly[currenttranspoly].verts++;
117 }
118 */
119
120 void transpolyend()
121 {
122         float center, d, maxdist;
123         int i;
124         transvert_t *v;
125         if (currenttranspoly >= MAX_TRANSPOLYS || currenttransvert >= MAX_TRANSVERTS)
126                 return;
127         if (transpoly[currenttranspoly].verts < 3) // skip invalid polygons
128         {
129                 currenttransvert = transpoly[currenttranspoly].firstvert; // reset vert pointer
130                 return;
131         }
132         center = 0;
133         maxdist = -1000000000000000.0f; // eh, it's definitely behind it, so...
134         for (i = 0,v = &transvert[transpoly[currenttranspoly].firstvert];i < transpoly[currenttranspoly].verts;i++, v++)
135         {
136                 d = DotProduct(v->v, vpn);
137                 center += d;
138                 if (d > maxdist)
139                         maxdist = d;
140         }
141         maxdist -= transviewdist;
142         if (maxdist < 4.0f) // behind view
143         {
144                 currenttransvert = transpoly[currenttranspoly].firstvert; // reset vert pointer
145                 return;
146         }
147         center *= transreciptable[transpoly[currenttranspoly].verts];
148         center -= transviewdist;
149         i = bound(0, (int) center, 4095);
150         currenttranslist->next = translisthash[i];
151         currenttranslist->poly = transpoly + currenttranspoly;
152         translisthash[i] = currenttranslist;
153         currenttranslist++;
154         currenttranspoly++;
155 }
156
157 int transpolyindices;
158
159 void transpolyrender()
160 {
161         int i, j, tpolytype, texnum;
162         transpoly_t *p;
163         if (!r_render.value)
164                 return;
165         if (currenttranspoly < 1)
166                 return;
167 //      transpolyrenderminmax();
168 //      if (transpolyindices < 1)
169 //              return;
170         // testing
171 //      Con_DPrintf("transpolyrender: %i polys %i infront %i vertices\n", currenttranspoly, transpolyindices, currenttransvert);
172 //      if (transpolyindices >= 2)
173 //              transpolysort();
174         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
175         glEnable(GL_BLEND);
176         glShadeModel(GL_SMOOTH);
177         glDepthMask(0); // disable zbuffer updates
178         glDisable(GL_ALPHA_TEST);
179         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
180         tpolytype = TPOLYTYPE_ALPHA;
181         texnum = -1;
182         /*
183         if (gl_vertexarrays.value)
184         {
185                 // set up the vertex array
186                 glInterleavedArrays(GL_T2F_C4UB_V3F, 0, transvert);
187                 for (i = 0;i < transpolyindices;i++)
188                 {
189                         p = &transpoly[transpolyindex[i]];
190                         if (p->texnum != texnum || p->transpolytype != tpolytype)
191                         {
192                                 if (p->texnum != texnum)
193                                 {
194                                         texnum = p->texnum;
195                                         glBindTexture(GL_TEXTURE_2D, texnum);
196                                 }
197                                 if (p->transpolytype != tpolytype)
198                                 {
199                                         tpolytype = p->transpolytype;
200                                         if (tpolytype == TPOLYTYPE_ADD) // additive
201                                                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
202                                         else // alpha
203                                                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
204                                 }
205                         }
206                         glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
207                         if (p->glowtexnum)
208                         {
209                                 texnum = p->glowtexnum; // highly unlikely to match next poly, but...
210                                 glBindTexture(GL_TEXTURE_2D, texnum);
211                                 tpolytype = TPOLYTYPE_ADD; // might match next poly
212                                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
213                                 glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
214                         }
215                 }
216                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
217                 glDisableClientState(GL_COLOR_ARRAY);
218                 glDisableClientState(GL_VERTEX_ARRAY);
219         }
220         else
221         */
222         {
223                 int points = -1;
224                 translistitem *item;
225                 transvert_t *vert;
226                 for (i = 4095;i >= 0;i--)
227                 {
228                         item = translisthash[i];
229                         while (item)
230                         {
231                                 p = item->poly;
232                                 item = item->next;
233                                 if (p->texnum != texnum || p->verts != points || p->transpolytype != tpolytype)
234                                 {
235                                         glEnd();
236                                         if (isG200)
237                                         {
238                                                 // LordHavoc: Matrox G200 cards can't handle per pixel alpha
239                                                 if (p->fogtexnum)
240                                                         glEnable(GL_ALPHA_TEST);
241                                                 else
242                                                         glDisable(GL_ALPHA_TEST);
243                                         }
244                                         if (p->texnum != texnum)
245                                         {
246                                                 texnum = p->texnum;
247                                                 glBindTexture(GL_TEXTURE_2D, texnum);
248                                         }
249                                         if (p->transpolytype != tpolytype)
250                                         {
251                                                 tpolytype = p->transpolytype;
252                                                 if (tpolytype == TPOLYTYPE_ADD) // additive
253                                                         glBlendFunc(GL_SRC_ALPHA, GL_ONE);
254                                                 else // alpha
255                                                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
256                                         }
257                                         points = p->verts;
258                                         switch (points)
259                                         {
260                                         case 3:
261                                                 glBegin(GL_TRIANGLES);
262                                                 break;
263                                         case 4:
264                                                 glBegin(GL_QUADS);
265                                                 break;
266                                         default:
267                                                 glBegin(GL_POLYGON);
268                                                 points = -1; // to force a reinit on the next poly
269                                                 break;
270                                         }
271                                 }
272                                 for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
273                                 {
274                                         // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...)
275                                         glTexCoord2f(vert->s, vert->t);
276                                         // again, vector version isn't supported I think
277                                         glColor4ub(vert->r, vert->g, vert->b, vert->a);
278                                         glVertex3fv(vert->v);
279                                 }
280                                 if (p->glowtexnum)
281                                 {
282                                         glEnd();
283                                         texnum = p->glowtexnum; // highly unlikely to match next poly, but...
284                                         glBindTexture(GL_TEXTURE_2D, texnum);
285                                         if (tpolytype != TPOLYTYPE_ADD)
286                                         {
287                                                 tpolytype = TPOLYTYPE_ADD; // might match next poly
288                                                 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
289                                         }
290                                         points = -1;
291                                         glBegin(GL_POLYGON);
292                                         for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
293                                         {
294                                                 glColor4ub(255,255,255,vert->a);
295                                                 // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...)
296                                                 glTexCoord2f(vert->s, vert->t);
297                                                 glVertex3fv(vert->v);
298                                         }
299                                         glEnd();
300                                 }
301                                 if (fogenabled && p->transpolytype == TPOLYTYPE_ALPHA)
302                                 {
303                                         vec3_t diff;
304                                         glEnd();
305                                         points = -1; // to force a reinit on the next poly
306                                         if (tpolytype != TPOLYTYPE_ALPHA)
307                                         {
308                                                 tpolytype = TPOLYTYPE_ALPHA; // probably matchs next poly
309                                                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
310                                         }
311                                         if (p->fogtexnum)
312                                         {
313                                                 if (texnum != p->fogtexnum) // highly unlikely to match next poly, but...
314                                                 {
315                                                         texnum = p->fogtexnum;
316                                                         glBindTexture(GL_TEXTURE_2D, texnum);
317                                                 }
318                                                 glBegin(GL_POLYGON);
319                                                 for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
320                                                 {
321                                                         VectorSubtract(vert->v, r_origin, diff);
322                                                         glTexCoord2f(vert->s, vert->t);
323                                                         glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff)));
324                                                         glVertex3fv(vert->v);
325                                                 }
326                                                 glEnd ();
327                                         }
328                                         else
329                                         {
330                                                 glDisable(GL_TEXTURE_2D);
331                                                 glBegin(GL_POLYGON);
332                                                 for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
333                                                 {
334                                                         VectorSubtract(vert->v, r_origin, diff);
335                                                         glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff)));
336                                                         glVertex3fv(vert->v);
337                                                 }
338                                                 glEnd ();
339                                                 glEnable(GL_TEXTURE_2D);
340                                         }
341                                 }
342                         }
343                 }
344                 glEnd();
345         }
346
347         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
348         glDepthMask(1); // enable zbuffer updates
349         glDisable(GL_ALPHA_TEST);
350 }
351
352 void wallpolyclear()
353 {
354         currentwallpoly = currentwallvert = 0;
355 }
356
357 void wallpolyrender()
358 {
359         int i, j, texnum, lighttexnum;
360         wallpoly_t *p;
361         wallvert_t *vert;
362         wallvertcolor_t *vertcolor;
363         if (!r_render.value)
364                 return;
365         if (currentwallpoly < 1)
366                 return;
367         c_brush_polys += currentwallpoly;
368         // testing
369         //Con_DPrintf("wallpolyrender: %i polys %i vertices\n", currentwallpoly, currentwallvert);
370         if (!gl_mtexable)
371                 gl_multitexture.value = 0;
372         glDisable(GL_BLEND);
373         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
374         glShadeModel(GL_FLAT);
375         // make sure zbuffer is enabled
376         glEnable(GL_DEPTH_TEST);
377 //      glDisable(GL_ALPHA_TEST);
378         glDepthMask(1);
379         glColor3f(1,1,1);
380         if (r_fullbright.value) // LordHavoc: easy to do fullbright...
381         {
382                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
383                 texnum = -1;
384                 for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
385                 {
386                         if (p->texnum != texnum)
387                         {
388                                 texnum = p->texnum;
389                                 glBindTexture(GL_TEXTURE_2D, texnum);
390                         }
391                         vert = &wallvert[p->firstvert];
392                         glBegin(GL_POLYGON);
393                         for (j=0 ; j<p->numverts ; j++, vert++)
394                         {
395                                 glTexCoord2f (vert->vert[3], vert->vert[4]);
396                                 glVertex3fv (vert->vert);
397                         }
398                         glEnd ();
399                 }
400         }
401         else if (gl_multitexture.value)
402         {
403                 qglSelectTexture(gl_mtex_enum+0);
404                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
405                 glEnable(GL_TEXTURE_2D);
406                 qglSelectTexture(gl_mtex_enum+1);
407                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
408                 glEnable(GL_TEXTURE_2D);
409                 texnum = -1;
410                 lighttexnum = -1;
411                 for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
412                 {
413                         if (p->texnum != texnum || p->lighttexnum != lighttexnum)
414                         {
415                                 texnum = p->texnum;
416                                 lighttexnum = p->lighttexnum;
417                                 qglSelectTexture(gl_mtex_enum+0);
418                                 glBindTexture(GL_TEXTURE_2D, texnum);
419                                 qglSelectTexture(gl_mtex_enum+1);
420                                 glBindTexture(GL_TEXTURE_2D, lighttexnum);
421                         }
422                         vert = &wallvert[p->firstvert];
423                         glBegin(GL_POLYGON);
424                         for (j=0 ; j<p->numverts ; j++, vert++)
425                         {
426                                 qglMTexCoord2f(gl_mtex_enum, vert->vert[3], vert->vert[4]); // texture
427                                 qglMTexCoord2f((gl_mtex_enum+1), vert->vert[5], vert->vert[6]); // lightmap
428                                 glVertex3fv (vert->vert);
429                         }
430                         glEnd ();
431                 }
432
433                 qglSelectTexture(gl_mtex_enum+1);
434                 glDisable(GL_TEXTURE_2D);
435                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
436                 qglSelectTexture(gl_mtex_enum+0);
437                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
438         }
439         else
440         {
441                 // first do the textures
442                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
443                 texnum = -1;
444                 for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
445                 {
446                         if (p->texnum != texnum)
447                         {
448                                 texnum = p->texnum;
449                                 glBindTexture(GL_TEXTURE_2D, texnum);
450                         }
451                         vert = &wallvert[p->firstvert];
452                         glBegin(GL_POLYGON);
453                         for (j=0 ; j<p->numverts ; j++, vert++)
454                         {
455                                 glTexCoord2f (vert->vert[3], vert->vert[4]);
456                                 glVertex3fv (vert->vert);
457                         }
458                         glEnd ();
459                 }
460                 // then modulate using the lightmaps
461                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
462                 glBlendFunc(GL_ZERO, GL_SRC_COLOR);
463                 glEnable(GL_BLEND);
464                 texnum = -1;
465                 for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
466                 {
467                         if (p->lighttexnum != texnum)
468                         {
469                                 texnum = p->lighttexnum;
470                                 glBindTexture(GL_TEXTURE_2D, texnum);
471                         }
472                         vert = &wallvert[p->firstvert];
473                         glBegin(GL_POLYGON);
474                         for (j=0 ; j<p->numverts ; j++, vert++)
475                         {
476                                 glTexCoord2f (vert->vert[5], vert->vert[6]);
477                                 glVertex3fv (vert->vert);
478                         }
479                         glEnd ();
480                 }
481         }
482         // switch to additive mode settings
483         glDepthMask(0);
484         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
485         glBlendFunc(GL_SRC_ALPHA, GL_ONE);
486         glEnable(GL_BLEND);
487 //      glDisable(GL_ALPHA_TEST);
488         glShadeModel(GL_SMOOTH);
489         // render vertex lit overlays ontop
490         texnum = -1;
491         for (i = 0, p = wallpoly;i < currentwallpoly;i++, p++)
492         {
493                 if (!p->lit)
494                         continue;
495                 for (j = 0,vertcolor = &wallvertcolor[p->firstvert];j < p->numverts;j++, vertcolor++)
496                         if (vertcolor->r || vertcolor->g || vertcolor->b)
497                                 goto lit;
498                 continue;
499 lit:
500                 c_light_polys++;
501                 if (p->texnum != texnum)
502                 {
503                         texnum = p->texnum;
504                         glBindTexture(GL_TEXTURE_2D, texnum);
505                 }
506                 glBegin(GL_POLYGON);
507                 for (j = 0,vert = &wallvert[p->firstvert], vertcolor = &wallvertcolor[p->firstvert];j < p->numverts;j++, vert++, vertcolor++)
508                 {
509                         // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...)
510                         glTexCoord2f(vert->vert[3], vert->vert[4]);
511                         // again, vector version isn't supported I think
512                         glColor3ub(vertcolor->r, vertcolor->g, vertcolor->b);
513                         glVertex3fv(vert->vert);
514                 }
515                 glEnd();
516         }
517         // render glow textures
518         glShadeModel(GL_FLAT);
519         glBlendFunc(GL_ONE, GL_ONE);
520         if (lighthalf)
521                 glColor3f(0.5,0.5,0.5);
522         else
523                 glColor3f(1,1,1);
524         texnum = -1;
525         for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
526         {
527                 if (!p->glowtexnum)
528                         continue;
529                 if (p->glowtexnum != texnum)
530                 {
531                         texnum = p->glowtexnum;
532                         glBindTexture(GL_TEXTURE_2D, texnum);
533                 }
534                 vert = &wallvert[p->firstvert];
535                 glBegin(GL_POLYGON);
536                 for (j=0 ; j<p->numverts ; j++, vert++)
537                 {
538                         glTexCoord2f (vert->vert[3], vert->vert[4]);
539                         glVertex3fv (vert->vert);
540                 }
541                 glEnd();
542         }
543         glColor3f(1,1,1);
544         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
545         glShadeModel(GL_SMOOTH);
546         if (fogenabled)
547         {
548                 vec3_t diff;
549                 glDisable(GL_TEXTURE_2D);
550                 for (i = 0,p = &wallpoly[0];i < currentwallpoly;i++, p++)
551                 {
552                         vert = &wallvert[p->firstvert];
553                         glBegin(GL_POLYGON);
554                         for (j=0 ; j<p->numverts ; j++, vert++)
555                         {
556                                 VectorSubtract(vert->vert, r_origin, diff);
557                                 glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
558                                 glVertex3fv (vert->vert);
559                         }
560                         glEnd ();
561                 }
562                 glEnable(GL_TEXTURE_2D);
563         }
564         glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
565         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
566 //      glDisable(GL_ALPHA_TEST);
567         glShadeModel(GL_SMOOTH);
568         glDisable(GL_BLEND);
569         glDepthMask(1);
570 }
571
572 void skypolyclear()
573 {
574         currentskypoly = currentskyvert = 0;
575 }
576
577 extern char skyname[];
578 extern rtexture_t *solidskytexture, *alphaskytexture;
579 void skypolyrender()
580 {
581         int i, j;
582         skypoly_t *p;
583         skyvert_t *vert;
584         float length, speedscale;
585         vec3_t dir;
586         if (!r_render.value)
587                 return;
588         if (currentskypoly < 1)
589                 return;
590         // testing
591 //      Con_DPrintf("skypolyrender: %i polys %i vertices\n", currentskypoly, currentskyvert);
592 //      glDisable(GL_ALPHA_TEST);
593         glDisable(GL_BLEND);
594         // make sure zbuffer is enabled
595         glEnable(GL_DEPTH_TEST);
596         glDepthMask(1);
597         if (!fogenabled && !skyname[0]) // normal quake sky
598         {
599                 glInterleavedArrays(GL_T2F_V3F, 0, skyvert);
600 //              glTexCoordPointer(2, GL_FLOAT, sizeof(skyvert_t), &skyvert[0].tex[0]);
601 //              glEnableClientState(GL_TEXTURE_COORD_ARRAY);
602 //              glVertexPointer(3, GL_FLOAT, sizeof(skyvert_t), &skyvert[0].v[0]);
603 //              glEnableClientState(GL_VERTEX_ARRAY);
604                 if(lighthalf)
605                         glColor3f(0.5f, 0.5f, 0.5f);
606                 else
607                         glColor3f(1.0f,1.0f,1.0f);
608                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
609                 glEnable(GL_TEXTURE_2D);
610                 glDisable(GL_BLEND);
611                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
612                 glBindTexture(GL_TEXTURE_2D, R_GetTexture(solidskytexture)); // upper clouds
613                 speedscale = cl.time*8;
614                 speedscale -= (int)speedscale & ~127 ;
615                 for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
616                 {
617                         vert = skyvert + p->firstvert;
618                         for (j = 0;j < p->verts;j++, vert++)
619                         {
620                                 VectorSubtract (vert->v, r_origin, dir);
621                                 dir[2] *= 3;    // flatten the sphere
622
623                                 length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2];
624                                 length = sqrt (length);
625                                 length = 6*63/length;
626
627                                 vert->tex[0] = (speedscale + dir[0] * length) * (1.0/128);
628                                 vert->tex[1] = (speedscale + dir[1] * length) * (1.0/128);
629                         }
630                 }
631                 GL_LockArray(0, currentskyvert);
632                 for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
633                         glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
634                 GL_UnlockArray();
635                 glEnable(GL_BLEND);
636                 glDepthMask(0);
637                 glBindTexture(GL_TEXTURE_2D, R_GetTexture(alphaskytexture)); // lower clouds
638                 speedscale = cl.time*16;
639                 speedscale -= (int)speedscale & ~127 ;
640                 for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
641                 {
642                         vert = skyvert + p->firstvert;
643                         for (j = 0;j < p->verts;j++, vert++)
644                         {
645                                 VectorSubtract (vert->v, r_origin, dir);
646                                 dir[2] *= 3;    // flatten the sphere
647
648                                 length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2];
649                                 length = sqrt (length);
650                                 length = 6*63/length;
651
652                                 vert->tex[0] = (speedscale + dir[0] * length) * (1.0/128);
653                                 vert->tex[1] = (speedscale + dir[1] * length) * (1.0/128);
654                         }
655                 }
656                 GL_LockArray(0, currentskyvert);
657                 for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
658                         glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
659                 GL_UnlockArray();
660                 glDisable(GL_BLEND);
661                 glColor3f(1,1,1);
662                 glDepthMask(1);
663                 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
664                 glDisableClientState(GL_VERTEX_ARRAY);
665         }
666         else
667         {
668                 glVertexPointer(3, GL_FLOAT, sizeof(skyvert_t), &skyvert[0].v[0]);
669                 glEnableClientState(GL_VERTEX_ARRAY);
670                 glDisable(GL_TEXTURE_2D);
671                 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
672                 glColor3fv(fogcolor); // note: gets rendered over by skybox if fog is not enabled
673                 GL_LockArray(0, currentskyvert);
674                 for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
675                         glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
676                 GL_UnlockArray();
677                 glColor3f(1,1,1);
678                 glEnable(GL_TEXTURE_2D);
679                 glDisableClientState(GL_VERTEX_ARRAY);
680         }
681 }