3 transvert_t *transvert;
4 transpoly_t *transpoly;
5 unsigned short *transpolyindex;
7 wallvertcolor_t *wallvertcolor;
21 cvar_t r_multitexture = {0, "r_multitexture", "1"};
22 cvar_t r_skyquality = {CVAR_SAVE, "r_skyquality", "2"};
23 cvar_t r_mergesky = {CVAR_SAVE, "r_mergesky", "0"};
25 static char skyworldname[1024];
26 static rtexture_t *mergeskytexture;
27 static rtexture_t *solidskytexture, *solidskytexture_half;
28 static rtexture_t *alphaskytexture, *alphaskytexture_half;
29 static qboolean skyavailable_quake;
30 static qboolean skyavailable_box;
32 void R_BuildSky (int scrollupper, int scrolllower);
34 typedef struct translistitem_s
37 struct translistitem_s *next;
41 translistitem translist[MAX_TRANSPOLYS];
42 translistitem *currenttranslist;
44 translistitem *translisthash[4096];
46 float transviewdist; // distance of view origin along the view normal
48 float transreciptable[256];
50 void gl_poly_start(void)
53 transvert = qmalloc(MAX_TRANSVERTS * sizeof(transvert_t));
54 transpoly = qmalloc(MAX_TRANSPOLYS * sizeof(transpoly_t));
55 transpolyindex = qmalloc(MAX_TRANSPOLYS * sizeof(unsigned short));
56 wallvert = qmalloc(MAX_WALLVERTS * sizeof(wallvert_t));
57 wallvertcolor = qmalloc(MAX_WALLVERTS * sizeof(wallvertcolor_t));
58 wallpoly = qmalloc(MAX_WALLPOLYS * sizeof(wallpoly_t));
59 skyvert = qmalloc(MAX_SKYVERTS * sizeof(skyvert_t));
60 skypoly = qmalloc(MAX_SKYPOLYS * sizeof(skypoly_t));
61 transreciptable[0] = 0.0f;
62 for (i = 1;i < 256;i++)
63 transreciptable[i] = 1.0f / i;
66 void gl_poly_shutdown(void)
70 qfree(transpolyindex);
78 void gl_poly_newmap(void)
80 skyavailable_box = false;
81 skyavailable_quake = false;
82 if (!strcmp(skyworldname, cl.worldmodel->name))
83 skyavailable_quake = true;
86 void GL_Poly_Init(void)
88 Cmd_AddCommand ("loadsky", &LoadSky_f);
89 Cvar_RegisterVariable (&r_multitexture);
90 Cvar_RegisterVariable (&r_skyquality);
91 Cvar_RegisterVariable (&r_mergesky);
92 R_RegisterModule("GL_Poly", gl_poly_start, gl_poly_shutdown, gl_poly_newmap);
95 void transpolyclear(void)
97 currenttranspoly = currenttransvert = 0;
98 currenttranslist = translist;
99 memset(translisthash, 0, sizeof(translisthash));
100 transviewdist = DotProduct(r_origin, vpn);
103 // turned into a #define
105 void transpolybegin(int texnum, int glowtexnum, int fogtexnum, int transpolytype)
107 if (currenttranspoly >= MAX_TRANSPOLYS || currenttransvert >= MAX_TRANSVERTS)
109 transpoly[currenttranspoly].texnum = (unsigned short) texnum;
110 transpoly[currenttranspoly].glowtexnum = (unsigned short) glowtexnum;
111 transpoly[currenttranspoly].fogtexnum = (unsigned short) fogtexnum;
112 transpoly[currenttranspoly].transpolytype = (unsigned short) transpolytype;
113 transpoly[currenttranspoly].firstvert = currenttransvert;
114 transpoly[currenttranspoly].verts = 0;
115 // transpoly[currenttranspoly].ndist = 0; // clear the normal
119 // turned into a #define
121 void transpolyvert(float x, float y, float z, float s, float t, int r, int g, int b, int a)
124 if (currenttranspoly >= MAX_TRANSPOLYS || currenttransvert >= MAX_TRANSVERTS)
126 transvert[currenttransvert].s = s;
127 transvert[currenttransvert].t = t;
128 transvert[currenttransvert].r = bound(0, r, 255);
129 transvert[currenttransvert].g = bound(0, g, 255);
130 transvert[currenttransvert].b = bound(0, b, 255);
131 transvert[currenttransvert].a = bound(0, a, 255);
132 transvert[currenttransvert].v[0] = x;
133 transvert[currenttransvert].v[1] = y;
134 transvert[currenttransvert].v[2] = z;
136 transpoly[currenttranspoly].verts++;
140 void transpolyend(void)
142 float center, d, maxdist;
145 if (currenttranspoly >= MAX_TRANSPOLYS || currenttransvert >= MAX_TRANSVERTS)
147 if (transpoly[currenttranspoly].verts < 3) // skip invalid polygons
149 currenttransvert = transpoly[currenttranspoly].firstvert; // reset vert pointer
153 maxdist = -1000000000000000.0f; // eh, it's definitely behind it, so...
154 for (i = 0,v = &transvert[transpoly[currenttranspoly].firstvert];i < transpoly[currenttranspoly].verts;i++, v++)
156 d = DotProduct(v->v, vpn);
161 maxdist -= transviewdist;
162 if (maxdist < 4.0f) // behind view
164 currenttransvert = transpoly[currenttranspoly].firstvert; // reset vert pointer
167 center *= transreciptable[transpoly[currenttranspoly].verts];
168 center -= transviewdist;
169 i = bound(0, (int) center, 4095);
170 currenttranslist->next = translisthash[i];
171 currenttranslist->poly = transpoly + currenttranspoly;
172 translisthash[i] = currenttranslist;
177 int transpolyindices;
179 void transpolyrender(void)
181 int i, j, tpolytype, texnum;
185 if (currenttranspoly < 1)
187 // transpolyrenderminmax();
188 // if (transpolyindices < 1)
191 // Con_DPrintf("transpolyrender: %i polys %i infront %i vertices\n", currenttranspoly, transpolyindices, currenttransvert);
192 // if (transpolyindices >= 2)
194 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
196 glShadeModel(GL_SMOOTH);
197 glDepthMask(0); // disable zbuffer updates
198 glDisable(GL_ALPHA_TEST);
199 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
200 tpolytype = TPOLYTYPE_ALPHA;
203 if (gl_vertexarrays.value)
205 // set up the vertex array
206 glInterleavedArrays(GL_T2F_C4UB_V3F, 0, transvert);
207 for (i = 0;i < transpolyindices;i++)
209 p = &transpoly[transpolyindex[i]];
210 if (p->texnum != texnum || p->transpolytype != tpolytype)
212 if (p->texnum != texnum)
215 glBindTexture(GL_TEXTURE_2D, texnum);
217 if (p->transpolytype != tpolytype)
219 tpolytype = p->transpolytype;
220 if (tpolytype == TPOLYTYPE_ADD) // additive
221 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
223 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
226 glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
229 texnum = p->glowtexnum; // highly unlikely to match next poly, but...
230 glBindTexture(GL_TEXTURE_2D, texnum);
231 tpolytype = TPOLYTYPE_ADD; // might match next poly
232 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
233 glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
236 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
237 glDisableClientState(GL_COLOR_ARRAY);
238 glDisableClientState(GL_VERTEX_ARRAY);
246 for (i = 4095;i >= 0;i--)
248 item = translisthash[i];
253 if (p->texnum != texnum || p->verts != points || p->transpolytype != tpolytype)
258 // LordHavoc: Matrox G200 cards can't handle per pixel alpha
260 glEnable(GL_ALPHA_TEST);
262 glDisable(GL_ALPHA_TEST);
264 if (p->texnum != texnum)
267 glBindTexture(GL_TEXTURE_2D, texnum);
269 if (p->transpolytype != tpolytype)
271 tpolytype = p->transpolytype;
272 if (tpolytype == TPOLYTYPE_ADD) // additive
273 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
275 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
281 glBegin(GL_TRIANGLES);
288 points = -1; // to force a reinit on the next poly
292 for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
294 // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...)
295 glTexCoord2f(vert->s, vert->t);
296 // again, vector version isn't supported I think
297 glColor4ub(vert->r, vert->g, vert->b, vert->a);
298 glVertex3fv(vert->v);
303 texnum = p->glowtexnum; // highly unlikely to match next poly, but...
304 glBindTexture(GL_TEXTURE_2D, texnum);
305 if (tpolytype != TPOLYTYPE_ADD)
307 tpolytype = TPOLYTYPE_ADD; // might match next poly
308 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
312 for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
314 glColor4ub(255,255,255,vert->a);
315 // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...)
316 glTexCoord2f(vert->s, vert->t);
317 glVertex3fv(vert->v);
321 if (fogenabled && p->transpolytype == TPOLYTYPE_ALPHA)
325 points = -1; // to force a reinit on the next poly
326 if (tpolytype != TPOLYTYPE_ALPHA)
328 tpolytype = TPOLYTYPE_ALPHA; // probably matchs next poly
329 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
333 if (texnum != p->fogtexnum) // highly unlikely to match next poly, but...
335 texnum = p->fogtexnum;
336 glBindTexture(GL_TEXTURE_2D, texnum);
339 for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
341 VectorSubtract(vert->v, r_origin, diff);
342 glTexCoord2f(vert->s, vert->t);
343 glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff)));
344 glVertex3fv(vert->v);
350 glDisable(GL_TEXTURE_2D);
352 for (j = 0,vert = &transvert[p->firstvert];j < p->verts;j++, vert++)
354 VectorSubtract(vert->v, r_origin, diff);
355 glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], vert->a*(1.0f/255.0f)*exp(fogdensity/DotProduct(diff,diff)));
356 glVertex3fv(vert->v);
359 glEnable(GL_TEXTURE_2D);
367 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
368 glDepthMask(1); // enable zbuffer updates
369 glDisable(GL_ALPHA_TEST);
372 void wallpolyclear(void)
374 currentwallpoly = currentwallvert = 0;
377 void wallpolyrender(void)
379 int i, j, texnum, lighttexnum;
382 wallvertcolor_t *vertcolor;
385 if (currentwallpoly < 1)
387 c_brush_polys += currentwallpoly;
389 //Con_DPrintf("wallpolyrender: %i polys %i vertices\n", currentwallpoly, currentwallvert);
391 r_multitexture.value = 0;
393 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
394 glShadeModel(GL_FLAT);
395 // make sure zbuffer is enabled
396 glEnable(GL_DEPTH_TEST);
397 // glDisable(GL_ALPHA_TEST);
400 if (r_fullbright.value) // LordHavoc: easy to do fullbright...
402 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
404 for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
406 if (p->texnum != texnum)
409 glBindTexture(GL_TEXTURE_2D, texnum);
411 vert = &wallvert[p->firstvert];
413 for (j=0 ; j<p->numverts ; j++, vert++)
415 glTexCoord2f (vert->vert[3], vert->vert[4]);
416 glVertex3fv (vert->vert);
421 else if (r_multitexture.value)
423 if (gl_combine.value)
425 qglActiveTexture(GL_TEXTURE0_ARB);
426 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
427 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
428 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
429 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
430 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);
431 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
432 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
433 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
434 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
435 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
436 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
437 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_TEXTURE);
438 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
439 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
440 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);
441 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0);
442 glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0);
443 glEnable(GL_TEXTURE_2D);
444 qglActiveTexture(GL_TEXTURE1_ARB);
445 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
446 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
447 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
448 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
449 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);
450 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
451 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
452 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
453 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
454 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
455 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_PREVIOUS_ARB);
456 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_TEXTURE);
457 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
458 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
459 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);
460 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 4.0);
461 glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0);
462 glEnable(GL_TEXTURE_2D);
466 qglActiveTexture(GL_TEXTURE0_ARB);
467 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
468 glEnable(GL_TEXTURE_2D);
469 qglActiveTexture(GL_TEXTURE1_ARB);
470 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
471 glEnable(GL_TEXTURE_2D);
475 for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
477 if (p->texnum != texnum)
480 qglActiveTexture(GL_TEXTURE0_ARB);
481 glBindTexture(GL_TEXTURE_2D, texnum);
482 qglActiveTexture(GL_TEXTURE1_ARB);
484 if (p->lighttexnum != lighttexnum)
486 lighttexnum = p->lighttexnum;
487 glBindTexture(GL_TEXTURE_2D, lighttexnum);
489 vert = &wallvert[p->firstvert];
491 for (j=0 ; j<p->numverts ; j++, vert++)
493 qglMultiTexCoord2f(GL_TEXTURE0_ARB, vert->vert[3], vert->vert[4]); // texture
494 qglMultiTexCoord2f(GL_TEXTURE1_ARB, vert->vert[5], vert->vert[6]); // lightmap
495 glVertex3fv (vert->vert);
500 qglActiveTexture(GL_TEXTURE1_ARB);
501 glDisable(GL_TEXTURE_2D);
502 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
503 qglActiveTexture(GL_TEXTURE0_ARB);
504 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
508 // first do the textures
509 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
511 for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
513 if (p->texnum != texnum)
516 glBindTexture(GL_TEXTURE_2D, texnum);
518 vert = &wallvert[p->firstvert];
520 for (j=0 ; j<p->numverts ; j++, vert++)
522 glTexCoord2f (vert->vert[3], vert->vert[4]);
523 glVertex3fv (vert->vert);
527 // then modulate using the lightmaps
528 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
529 glBlendFunc(GL_ZERO, GL_SRC_COLOR);
532 for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
534 if (p->lighttexnum != texnum)
536 texnum = p->lighttexnum;
537 glBindTexture(GL_TEXTURE_2D, texnum);
539 vert = &wallvert[p->firstvert];
541 for (j=0 ; j<p->numverts ; j++, vert++)
543 glTexCoord2f (vert->vert[5], vert->vert[6]);
544 glVertex3fv (vert->vert);
549 // switch to additive mode settings
551 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
552 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
554 // glDisable(GL_ALPHA_TEST);
555 glShadeModel(GL_SMOOTH);
556 // render vertex lit overlays ontop
558 for (i = 0, p = wallpoly;i < currentwallpoly;i++, p++)
562 for (j = 0,vertcolor = &wallvertcolor[p->firstvert];j < p->numverts;j++, vertcolor++)
563 if (vertcolor->r || vertcolor->g || vertcolor->b)
568 if (p->texnum != texnum)
571 glBindTexture(GL_TEXTURE_2D, texnum);
574 for (j = 0,vert = &wallvert[p->firstvert], vertcolor = &wallvertcolor[p->firstvert];j < p->numverts;j++, vert++, vertcolor++)
576 // would be 2fv, but windoze Matrox G200 and probably G400 drivers don't support that (dumb...)
577 glTexCoord2f(vert->vert[3], vert->vert[4]);
578 // again, vector version isn't supported I think
579 glColor3ub(vertcolor->r, vertcolor->g, vertcolor->b);
580 glVertex3fv(vert->vert);
584 // render glow textures
585 glShadeModel(GL_FLAT);
586 glBlendFunc(GL_ONE, GL_ONE);
588 glColor3f(0.5,0.5,0.5);
592 for (i = 0,p = wallpoly;i < currentwallpoly;i++, p++)
596 if (p->glowtexnum != texnum)
598 texnum = p->glowtexnum;
599 glBindTexture(GL_TEXTURE_2D, texnum);
601 vert = &wallvert[p->firstvert];
603 for (j=0 ; j<p->numverts ; j++, vert++)
605 glTexCoord2f (vert->vert[3], vert->vert[4]);
606 glVertex3fv (vert->vert);
611 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
612 glShadeModel(GL_SMOOTH);
616 glDisable(GL_TEXTURE_2D);
617 for (i = 0,p = &wallpoly[0];i < currentwallpoly;i++, p++)
619 vert = &wallvert[p->firstvert];
621 for (j=0 ; j<p->numverts ; j++, vert++)
623 VectorSubtract(vert->vert, r_origin, diff);
624 glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
625 glVertex3fv (vert->vert);
629 glEnable(GL_TEXTURE_2D);
631 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
632 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
633 // glDisable(GL_ALPHA_TEST);
634 glShadeModel(GL_SMOOTH);
639 static int skyrendersphere;
640 static int skyrenderbox;
641 static int skyrenderglquakepolys;
642 static int skyrendertwolayers;
643 static int skyrendercombine;
645 void skypolyclear(void)
647 currentskypoly = currentskyvert = 0;
648 skyrendersphere = false;
649 skyrenderbox = false;
650 skyrenderglquakepolys = false;
651 skyrendertwolayers = false;
652 skyrendercombine = false;
653 if (r_skyquality.value >= 1 && !fogenabled)
655 if (skyavailable_box)
657 else if (skyavailable_quake)
659 switch((int) r_skyquality.value)
662 skyrenderglquakepolys = true;
665 skyrenderglquakepolys = true;
666 skyrendertwolayers = true;
667 if (gl_combine.value)
668 skyrendercombine = true;
671 skyrendersphere = true;
675 skyrendersphere = true;
676 skyrendertwolayers = true;
677 if (gl_combine.value)
678 skyrendercombine = true;
683 if (r_mergesky.value && (skyrenderglquakepolys || skyrendersphere))
685 skyrendertwolayers = false;
686 skyrendercombine = false;
687 // R_BuildSky((int) (cl.time * 8.0), (int) (cl.time * 16.0));
688 // R_BuildSky((int) (cl.time * -8.0), 0);
689 R_BuildSky(0, (int) (cl.time * 8.0));
694 void skypolyrender(void)
699 float length, speedscale;
704 if (currentskypoly < 1)
706 // glDisable(GL_ALPHA_TEST);
708 // make sure zbuffer is enabled
709 glEnable(GL_DEPTH_TEST);
711 glVertexPointer(3, GL_FLOAT, sizeof(skyvert_t), &skyvert[0].v[0]);
712 glEnableClientState(GL_VERTEX_ARRAY);
713 GL_LockArray(0, currentskyvert);
714 speedscale = cl.time * (8.0/128.0);
715 speedscale -= (int)speedscale;
716 for (vert = skyvert, j = 0;j < currentskyvert;j++, vert++)
718 VectorSubtract (vert->v, r_origin, dir);
719 // flatten the sphere
722 // LordHavoc: fast version
723 number = DotProduct(dir, dir);
724 *((long *)&y) = 0x5f3759df - ((* (long *) &number) >> 1);
725 length = 3.0f * (y * (1.5f - (number * 0.5f * y * y)));
726 // LordHavoc: slow version
727 //length = 3.0f / sqrt(DotProduct(dir, dir));
729 vert->tex2[0] = speedscale + (vert->tex[0] = speedscale + dir[0] * length);
730 vert->tex2[1] = speedscale + (vert->tex[1] = speedscale + dir[1] * length);
734 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
736 if (skyrenderglquakepolys)
738 glTexCoordPointer(2, GL_FLOAT, sizeof(skyvert_t), &skyvert[0].tex[0]);
739 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
741 if (skyrendercombine)
744 glBindTexture(GL_TEXTURE_2D, R_GetTexture(lighthalf ? solidskytexture_half : solidskytexture));
746 // set up the second texcoord array
747 // switch texcoord array selector to TMU 1
748 qglClientActiveTexture(GL_TEXTURE1_ARB);
749 glTexCoordPointer(2, GL_FLOAT, sizeof(skyvert_t), &skyvert[0].tex2[0]);
750 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
752 // render both layers as one pass using GL_ARB_texture_env_combine
753 // TMU 0 is already selected, the TMU 0 texcoord array is already
754 // set up, the texture is bound, and texturing is already enabled,
755 // so just set up COMBINE
757 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
759 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
760 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
761 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
762 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);
763 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
764 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
765 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
767 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
768 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
769 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
770 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_TEXTURE);
771 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
772 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
773 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);
775 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0);
776 glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0);
779 qglActiveTexture(GL_TEXTURE1_ARB);
781 glBindTexture(GL_TEXTURE_2D, R_GetTexture(lighthalf ? alphaskytexture_half : alphaskytexture));
783 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
785 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
786 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
787 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
788 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);
789 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
790 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
791 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
793 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
794 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
795 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
796 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_TEXTURE);
797 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
798 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
799 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);
801 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0);
802 glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0);
803 glEnable(GL_TEXTURE_2D);
806 for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
807 glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
809 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
810 glDisable(GL_TEXTURE_2D);
811 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
812 qglActiveTexture(GL_TEXTURE0_ARB);
813 // switch texcoord array selector back to TMU 0
814 qglClientActiveTexture(GL_TEXTURE0_ARB);
815 // the TMU 0 texcoord array is disabled by the code below
819 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
820 if (r_mergesky.value)
821 glBindTexture(GL_TEXTURE_2D, R_GetTexture(mergeskytexture)); // both layers in one texture
823 glBindTexture(GL_TEXTURE_2D, R_GetTexture(solidskytexture)); // upper clouds
825 glColor3f(0.5f, 0.5f, 0.5f);
827 glColor3f(1.0f,1.0f,1.0f);
828 glEnable(GL_TEXTURE_2D);
829 GL_LockArray(0, currentskyvert);
830 for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
831 glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
833 if (skyrendertwolayers)
837 glBindTexture(GL_TEXTURE_2D, R_GetTexture(alphaskytexture)); // lower clouds
838 // switch to lower clouds texcoord array
839 glTexCoordPointer(2, GL_FLOAT, sizeof(skyvert_t), &skyvert[0].tex2[0]);
840 for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
841 glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
847 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
851 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
852 glDisable(GL_TEXTURE_2D);
853 // note: this color is not seen if skyrendersphere or skyrenderbox is on
854 glColor3fv(fogcolor);
855 for (i = 0, p = &skypoly[0];i < currentskypoly;i++, p++)
856 glDrawArrays(GL_POLYGON, p->firstvert, p->verts);
858 glEnable(GL_TEXTURE_2D);
861 glDisableClientState(GL_VERTEX_ARRAY);
864 static char skyname[256];
871 char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
872 rtexture_t *skyboxside[6];
873 int R_SetSkyBox(char *sky)
879 if (strcmp(sky, skyname) == 0) // no change
882 if (strlen(sky) > 1000)
884 Con_Printf ("sky name too long (%i, max is 1000)\n", strlen(sky));
888 skyboxside[0] = skyboxside[1] = skyboxside[2] = skyboxside[3] = skyboxside[4] = skyboxside[5] = NULL;
889 skyavailable_box = false;
895 for (i = 0;i < 6;i++)
897 sprintf (name, "env/%s%s", sky, suf[i]);
898 if (!(image_rgba = loadimagepixels(name, false, 0, 0)))
900 sprintf (name, "gfx/env/%s%s", sky, suf[i]);
901 if (!(image_rgba = loadimagepixels(name, false, 0, 0)))
903 Con_Printf ("Couldn't load %s\n", name);
907 skyboxside[i] = R_LoadTexture(va("skyboxside%d", i), image_width, image_height, image_rgba, TEXF_RGBA | TEXF_PRECACHE);
911 if (skyboxside[0] || skyboxside[1] || skyboxside[2] || skyboxside[3] || skyboxside[4] || skyboxside[5])
913 skyavailable_box = true;
914 strcpy(skyname, sky);
920 // LordHavoc: added LoadSky console command
921 void LoadSky_f (void)
927 Con_Printf("current sky: %s\n", skyname);
929 Con_Printf("no skybox has been set\n");
932 if (R_SetSkyBox(Cmd_Argv(1)))
935 Con_Printf("skybox set to %s\n", skyname);
937 Con_Printf("skybox disabled\n");
940 Con_Printf("failed to load skybox %s\n", Cmd_Argv(1));
943 Con_Printf("usage: loadsky skyname\n");
948 #define R_SkyBoxPolyVec(s,t,x,y,z) \
949 glTexCoord2f((s) * (254.0f/256.0f) + (1.0f/256.0f), (t) * (254.0f/256.0f) + (1.0f/256.0f));\
950 glVertex3f((x) * 1024.0 + r_origin[0], (y) * 1024.0 + r_origin[1], (z) * 1024.0 + r_origin[2]);
954 glDisable(GL_DEPTH_TEST);
956 glDisable (GL_BLEND);
957 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
959 glColor3f(0.5,0.5,0.5);
962 glBindTexture(GL_TEXTURE_2D, R_GetTexture(skyboxside[3])); // front
964 R_SkyBoxPolyVec(1, 0, 1, -1, 1);
965 R_SkyBoxPolyVec(1, 1, 1, -1, -1);
966 R_SkyBoxPolyVec(0, 1, 1, 1, -1);
967 R_SkyBoxPolyVec(0, 0, 1, 1, 1);
969 glBindTexture(GL_TEXTURE_2D, R_GetTexture(skyboxside[1])); // back
971 R_SkyBoxPolyVec(1, 0, -1, 1, 1);
972 R_SkyBoxPolyVec(1, 1, -1, 1, -1);
973 R_SkyBoxPolyVec(0, 1, -1, -1, -1);
974 R_SkyBoxPolyVec(0, 0, -1, -1, 1);
976 glBindTexture(GL_TEXTURE_2D, R_GetTexture(skyboxside[0])); // right
978 R_SkyBoxPolyVec(1, 0, 1, 1, 1);
979 R_SkyBoxPolyVec(1, 1, 1, 1, -1);
980 R_SkyBoxPolyVec(0, 1, -1, 1, -1);
981 R_SkyBoxPolyVec(0, 0, -1, 1, 1);
983 glBindTexture(GL_TEXTURE_2D, R_GetTexture(skyboxside[2])); // left
985 R_SkyBoxPolyVec(1, 0, -1, -1, 1);
986 R_SkyBoxPolyVec(1, 1, -1, -1, -1);
987 R_SkyBoxPolyVec(0, 1, 1, -1, -1);
988 R_SkyBoxPolyVec(0, 0, 1, -1, 1);
990 glBindTexture(GL_TEXTURE_2D, R_GetTexture(skyboxside[4])); // up
992 R_SkyBoxPolyVec(1, 0, 1, -1, 1);
993 R_SkyBoxPolyVec(1, 1, 1, 1, 1);
994 R_SkyBoxPolyVec(0, 1, -1, 1, 1);
995 R_SkyBoxPolyVec(0, 0, -1, -1, 1);
997 glBindTexture(GL_TEXTURE_2D, R_GetTexture(skyboxside[5])); // down
999 R_SkyBoxPolyVec(1, 0, 1, 1, -1);
1000 R_SkyBoxPolyVec(1, 1, 1, -1, -1);
1001 R_SkyBoxPolyVec(0, 1, -1, -1, -1);
1002 R_SkyBoxPolyVec(0, 0, -1, 1, -1);
1005 glEnable (GL_DEPTH_TEST);
1009 float skysphere[33*33*5];
1010 int skysphereindices[32*32*6];
1011 void skyspherecalc(float *sphere, float dx, float dy, float dz)
1013 float a, b, x, ax, ay, v[3], length;
1015 for (a = 0;a <= 1;a += (1.0 / 32.0))
1017 ax = cos(a * M_PI * 2);
1018 ay = -sin(a * M_PI * 2);
1019 for (b = 0;b <= 1;b += (1.0 / 32.0))
1021 x = cos(b * M_PI * 2);
1024 v[2] = -sin(b * M_PI * 2) * dz;
1025 length = 3.0f / sqrt(v[0]*v[0]+v[1]*v[1]+(v[2]*v[2]*9));
1026 *sphere++ = v[0] * length;
1027 *sphere++ = v[1] * length;
1033 index = skysphereindices;
1034 for (j = 0;j < 32;j++)
1036 for (i = 0;i < 32;i++)
1038 *index++ = j * 33 + i;
1039 *index++ = j * 33 + i + 1;
1040 *index++ = (j + 1) * 33 + i;
1042 *index++ = j * 33 + i + 1;
1043 *index++ = (j + 1) * 33 + i + 1;
1044 *index++ = (j + 1) * 33 + i;
1050 void skyspherearrays(float *vert, float *tex, float *tex2, float *source, float s, float s2)
1057 for (i = 0;i < (33*33);i++)
1059 *t++ = source[0] + s;
1060 *t++ = source[1] + s;
1061 *t2++ = source[0] + s2;
1062 *t2++ = source[1] + s2;
1063 *v++ = source[2] + r_origin[0];
1064 *v++ = source[3] + r_origin[1];
1065 *v++ = source[4] + r_origin[2];
1071 void R_SkySphere(void)
1073 float speedscale, speedscale2;
1074 float vert[33*33*4], tex[33*33*2], tex2[33*33*2];
1075 static qboolean skysphereinitialized = false;
1076 if (!skysphereinitialized)
1078 skysphereinitialized = true;
1079 skyspherecalc(skysphere, 1024, 1024, 1024 / 3);
1081 glDisable(GL_DEPTH_TEST);
1083 glDisable (GL_BLEND);
1084 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1085 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1087 glColor3f(0.5,0.5,0.5);
1090 speedscale = cl.time*8.0/128.0;
1091 speedscale -= (int)speedscale;
1092 speedscale2 = cl.time*16.0/128.0;
1093 speedscale2 -= (int)speedscale2;
1094 skyspherearrays(vert, tex, tex2, skysphere, speedscale, speedscale2);
1095 glVertexPointer(3, GL_FLOAT, sizeof(float) * 4, vert);
1096 glEnableClientState(GL_VERTEX_ARRAY);
1097 // do not lock the texcoord array, because it will be switched
1098 GL_LockArray(0, 32*32*6);
1099 glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, tex);
1100 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1101 if (r_mergesky.value)
1103 glBindTexture(GL_TEXTURE_2D, R_GetTexture(mergeskytexture)); // both layers in one texture
1104 glDrawElements(GL_TRIANGLES, 32*32*6, GL_UNSIGNED_INT, &skysphereindices[0]);
1108 // LordHavoc: note that this combine operation does not use the color,
1109 // so it has to use alternate textures in lighthalf mode
1110 if (skyrendercombine)
1113 glBindTexture(GL_TEXTURE_2D, R_GetTexture(lighthalf ? solidskytexture_half : solidskytexture));
1115 // set up the second texcoord array
1116 // switch texcoord array selector to TMU 1
1117 qglClientActiveTexture(GL_TEXTURE1_ARB);
1118 glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, tex2);
1119 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1122 // render both layers as one pass using GL_ARB_texture_env_combine
1123 // TMU 0 is already selected, the TMU 0 texcoord array is already
1124 // set up, the texture is bound, and texturing is already enabled,
1125 // so just set up COMBINE
1127 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
1129 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
1130 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
1131 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
1132 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);
1133 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
1134 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
1135 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
1137 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
1138 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
1139 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
1140 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_TEXTURE);
1141 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
1142 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
1143 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);
1145 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0);
1146 glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0);
1149 qglActiveTexture(GL_TEXTURE1_ARB);
1151 glBindTexture(GL_TEXTURE_2D, R_GetTexture(lighthalf ? alphaskytexture_half : alphaskytexture));
1153 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
1155 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
1156 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
1157 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
1158 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);
1159 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
1160 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
1161 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
1163 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
1164 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
1165 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
1166 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_TEXTURE);
1167 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
1168 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
1169 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);
1171 glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0);
1172 glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0);
1173 glEnable(GL_TEXTURE_2D);
1176 glDrawElements(GL_TRIANGLES, 32*32*6, GL_UNSIGNED_INT, &skysphereindices[0]);
1178 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1179 glDisable(GL_TEXTURE_2D);
1180 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1181 qglActiveTexture(GL_TEXTURE0_ARB);
1182 // switch texcoord array selector back to TMU 0
1183 qglClientActiveTexture(GL_TEXTURE0_ARB);
1184 // the TMU 0 texcoord array is disabled by the code below
1188 glBindTexture(GL_TEXTURE_2D, R_GetTexture(solidskytexture)); // upper clouds
1189 glDrawElements(GL_TRIANGLES, 32*32*6, GL_UNSIGNED_INT, &skysphereindices[0]);
1191 if (skyrendertwolayers)
1193 glEnable (GL_BLEND);
1194 glBindTexture(GL_TEXTURE_2D, R_GetTexture(alphaskytexture)); // lower clouds
1195 glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, tex2);
1196 glDrawElements(GL_TRIANGLES, 32*32*6, GL_UNSIGNED_INT, &skysphereindices[0]);
1197 glDisable (GL_BLEND);
1201 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1203 glDisableClientState(GL_VERTEX_ARRAY);
1204 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1206 glEnable (GL_DEPTH_TEST);
1212 if (!r_render.value)
1214 if (skyrendersphere)
1216 else if (skyrenderbox)
1220 //===============================================================
1222 byte skyupperlayerpixels[128*128*4];
1223 byte skylowerlayerpixels[128*128*4];
1224 byte skymergedpixels[128*128*4];
1226 void R_BuildSky (int scrollupper, int scrolllower)
1228 int x, y, ux, uy, lx, ly;
1230 m = skymergedpixels;
1231 for (y = 0;y < 128;y++)
1233 uy = (y + scrollupper) & 127;
1234 ly = (y + scrolllower) & 127;
1235 for (x = 0;x < 128;x++)
1237 ux = (x + scrollupper) & 127;
1238 lx = (x + scrolllower) & 127;
1239 u = &skyupperlayerpixels[(uy * 128 + ux) * 4];
1240 l = &skylowerlayerpixels[(ly * 128 + lx) * 4];
1244 *((int *)m) = *((int *)l);
1247 m[0] = ((((int) l[0] - (int) u[0]) * (int) l[3]) >> 8) + (int) u[0];
1248 m[1] = ((((int) l[1] - (int) u[1]) * (int) l[3]) >> 8) + (int) u[1];
1249 m[2] = ((((int) l[2] - (int) u[2]) * (int) l[3]) >> 8) + (int) u[2];
1254 *((int *)m) = *((int *)u);
1258 // FIXME: implement generated texture callbacks to speed this up? (skip identifier lookup, CRC, memcpy, etc)
1259 if (mergeskytexture)
1261 glBindTexture(GL_TEXTURE_2D, R_GetTexture(mergeskytexture));
1262 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 128, 128, GL_RGBA, GL_UNSIGNED_BYTE, skymergedpixels);
1265 mergeskytexture = R_LoadTexture("mergedskytexture", 128, 128, skymergedpixels, TEXF_RGBA | TEXF_ALWAYSPRECACHE);
1272 A sky texture is 256*128, with the right side being a masked overlay
1275 void R_InitSky (byte *src, int bytesperpixel)
1278 unsigned trans[128*128];
1286 strcpy(skyworldname, loadmodel->name);
1287 if (bytesperpixel == 4)
1289 for (i = 0;i < 128;i++)
1290 for (j = 0;j < 128;j++)
1291 trans[(i*128) + j] = src[i*256+j+128];
1295 // make an average value for the back to avoid
1296 // a fringe on the top level
1298 for (i=0 ; i<128 ; i++)
1300 for (j=0 ; j<128 ; j++)
1302 p = src[i*256 + j + 128];
1303 rgba = &d_8to24table[p];
1304 trans[(i*128) + j] = *rgba;
1305 r += ((byte *)rgba)[0];
1306 g += ((byte *)rgba)[1];
1307 b += ((byte *)rgba)[2];
1311 ((byte *)&transpix)[0] = r/(128*128);
1312 ((byte *)&transpix)[1] = g/(128*128);
1313 ((byte *)&transpix)[2] = b/(128*128);
1314 ((byte *)&transpix)[3] = 0;
1317 memcpy(skyupperlayerpixels, trans, 128*128*4);
1319 solidskytexture = R_LoadTexture ("sky_solidtexture", 128, 128, (byte *) trans, TEXF_RGBA | TEXF_PRECACHE);
1320 for (i = 0;i < 128*128;i++)
1322 ((byte *)&trans[i])[0] >>= 1;
1323 ((byte *)&trans[i])[1] >>= 1;
1324 ((byte *)&trans[i])[2] >>= 1;
1326 solidskytexture_half = R_LoadTexture ("sky_solidtexture_half", 128, 128, (byte *) trans, TEXF_RGBA | TEXF_PRECACHE);
1328 if (bytesperpixel == 4)
1330 for (i = 0;i < 128;i++)
1331 for (j = 0;j < 128;j++)
1332 trans[(i*128) + j] = src[i*256+j];
1336 for (i=0 ; i<128 ; i++)
1338 for (j=0 ; j<128 ; j++)
1342 trans[(i*128) + j] = transpix;
1344 trans[(i*128) + j] = d_8to24table[p];
1349 memcpy(skylowerlayerpixels, trans, 128*128*4);
1351 alphaskytexture = R_LoadTexture ("sky_alphatexture", 128, 128, (byte *) trans, TEXF_ALPHA | TEXF_RGBA | TEXF_PRECACHE);
1352 for (i = 0;i < 128*128;i++)
1354 ((byte *)&trans[i])[0] >>= 1;
1355 ((byte *)&trans[i])[1] >>= 1;
1356 ((byte *)&trans[i])[2] >>= 1;
1358 alphaskytexture_half = R_LoadTexture ("sky_alphatexture_half", 128, 128, (byte *) trans, TEXF_ALPHA | TEXF_RGBA | TEXF_PRECACHE);