1 /*
2 ** gl_sky.cpp
3 **
4 ** Draws the sky. Loosely based on the JDoom sky and the ZDoomGL 0.66.2 sky.
5 **
6 **---------------------------------------------------------------------------
7 ** Copyright 2003 Tim Stump
8 ** Copyright 2005 Christoph Oelckers
9 ** Copyright 2009 Andrey Budko
10 ** All rights reserved.
11 **
12 ** Redistribution and use in source and binary forms, with or without
13 ** modification, are permitted provided that the following conditions
14 ** are met:
15 **
16 ** 1. Redistributions of source code must retain the above copyright
17 ** notice, this list of conditions and the following disclaimer.
18 ** 2. Redistributions in binary form must reproduce the above copyright
19 ** notice, this list of conditions and the following disclaimer in the
20 ** documentation and/or other materials provided with the distribution.
21 ** 3. The name of the author may not be used to endorse or promote products
22 ** derived from this software without specific prior written permission.
23 ** 4. Full disclosure of the entire project's source code, except for third
24 ** party libraries is mandatory. (NOTE: This clause is non-negotiable!)
25 **
26 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 **---------------------------------------------------------------------------
37 **
38 */
39
40 #ifdef HAVE_CONFIG_H
41 #include "config.h"
42 #endif
43
44 #include "gl_opengl.h"
45
46 #include <SDL.h>
47
48 #include "doomstat.h"
49 #include "v_video.h"
50 #include "gl_intern.h"
51 #include "r_plane.h"
52 #include "r_sky.h"
53 #include "r_main.h"
54 #include "sc_man.h"
55 #include "m_misc.h"
56 #include "lprintf.h"
57
58 #include "e6y.h"
59
60 typedef struct
61 {
62 int mode;
63 int vertexcount;
64 int vertexindex;
65 int use_texture;
66 } GLSkyLoopDef;
67
68 typedef struct
69 {
70 int id;
71 int rows, columns;
72 int loopcount;
73 GLSkyLoopDef *loops;
74 vbo_vertex_t *data;
75 } GLSkyVBO;
76
77 int gl_skymode;
78 int gl_drawskys;
79 // Sky stretching is rather pointless with the GL renderer
80 // now that it can handle all sky heights.
81 int gl_stretchsky = false;
82
83 static PalEntry_t *SkyColor;
84
85 SkyBoxParams_t SkyBox;
86 float y_offset_saved;
87
88 // skybox
89 box_skybox_t *BoxSkybox = NULL;
90 int BoxSkyboxCount = 0;
91
92 box_skybox_t *BoxSkybox_default;
93
gld_InitSky(void)94 void gld_InitSky(void)
95 {
96 memset(&SkyBox, 0, sizeof(SkyBox));
97 SkyBox.index = -1;
98 y_offset_saved = 0;
99 }
100
gld_InitFrameSky(void)101 void gld_InitFrameSky(void)
102 {
103 SkyBox.type = SKY_NONE;
104 SkyBox.wall.gltexture = NULL;
105 SkyBox.x_scale = 0;
106 SkyBox.y_scale = 0;
107 SkyBox.x_offset = 0;
108 SkyBox.y_offset = 0;
109 SkyBox.side = NULL;
110 }
111
gld_DrawFakeSkyStrips(void)112 void gld_DrawFakeSkyStrips(void)
113 {
114 int i;
115
116 // This draws a valid z-buffer into the stencil's contents to ensure it
117 // doesn't get overwritten by the level's geometry.
118
119 // Because some of outdated hardware has no support for
120 // glColorMask(0, 0, 0, 0) or something,
121 // I need to render fake strips of sky before dome with using
122 // full clearing of color buffer (only in compatibility mode)
123
124 if (!gl_compatibility)
125 {
126 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // no graphics
127 }
128 gld_EnableTexture2D(GL_TEXTURE0_ARB, false);
129
130 for (i = gld_drawinfo.num_items[GLDIT_SWALL] - 1; i >= 0; i--)
131 {
132 GLWall* wall = gld_drawinfo.items[GLDIT_SWALL][i].item.wall;
133
134 glBegin(GL_TRIANGLE_STRIP);
135 glVertex3f(wall->glseg->x1,wall->ytop,wall->glseg->z1);
136 glVertex3f(wall->glseg->x1,wall->ybottom,wall->glseg->z1);
137 glVertex3f(wall->glseg->x2,wall->ytop,wall->glseg->z2);
138 glVertex3f(wall->glseg->x2,wall->ybottom,wall->glseg->z2);
139 glEnd();
140 }
141
142 gld_EnableTexture2D(GL_TEXTURE0_ARB, true);
143 if (!gl_compatibility)
144 {
145 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
146 }
147 else
148 {
149 glClear(GL_COLOR_BUFFER_BIT);
150 }
151 }
152
gld_GetScreenSkyScale(GLWall * wall,float * scale_x,float * scale_y)153 void gld_GetScreenSkyScale(GLWall *wall, float *scale_x, float *scale_y)
154 {
155 float sx, sy;
156
157 sx = (wall->flag == GLDWF_SKYFLIP ? -128.0f : 128.0f);
158
159 if (!mlook_or_fov)
160 {
161 sx = sx / (float)wall->gltexture->buffer_width;
162 sy = 200.0f / 160.0f;//wall->gltexture->buffer_height;
163 }
164 else
165 {
166 sx = sx * skyscale / (float)wall->gltexture->buffer_width;
167 sy = 127.0f * skyscale / 160.0f;
168 }
169
170 *scale_x = sx;
171 *scale_y = sy;
172 }
173
174 // Sky textures with a zero index should be forced
175 // See third episode of requiem.wad
gld_AddSkyTexture(GLWall * wall,int sky1,int sky2,int skytype)176 void gld_AddSkyTexture(GLWall *wall, int sky1, int sky2, int skytype)
177 {
178 side_t *s = NULL;
179 line_t *l = NULL;
180 wall->gltexture = NULL;
181
182 if ((sky1) & PL_SKYFLAT)
183 {
184 l = &lines[sky1 & ~PL_SKYFLAT];
185 }
186 else
187 {
188 if ((sky2) & PL_SKYFLAT)
189 {
190 l = &lines[sky2 & ~PL_SKYFLAT];
191 }
192 }
193
194 if (l)
195 {
196 s = *l->sidenum + sides;
197 SkyBox.side = s;
198 wall->gltexture = gld_RegisterTexture(texturetranslation[s->toptexture], false,
199 texturetranslation[s->toptexture] == skytexture || l->special == 271 || l->special == 272);
200 if (wall->gltexture)
201 {
202 if (!mlook_or_fov)
203 {
204 wall->skyyaw = -2.0f*((-(float)((viewangle+s->textureoffset)>>ANGLETOFINESHIFT)*360.0f/FINEANGLES)/90.0f);
205 wall->skyymid = 200.0f/319.5f*(((float)s->rowoffset/(float)FRACUNIT - 28.0f)/100.0f);
206 }
207 else
208 {
209 wall->skyyaw = -2.0f*(((270.0f-(float)((viewangle+s->textureoffset)>>ANGLETOFINESHIFT)*360.0f/FINEANGLES)+90.0f)/90.0f/skyscale);
210 wall->skyymid = skyYShift+(((float)s->rowoffset/(float)FRACUNIT)/100.0f);
211 }
212 wall->flag = (l->special == 272 ? GLDWF_SKY : GLDWF_SKYFLIP);
213 }
214 }
215 else
216 {
217 wall->gltexture = gld_RegisterTexture(skytexture, false, true);
218 if (wall->gltexture)
219 {
220 wall->skyyaw = skyXShift;
221 wall->skyymid = skyYShift;
222 wall->flag = GLDWF_SKY;
223 }
224 }
225
226 if (wall->gltexture)
227 {
228 SkyBox.type |= skytype;
229
230 wall->gltexture->flags |= GLTEXTURE_SKY;
231
232 gld_AddDrawItem(GLDIT_SWALL, wall);
233
234 if (!SkyBox.wall.gltexture)
235 {
236 SkyBox.wall = *wall;
237
238 switch (gl_drawskys)
239 {
240 case skytype_standard:
241 gld_GetScreenSkyScale(wall, &SkyBox.x_scale, &SkyBox.y_scale);
242 break;
243
244 case skytype_screen:
245 if (s)
246 {
247 SkyBox.x_offset = (float)s->textureoffset;
248 SkyBox.y_offset = (float)s->rowoffset / (float)FRACUNIT;
249 }
250 break;
251 case skytype_skydome:
252 if (s)
253 {
254 SkyBox.x_offset = (float)s->textureoffset * 180.0f / (float)ANG180;
255 SkyBox.y_offset = (float)s->rowoffset / (float)FRACUNIT;
256 }
257 break;
258 }
259 }
260 }
261 }
262
gld_DrawStripsSky(void)263 void gld_DrawStripsSky(void)
264 {
265 int i;
266 float skyymid_multiplier;
267 GLTexture *gltexture = NULL;
268
269 if (gl_drawskys == skytype_standard)
270 {
271 if (comp[comp_skymap] && gl_shared_texture_palette)
272 glDisable(GL_SHARED_TEXTURE_PALETTE_EXT);
273
274 if (comp[comp_skymap] && (invul_method & INVUL_BW))
275 glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
276
277 glEnable(GL_TEXTURE_GEN_S);
278 glEnable(GL_TEXTURE_GEN_T);
279 glEnable(GL_TEXTURE_GEN_Q);
280 if (comp[comp_skymap] || !(invul_method & INVUL_BW))
281 glColor4fv(gl_whitecolor);
282
283 SetTextureMode(TM_OPAQUE);
284 }
285
286 gld_EnableDetail(false);
287 glMatrixMode(GL_TEXTURE);
288
289 skyymid_multiplier = 1.0f;
290 if (wide_ratio & 4)
291 {
292 skyymid_multiplier = (float)BaseRatioSizes[wide_ratio].multiplier / 48.0f;
293 }
294
295 for (i = gld_drawinfo.num_items[GLDIT_SWALL] - 1; i >= 0; i--)
296 {
297 GLWall *wall = gld_drawinfo.items[GLDIT_SWALL][i].item.wall;
298
299 gltexture = (gl_drawskys == skytype_none ? NULL : wall->gltexture);
300 gld_BindTexture(gltexture, 0);
301
302 if (!gltexture)
303 {
304 glColor4f(1.0f,0.0f,0.0f,1.0f);
305 }
306
307 if (gltexture)
308 {
309 float sx, sy;
310
311 glPushMatrix();
312
313 gld_GetScreenSkyScale(wall, &sx, &sy);
314 glScalef(sx, sy * skyymid_multiplier, 1.0f);
315 glTranslatef(wall->skyyaw, wall->skyymid / skyymid_multiplier, 0.0f);
316 }
317
318 #if 0
319 {
320 float r = (float)(wall->seg->sidedef - sides) / (float)(numsides - 1);
321 float g = (float)wall->seg->linedef->iLineID / (float)(numlines - 1);
322 float b = (float)i / (float)(gld_drawinfo.num_items[GLDIT_SWALL] - 1);
323 glColor4f(r, g, b, 1.0f);
324 }
325 #endif
326
327 glBegin(GL_TRIANGLE_STRIP);
328 glVertex3f(wall->glseg->x1,wall->ytop,wall->glseg->z1);
329 glVertex3f(wall->glseg->x1,wall->ybottom,wall->glseg->z1);
330 glVertex3f(wall->glseg->x2,wall->ytop,wall->glseg->z2);
331 glVertex3f(wall->glseg->x2,wall->ybottom,wall->glseg->z2);
332 glEnd();
333
334 if (gltexture)
335 {
336 glPopMatrix();
337 }
338 }
339
340 glMatrixMode(GL_MODELVIEW);
341
342 gld_DrawSkyCaps();
343
344 if (gl_drawskys == skytype_standard)
345 {
346 glDisable(GL_TEXTURE_GEN_Q);
347 glDisable(GL_TEXTURE_GEN_T);
348 glDisable(GL_TEXTURE_GEN_S);
349
350 if (comp[comp_skymap] && (invul_method & INVUL_BW))
351 glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB,GL_COMBINE);
352
353 if (comp[comp_skymap] && gl_shared_texture_palette)
354 glEnable(GL_SHARED_TEXTURE_PALETTE_EXT);
355
356 SetTextureMode(TM_MODULATE);
357 }
358 }
359
gld_DrawSkyCaps(void)360 void gld_DrawSkyCaps(void)
361 {
362 if (SkyBox.type && SkyBox.wall.gltexture)
363 {
364 dboolean mlook = GetMouseLook();
365
366 if (mlook)
367 {
368 gld_BindTexture(SkyBox.wall.gltexture, 0);
369
370 glMatrixMode(GL_TEXTURE);
371 glPushMatrix();
372
373 glScalef(SkyBox.x_scale, SkyBox.y_scale, 1.0f);
374 glTranslatef(SkyBox.wall.skyyaw, SkyBox.wall.skyymid, 0.0f);
375
376 if (SkyBox.type & SKY_CEILING)
377 {
378 glBegin(GL_TRIANGLE_STRIP);
379 glVertex3f(-MAXCOORD,+MAXCOORD,+MAXCOORD);
380 glVertex3f(+MAXCOORD,+MAXCOORD,+MAXCOORD);
381 glVertex3f(-MAXCOORD,+MAXCOORD,-MAXCOORD);
382 glVertex3f(+MAXCOORD,+MAXCOORD,-MAXCOORD);
383 glEnd();
384 }
385
386 if (SkyBox.type & SKY_FLOOR)
387 {
388 glBegin(GL_TRIANGLE_STRIP);
389 glVertex3f(-MAXCOORD,-MAXCOORD,+MAXCOORD);
390 glVertex3f(+MAXCOORD,-MAXCOORD,+MAXCOORD);
391 glVertex3f(-MAXCOORD,-MAXCOORD,-MAXCOORD);
392 glVertex3f(+MAXCOORD,-MAXCOORD,-MAXCOORD);
393 glEnd();
394 }
395
396 glPopMatrix();
397 glMatrixMode(GL_MODELVIEW);
398 }
399 }
400 }
401
402 //===========================================================================
403 //
404 // averageColor
405 // input is RGBA8 pixel format.
406 // The resulting RGB color can be scaled uniformly so that the highest
407 // component becomes one.
408 //
409 //===========================================================================
410 #define APART(c) (((c)>>24)&0xff)
411 #define RPART(c) (((c)>>16)&0xff)
412 #define GPART(c) (((c)>>8)&0xff)
413 #define BPART(c) ((c)&0xff)
414
averageColor(PalEntry_t * PalEntry,const unsigned int * data,int size,fixed_t maxout_factor)415 void averageColor(PalEntry_t * PalEntry, const unsigned int *data, int size, fixed_t maxout_factor)
416 {
417 int i;
418 int maxv;
419 unsigned int r, g, b;
420
421 // First clear them.
422 r = g = b = 0;
423 if (size == 0)
424 {
425 PalEntry->r = 255;
426 PalEntry->g = 255;
427 PalEntry->b = 255;
428 return;
429 }
430 for(i = 0; i < size; i++)
431 {
432 r += BPART(data[i]);
433 g += GPART(data[i]);
434 b += RPART(data[i]);
435 }
436
437 r = r / size;
438 g = g / size;
439 b = b / size;
440
441 maxv=MAX(MAX(r,g),b);
442
443 if(maxv && maxout_factor)
444 {
445 maxout_factor = FixedMul(maxout_factor, 255);
446 r = r * maxout_factor / maxv;
447 g = g * maxout_factor / maxv;
448 b = b * maxout_factor / maxv;
449 }
450
451 PalEntry->r = r;
452 PalEntry->g = g;
453 PalEntry->b = b;
454 return;
455 }
456
457 // It is an alternative way of drawing the sky (gl_drawskys == skytype_screen)
458 // This method make sense only for old hardware which have no support for GL_TEXTURE_GEN_*
459 // Voodoo as example
gld_DrawScreenSkybox(void)460 void gld_DrawScreenSkybox(void)
461 {
462 if (SkyBox.wall.gltexture)
463 {
464 #define WRAPANGLE (ANGLE_MAX/4)
465
466 float fU1, fU2, fV1, fV2;
467 GLWall *wall = &SkyBox.wall;
468 angle_t angle;
469 int i, k;
470 float w;
471
472 if (!gl_compatibility)
473 {
474 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // no graphics
475 }
476 gld_EnableTexture2D(GL_TEXTURE0_ARB, false);
477
478 for (i = gld_drawinfo.num_items[GLDIT_SWALL] - 1; i >= 0; i--)
479 {
480 GLWall* wall = gld_drawinfo.items[GLDIT_SWALL][i].item.wall;
481
482 glBegin(GL_TRIANGLE_STRIP);
483 glVertex3f(wall->glseg->x1,wall->ytop,wall->glseg->z1);
484 glVertex3f(wall->glseg->x1,wall->ybottom,wall->glseg->z1);
485 glVertex3f(wall->glseg->x2,wall->ytop,wall->glseg->z2);
486 glVertex3f(wall->glseg->x2,wall->ybottom,wall->glseg->z2);
487 glEnd();
488 }
489
490 gld_EnableTexture2D(GL_TEXTURE0_ARB, true);
491 if (!gl_compatibility)
492 {
493 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
494 }
495 else
496 {
497 glClear(GL_COLOR_BUFFER_BIT);
498 }
499
500 if (!mlook_or_fov)
501 {
502 fV1 = SkyBox.y_offset / 127.0f;
503 fV2 = fV1 + 320.0f / 200.0f;
504 }
505 else
506 {
507 float f = viewPitch * 2 + 40 / skyscale;
508 f = BETWEEN(0, 127, f);
509 fV1 = (f + SkyBox.y_offset) / 127.0f * skyscale;
510 fV2 = fV1 + 1.0f;
511 }
512
513 k = MAX(wall->gltexture->buffer_width, 256) / 256;
514 angle = ((viewangle - ANG45) / k) % WRAPANGLE;
515
516 if (wall->flag == GLDWF_SKYFLIP)
517 {
518 fU1 = -((float)angle + SkyBox.x_offset) / (WRAPANGLE - 1);
519 fU2 = fU1 + 1.0f / k;
520 }
521 else
522 {
523 fU2 = ((float)angle + SkyBox.x_offset) / (WRAPANGLE - 1);
524 fU1 = fU2 + 1.0f / k;
525 }
526
527 glDisable(GL_DEPTH_TEST);
528 glDisable(GL_ALPHA_TEST);
529
530 glPushMatrix();
531 glMatrixMode(GL_MODELVIEW);
532 glLoadIdentity();
533
534 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
535 gld_BindTexture(wall->gltexture, 0);
536 w = 160.0f * SCREENWIDTH / WIDE_SCREENWIDTH;
537 glBegin(GL_TRIANGLE_STRIP);
538 glTexCoord2f(fU1, fV1); glVertex3f(-w, +100.5f, -screen_skybox_zplane);
539 glTexCoord2f(fU1, fV2); glVertex3f(-w, -100.5f, -screen_skybox_zplane);
540 glTexCoord2f(fU2, fV1); glVertex3f(+w, +100.5f, -screen_skybox_zplane);
541 glTexCoord2f(fU2, fV2); glVertex3f(+w, -100.5f, -screen_skybox_zplane);
542 glEnd();
543
544 glPopMatrix();
545
546 glEnable(GL_ALPHA_TEST);
547 glEnable(GL_DEPTH_TEST);
548 }
549 }
550
551 // The texture offset to be applied to the texture coordinates in SkyVertex().
552 static int rows, columns;
553 static dboolean yflip;
554 static int texw;
555 static float yMult, yAdd;
556 static dboolean foglayer;
557 static float delta = 0.0f;
558
559 int gl_sky_detail = 16;
560
561 //-----------------------------------------------------------------------------
562 //
563 //
564 //
565 //-----------------------------------------------------------------------------
566
gld_GetSkyCapColors(void)567 void gld_GetSkyCapColors(void)
568 {
569 int color, width, height;
570 int frame_fixedcolormap_saved;
571 unsigned char *buffer = NULL;
572 const unsigned char *playpal = V_GetPlaypal();
573 const lighttable_t *colormap;
574 const lighttable_t *fixedcolormap_saved;
575 PalEntry_t *ceiling_rgb = &SkyBox.CeilingSkyColor[0];
576 PalEntry_t *floor_rgb = &SkyBox.FloorSkyColor[0];
577
578 // saving current colormap
579 fixedcolormap_saved = fixedcolormap;
580 frame_fixedcolormap_saved = frame_fixedcolormap;
581
582 fixedcolormap = fullcolormap;
583 frame_fixedcolormap = 0;
584
585 gld_BindTexture(SkyBox.wall.gltexture, 0);
586
587 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
588 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
589
590 buffer = malloc(width * height * 4);
591 glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
592
593 averageColor(ceiling_rgb, (unsigned int*)buffer, width * MIN(30, height), 0);
594
595 if (height > 30)
596 {
597 averageColor(floor_rgb,
598 ((unsigned int*)buffer) + (height - 30) * width, width * 30, 0);
599 }
600 else
601 {
602 *floor_rgb = *ceiling_rgb;
603 }
604
605 colormap = fullcolormap + INVERSECOLORMAP * 256 * sizeof(lighttable_t);
606
607 color = V_BestColor(playpal, ceiling_rgb->r, ceiling_rgb->g, ceiling_rgb->b);
608 SkyBox.CeilingSkyColor[1].r = playpal[colormap[color] * 3 + 0];
609 SkyBox.CeilingSkyColor[1].g = playpal[colormap[color] * 3 + 1];
610 SkyBox.CeilingSkyColor[1].b = playpal[colormap[color] * 3 + 2];
611
612 color = V_BestColor(playpal, floor_rgb->r, floor_rgb->g, floor_rgb->b);
613 SkyBox.FloorSkyColor[1].r = playpal[colormap[color] * 3 + 0];
614 SkyBox.FloorSkyColor[1].g = playpal[colormap[color] * 3 + 1];
615 SkyBox.FloorSkyColor[1].b = playpal[colormap[color] * 3 + 2];
616
617 // restorin current colormap
618 fixedcolormap = fixedcolormap_saved;
619 frame_fixedcolormap = frame_fixedcolormap_saved;
620
621 free(buffer);
622 }
623
624 //-----------------------------------------------------------------------------
625 //
626 //
627 //
628 //-----------------------------------------------------------------------------
629
SkyVertex(vbo_vertex_t * vbo,int r,int c)630 static void SkyVertex(vbo_vertex_t *vbo, int r, int c)
631 {
632 static fixed_t scale = 10000 << FRACBITS;
633 static angle_t maxSideAngle = ANG180 / 3;
634
635 angle_t topAngle= (angle_t)(c / (float)columns * ANGLE_MAX);
636 angle_t sideAngle = maxSideAngle * (rows - r) / rows;
637 fixed_t height = finesine[sideAngle>>ANGLETOFINESHIFT];
638 fixed_t realRadius = FixedMul(scale, finecosine[sideAngle>>ANGLETOFINESHIFT]);
639 fixed_t x = FixedMul(realRadius, finecosine[topAngle>>ANGLETOFINESHIFT]);
640 fixed_t y = (!yflip) ? FixedMul(scale, height) : FixedMul(scale, height) * -1;
641 fixed_t z = FixedMul(realRadius, finesine[topAngle>>ANGLETOFINESHIFT]);
642 float timesRepeat;
643
644 timesRepeat = (short)(4 * (256.0f / texw));
645 if (timesRepeat == 0.0f)
646 timesRepeat = 1.0f;
647
648 if (!foglayer)
649 {
650 vbo->r = 255;
651 vbo->g = 255;
652 vbo->b = 255;
653 vbo->a = (r == 0 ? 0 : 255);
654
655 // And the texture coordinates.
656 if(!yflip) // Flipped Y is for the lower hemisphere.
657 {
658 vbo->u = (-timesRepeat * c / (float)columns) ;
659 vbo->v = (r / (float)rows) * 1.f * yMult + yAdd;
660 }
661 else
662 {
663 vbo->u = (-timesRepeat * c / (float)columns) ;
664 vbo->v = ((rows-r)/(float)rows) * 1.f * yMult + yAdd;
665 }
666
667 if (SkyBox.wall.flag == GLDWF_SKYFLIP)
668 vbo->u = -vbo->u;
669 }
670
671 if (r != 4)
672 {
673 y += FRACUNIT * 300;
674 }
675
676 // And finally the vertex.
677 vbo->x =-(float)x/(float)MAP_SCALE; // Doom mirrors the sky vertically!
678 vbo->y = (float)y/(float)MAP_SCALE + delta;
679 vbo->z = (float)z/(float)MAP_SCALE;
680 }
681
682 GLSkyVBO sky_vbo[2];
683
gld_BuildSky(int row_count,int col_count,SkyBoxParams_t * sky,int cm)684 static void gld_BuildSky(int row_count, int col_count, SkyBoxParams_t *sky, int cm)
685 {
686 int texh, c, r;
687 vbo_vertex_t *vertex_p;
688 int vertex_count = 2 * row_count * (col_count * 2 + 2) + col_count * 2;
689 int vbo_idx = (cm == INVERSECOLORMAP ? 1 : 0);
690 GLSkyVBO *vbo = &sky_vbo[vbo_idx];
691
692 if ((vbo->columns != col_count) || (vbo->rows != row_count))
693 {
694 free(vbo->loops);
695 free(vbo->data);
696 memset(vbo, 0, sizeof(vbo[0]));
697 }
698
699 if (!vbo->data)
700 {
701 memset(vbo, 0, sizeof(vbo[0]));
702 vbo->loops = malloc((row_count * 2 + 2) * sizeof(vbo->loops[0]));
703 // create vertex array
704 vbo->data = malloc(vertex_count * sizeof(vbo->data[0]));
705 }
706
707 vbo->columns = col_count;
708 vbo->rows = row_count;
709
710 texh = sky->wall.gltexture->buffer_height;
711 if (texh > 190 && gl_stretchsky)
712 texh = 190;
713 texw = sky->wall.gltexture->buffer_width;
714
715 vertex_p = &vbo->data[0];
716 vbo->loopcount = 0;
717 for (yflip = 0; yflip < 2; yflip++)
718 {
719 vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_FAN;
720 vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0];
721 vbo->loops[vbo->loopcount].vertexcount = col_count;
722 vbo->loops[vbo->loopcount].use_texture = false;
723 vbo->loopcount++;
724
725 yAdd = sky->y_offset / texh;
726 yMult = (texh <= 180 ? 1.0f : 180.0f / texh);
727 if (yflip == 0)
728 {
729 SkyColor = &sky->CeilingSkyColor[vbo_idx];
730 }
731 else
732 {
733 SkyColor = &sky->FloorSkyColor[vbo_idx];
734 if (texh <= 180) yMult = 1.0f; else yAdd += 180.0f / texh;
735 }
736
737 delta = 0.0f;
738 foglayer = true;
739 for(c = 0; c < col_count; c++)
740 {
741 SkyVertex(vertex_p, 1, c);
742 vertex_p->r = SkyColor->r;
743 vertex_p->g = SkyColor->g;
744 vertex_p->b = SkyColor->b;
745 vertex_p->a = 255;
746 vertex_p++;
747 }
748 foglayer = false;
749
750 delta = (yflip ? 5.0f : -5.0f) / MAP_COEFF;
751
752 for(r = 0; r < row_count; r++)
753 {
754 vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_STRIP;
755 vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0];
756 vbo->loops[vbo->loopcount].vertexcount = 2 * col_count + 2;
757 vbo->loops[vbo->loopcount].use_texture = true;
758 vbo->loopcount++;
759
760 for(c = 0; c <= col_count; c++)
761 {
762 SkyVertex(vertex_p++, r + (yflip ? 1 : 0), (c ? c : 0));
763 SkyVertex(vertex_p++, r + (yflip ? 0 : 1), (c ? c : 0));
764 }
765 }
766 }
767 }
768
769 //-----------------------------------------------------------------------------
770 //
771 //
772 //
773 //-----------------------------------------------------------------------------
774
RenderDome(SkyBoxParams_t * sky)775 static void RenderDome(SkyBoxParams_t *sky)
776 {
777 int i, j;
778 int vbosize;
779 GLSkyVBO *vbo;
780
781 if (!sky || !sky->wall.gltexture)
782 return;
783
784 if (invul_method == INVUL_CM && frame_fixedcolormap == INVERSECOLORMAP)
785 vbo = &sky_vbo[1];
786 else
787 vbo = &sky_vbo[0];
788
789
790 #if defined(USE_VERTEX_ARRAYS) || defined(USE_VBO)
791 // be sure the second ARB is not enabled
792 gld_EnableDetail(false);
793 #endif
794
795 glRotatef(-180.0f + sky->x_offset, 0.f, 1.f, 0.f);
796
797 rows = 4;
798 columns = 4 * gl_sky_detail;
799
800 vbosize = 2 * rows * (columns * 2 + 2) + columns * 2;
801
802 if (sky->y_offset != y_offset_saved ||
803 sky->wall.gltexture->index != sky->index)
804 {
805 y_offset_saved = sky->y_offset;
806
807 if (sky->wall.gltexture->index != sky->index)
808 {
809 sky->index = sky->wall.gltexture->index;
810 gld_GetSkyCapColors();
811 }
812
813 gld_BuildSky(rows, columns, sky, 0);
814 gld_BuildSky(rows, columns, sky, INVERSECOLORMAP);
815
816 #ifdef USE_VBO
817 if (gl_ext_arb_vertex_buffer_object)
818 {
819 if (vbo->id)
820 {
821 // delete VBO when already exists
822 GLEXT_glDeleteBuffersARB(1, &vbo->id);
823 }
824 // generate a new VBO and get the associated ID
825 GLEXT_glGenBuffersARB(1, &vbo->id);
826 // bind VBO in order to use
827 GLEXT_glBindBufferARB(GL_ARRAY_BUFFER, vbo->id);
828 // upload data to VBO
829 GLEXT_glBufferDataARB(GL_ARRAY_BUFFER,
830 vbosize * sizeof(vbo->data[0]),
831 vbo->data, GL_STATIC_DRAW_ARB);
832 }
833 #endif
834 }
835
836 gld_BindTexture(SkyBox.wall.gltexture, 0);
837
838 #if defined(USE_VERTEX_ARRAYS) || defined(USE_VBO)
839 if (gl_ext_arb_vertex_buffer_object)
840 {
841 // bind VBO in order to use
842 GLEXT_glBindBufferARB(GL_ARRAY_BUFFER, vbo->id);
843 }
844
845 // activate and specify pointers to arrays
846 glVertexPointer(3, GL_FLOAT, sizeof(vbo->data[0]), sky_vbo_x);
847 glTexCoordPointer(2, GL_FLOAT, sizeof(vbo->data[0]), sky_vbo_u);
848 glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vbo->data[0]), sky_vbo_r);
849
850 // activate vertex array, texture coord array and color arrays
851 glEnableClientState(GL_VERTEX_ARRAY);
852 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
853 glEnableClientState(GL_COLOR_ARRAY);
854 #endif
855
856 if (!gl_stretchsky)
857 {
858 int texh = sky->wall.gltexture->buffer_height;
859
860 if (texh <= 180)
861 {
862 glScalef(1.0f, (float)texh / 230.0f, 1.0f);
863 }
864 else
865 {
866 if (texh > 190)
867 glScalef(1.0f, 230.0f / 240.0f, 1.0f);
868 }
869 }
870
871 for(j = (HaveMouseLook() || !gl_stretchsky ? 0 : 1); j < 2; j++)
872 {
873 gld_EnableTexture2D(GL_TEXTURE0_ARB, j != 0);
874
875 for(i = 0; i < vbo->loopcount; i++)
876 {
877 GLSkyLoopDef *loop = &vbo->loops[i];
878
879 if (j == 0 ? loop->use_texture : !loop->use_texture)
880 continue;
881
882 #if defined(USE_VERTEX_ARRAYS) || defined(USE_VBO)
883 glDrawArrays(loop->mode, loop->vertexindex, loop->vertexcount);
884 #else
885 {
886 int k;
887 glBegin(loop->mode);
888 for (k = loop->vertexindex; k < (loop->vertexindex + loop->vertexcount); k++)
889 {
890 vbo_vertex_t *v = &vbo->data[k];
891 if (loop->use_texture)
892 {
893 glTexCoord2fv((GLfloat*)&v->u);
894 }
895 glColor4ubv((GLubyte*)&v->r);
896 glVertex3fv((GLfloat*)&v->x);
897 }
898 glEnd();
899 }
900 #endif
901 }
902 }
903
904 glScalef(1.0f, 1.0f, 1.0f);
905
906 // current color is undefined after glDrawArrays
907 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
908
909 #if defined(USE_VERTEX_ARRAYS) || defined(USE_VBO)
910 if (gl_ext_arb_vertex_buffer_object)
911 {
912 // bind with 0, so, switch back to normal pointer operation
913 GLEXT_glBindBufferARB(GL_ARRAY_BUFFER, 0);
914 }
915 // deactivate color array
916 glDisableClientState(GL_COLOR_ARRAY);
917 #endif
918 }
919
gld_DrawDomeSkyBox(void)920 void gld_DrawDomeSkyBox(void)
921 {
922 if (SkyBox.wall.gltexture)
923 {
924 GLint shading_mode = GL_FLAT;
925
926 gld_DrawFakeSkyStrips();
927
928 glGetIntegerv(GL_SHADE_MODEL, &shading_mode);
929 glShadeModel(GL_SMOOTH);
930
931 glDepthMask(false);
932
933 glDisable(GL_DEPTH_TEST);
934 glDisable(GL_ALPHA_TEST);
935 SetTextureMode(TM_OPAQUE);
936
937 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
938
939 glPushMatrix();
940 glMatrixMode(GL_MODELVIEW);
941 glLoadIdentity();
942
943 glRotatef(roll, 0.0f, 0.0f, 1.0f);
944 glRotatef(pitch, 1.0f, 0.0f, 0.0f);
945 glRotatef(yaw, 0.0f, 1.0f, 0.0f);
946 glScalef(-2.0f, 2.0f, 2.0f);
947 glTranslatef(0.f, -1250.0f / MAP_COEFF, 0.f);
948
949 RenderDome(&SkyBox);
950
951 glPopMatrix();
952
953 glEnable(GL_ALPHA_TEST);
954 glEnable(GL_DEPTH_TEST);
955 glDepthMask(true);
956
957 SetTextureMode(TM_MODULATE);
958
959 glShadeModel(shading_mode);
960 }
961 }
962
R_BoxSkyboxNumForName(const char * name)963 int R_BoxSkyboxNumForName(const char *name)
964 {
965 int i;
966
967 for (i = 0; i < BoxSkyboxCount; i++)
968 {
969 if (!strcasecmp(BoxSkybox[i].name, name))
970 {
971 return i;
972 }
973 }
974
975 return -1;
976 }
977
R_SetBoxSkybox(int texture)978 void R_SetBoxSkybox(int texture)
979 {
980 int i;
981
982 BoxSkybox_default = NULL;
983
984 for (i = 0; i < BoxSkyboxCount; i++)
985 {
986 if (R_CheckTextureNumForName(BoxSkybox[i].name) == texture)
987 {
988 BoxSkybox_default = &BoxSkybox[i];
989 return;
990 }
991 }
992 }
993
R_GetBoxSkybox(int index)994 box_skybox_t* R_GetBoxSkybox(int index)
995 {
996 if (index >= 0 && index < BoxSkyboxCount)
997 return &BoxSkybox[index];
998 else
999 return NULL;
1000 }
1001
gld_ParseSkybox(void)1002 void gld_ParseSkybox(void)
1003 {
1004 if (SC_GetString())
1005 {
1006 box_skybox_t sb;
1007 memset(&sb, 0, sizeof(sb));
1008
1009 strncpy(sb.name, sc_String, 8);
1010 sb.name[8] = 0;
1011 M_Strupr(sb.name);
1012
1013 while (SC_Check())
1014 {
1015 SC_GetString();
1016 if (SC_Compare("fliptop"))
1017 {
1018 sb.fliptop = true;
1019 }
1020 }
1021
1022 if (SC_GetString() && SC_Compare("{"))
1023 {
1024 int facecount = 0;
1025
1026 while (SC_GetString() && !SC_Compare("}"))
1027 {
1028 if (facecount < 6)
1029 {
1030 strcpy(sb.faces[facecount], sc_String);
1031 }
1032 facecount++;
1033 }
1034
1035 if (SC_Compare("}") && (facecount == 3 || facecount == 6))
1036 {
1037 int i;
1038 int ok = true;
1039
1040 for (i = 0; i < facecount; i++)
1041 {
1042 if (R_CheckTextureNumForName(sb.faces[i]) == -1)
1043 {
1044 ok = false;
1045 break;
1046 }
1047 }
1048
1049 if (ok)
1050 {
1051 BoxSkyboxCount++;
1052 BoxSkybox = realloc(BoxSkybox, BoxSkyboxCount * sizeof(BoxSkybox[0]));
1053 memcpy(&BoxSkybox[BoxSkyboxCount - 1], &sb, sizeof(sb));
1054 }
1055 }
1056 }
1057 }
1058
1059 R_SetBoxSkybox(skytexture);
1060 }
1061
gld_BindFace(box_skybox_t * sb,int index)1062 int gld_BindFace(box_skybox_t *sb, int index)
1063 {
1064 int lump;
1065 GLTexture *gltexture;
1066 char *name = sb->faces[index];
1067
1068 #if 0
1069 lump = W_CheckNumForName(name);
1070 if (lump != -1)
1071 {
1072 gltexture = gld_RegisterPatch(lump, CR_DEFAULT);
1073 gltexture->wrap_mode = GLEXT_CLAMP_TO_EDGE;
1074 gld_BindPatch(gltexture, CR_DEFAULT);
1075 return true;
1076 }
1077
1078 //lump = R_FlatNumForName(name);
1079 lump = (W_CheckNumForName)(name, ns_flats);
1080 if (lump != -1)
1081 {
1082 lump -= firstflat;
1083 gltexture = gld_RegisterFlat(lump, true);
1084 gltexture->wrap_mode = GLEXT_CLAMP_TO_EDGE;
1085 gld_BindFlat(gltexture);
1086 return true;
1087 }
1088 #endif
1089
1090 lump = R_CheckTextureNumForName(name);
1091 if (lump != -1)
1092 {
1093 gltexture = gld_RegisterTexture(lump, false, false);
1094 gld_BindTexture(gltexture, GLTEXTURE_CLAMPXY);
1095 return true;
1096 }
1097
1098 return false;
1099 }
1100
gld_DrawBoxSkyBox(void)1101 int gld_DrawBoxSkyBox(void)
1102 {
1103 int faces;
1104 box_skybox_t *sb;
1105
1106 if (BoxSkyboxCount == 0)
1107 return false;
1108
1109 if (SkyBox.side)
1110 {
1111 sb = R_GetBoxSkybox(SkyBox.side->skybox_index);
1112 }
1113 else
1114 {
1115 sb = BoxSkybox_default;
1116 }
1117
1118 if (!sb)
1119 {
1120 return false;
1121 }
1122
1123 gld_DrawFakeSkyStrips();
1124
1125 glDepthMask(false);
1126
1127 glDisable(GL_DEPTH_TEST);
1128 glDisable(GL_ALPHA_TEST);
1129
1130 SetTextureMode(TM_OPAQUE);
1131
1132 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1133
1134 glMatrixMode(GL_MODELVIEW);
1135 glPushMatrix();
1136
1137 glLoadIdentity();
1138
1139 glRotatef(roll, 0.0f, 0.0f, 1.0f);
1140 glRotatef(pitch, 1.0f, 0.0f, 0.0f);
1141 glRotatef(yaw, 0.0f, 1.0f, 0.0f);
1142 glScalef(-2.0f, 2.0f, 2.0f);
1143
1144 if (SkyBox.side)
1145 {
1146 float xoffset = (float)SkyBox.side->textureoffset * 180.0f / (float)ANG180;
1147 glRotatef(-180.0f + xoffset, 0.0f, 1.0f, 0.0f);
1148 }
1149
1150 if (sb->faces[5][0])
1151 {
1152 faces = 4;
1153
1154 // north
1155 gld_BindFace(sb, 0);
1156
1157 glBegin(GL_TRIANGLE_FAN);
1158 glTexCoord2f(0.0f, 0.0f);
1159 glVertex3f(+MAXCOORD, MAXCOORD, -MAXCOORD);
1160 glTexCoord2f(1.0f, 0.0f);
1161 glVertex3f(-MAXCOORD, +MAXCOORD, -MAXCOORD);
1162 glTexCoord2f(1.0f, 1.0f);
1163 glVertex3f(-MAXCOORD, -MAXCOORD, -MAXCOORD);
1164 glTexCoord2f(0.0f, 1.0f);
1165 glVertex3f(+MAXCOORD, -MAXCOORD, -MAXCOORD);
1166 glEnd();
1167
1168 // east
1169 gld_BindFace(sb, 1);
1170
1171 glBegin(GL_TRIANGLE_FAN);
1172 glTexCoord2f(0.0f, 0.0f);
1173 glVertex3f(-MAXCOORD, +MAXCOORD, -MAXCOORD);
1174 glTexCoord2f(1.0f, 0.0f);
1175 glVertex3f(-MAXCOORD, +MAXCOORD, +MAXCOORD);
1176 glTexCoord2f(1.0f, 1.0f);
1177 glVertex3f(-MAXCOORD, -MAXCOORD, +MAXCOORD);
1178 glTexCoord2f(0.0f, 1.0f);
1179 glVertex3f(-MAXCOORD, -MAXCOORD, -MAXCOORD);
1180 glEnd();
1181
1182 // south
1183 gld_BindFace(sb, 2);
1184
1185 glBegin(GL_TRIANGLE_FAN);
1186 glTexCoord2f(0.0f, 0.0f);
1187 glVertex3f(-MAXCOORD, +MAXCOORD, +MAXCOORD);
1188 glTexCoord2f(1.0f, 0.0f);
1189 glVertex3f(+MAXCOORD, +MAXCOORD, +MAXCOORD);
1190 glTexCoord2f(1.0f, 1.0f);
1191 glVertex3f(+MAXCOORD, -MAXCOORD, +MAXCOORD);
1192 glTexCoord2f(0.0f, 1.0f);
1193 glVertex3f(-MAXCOORD, -MAXCOORD, +MAXCOORD);
1194 glEnd();
1195
1196 // west
1197 gld_BindFace(sb, 3);
1198
1199 glBegin(GL_TRIANGLE_FAN);
1200 glTexCoord2f(0.0f, 0.0f);
1201 glVertex3f(+MAXCOORD, +MAXCOORD, +MAXCOORD);
1202 glTexCoord2f(1.0f, 0.0f);
1203 glVertex3f(+MAXCOORD, +MAXCOORD, -MAXCOORD);
1204 glTexCoord2f(1.0f, 1.0f);
1205 glVertex3f(+MAXCOORD, -MAXCOORD, -MAXCOORD);
1206 glTexCoord2f(0.0f, 1.0f);
1207 glVertex3f(+MAXCOORD, -MAXCOORD, +MAXCOORD);
1208 glEnd();
1209 }
1210 else
1211 {
1212 faces = 1;
1213
1214 // all 4 sides
1215 gld_BindFace(sb, 0);
1216
1217 glBegin(GL_TRIANGLE_FAN);
1218 glTexCoord2f(0.0f, 0.0f);
1219 glVertex3f(+MAXCOORD, +MAXCOORD, -MAXCOORD);
1220 glTexCoord2f(.25f, 0);
1221 glVertex3f(-MAXCOORD, +MAXCOORD, -MAXCOORD);
1222 glTexCoord2f(.25f, 1);
1223 glVertex3f(-MAXCOORD, -MAXCOORD, -MAXCOORD);
1224 glTexCoord2f(0.0f, 1.0f);
1225 glVertex3f(+MAXCOORD, -MAXCOORD, -MAXCOORD);
1226 glEnd();
1227
1228 // east
1229 glBegin(GL_TRIANGLE_FAN);
1230 glTexCoord2f(.25f, 0);
1231 glVertex3f(-MAXCOORD, +MAXCOORD, -MAXCOORD);
1232 glTexCoord2f(.5f, 0);
1233 glVertex3f(-MAXCOORD, +MAXCOORD, +MAXCOORD);
1234 glTexCoord2f(.5f, 1);
1235 glVertex3f(-MAXCOORD, -MAXCOORD, +MAXCOORD);
1236 glTexCoord2f(.25f, 1);
1237 glVertex3f(-MAXCOORD, -MAXCOORD, -MAXCOORD);
1238 glEnd();
1239
1240 // south
1241 glBegin(GL_TRIANGLE_FAN);
1242 glTexCoord2f(.5f, 0);
1243 glVertex3f(-MAXCOORD, +MAXCOORD, +MAXCOORD);
1244 glTexCoord2f(.75f, 0);
1245 glVertex3f(+MAXCOORD, +MAXCOORD, +MAXCOORD);
1246 glTexCoord2f(.75f, 1);
1247 glVertex3f(+MAXCOORD, -MAXCOORD, +MAXCOORD);
1248 glTexCoord2f(.5f, 1);
1249 glVertex3f(-MAXCOORD, -MAXCOORD, +MAXCOORD);
1250 glEnd();
1251
1252 // west
1253 glBegin(GL_TRIANGLE_FAN);
1254 glTexCoord2f(.75f, 0);
1255 glVertex3f(+MAXCOORD, +MAXCOORD, +MAXCOORD);
1256 glTexCoord2f(1.0f, 0.0f);
1257 glVertex3f(+MAXCOORD, +MAXCOORD, -MAXCOORD);
1258 glTexCoord2f(1.0f, 1.0f);
1259 glVertex3f(+MAXCOORD, -MAXCOORD, -MAXCOORD);
1260 glTexCoord2f(.75f, 1);
1261 glVertex3f(+MAXCOORD, -MAXCOORD, +MAXCOORD);
1262 glEnd();
1263 }
1264
1265 // top
1266 gld_BindFace(sb, faces);
1267 glBegin(GL_TRIANGLE_FAN);
1268 if (!sb->fliptop)
1269 {
1270 glTexCoord2f(0.0f, 0.0f);
1271 glVertex3f(+MAXCOORD, +MAXCOORD, -MAXCOORD);
1272 glTexCoord2f(1.0f, 0.0f);
1273 glVertex3f(-MAXCOORD, +MAXCOORD, -MAXCOORD);
1274 glTexCoord2f(1.0f, 1.0f);
1275 glVertex3f(-MAXCOORD, +MAXCOORD, +MAXCOORD);
1276 glTexCoord2f(0.0f, 1.0f);
1277 glVertex3f(+MAXCOORD, +MAXCOORD, +MAXCOORD);
1278 }
1279 else
1280 {
1281 glTexCoord2f(0.0f, 0.0f);
1282 glVertex3f(+MAXCOORD, +MAXCOORD, +MAXCOORD);
1283 glTexCoord2f(1.0f, 0.0f);
1284 glVertex3f(-MAXCOORD, +MAXCOORD, +MAXCOORD);
1285 glTexCoord2f(1.0f, 1.0f);
1286 glVertex3f(-MAXCOORD, +MAXCOORD, -MAXCOORD);
1287 glTexCoord2f(0.0f, 1.0f);
1288 glVertex3f(+MAXCOORD, +MAXCOORD, -MAXCOORD);
1289 }
1290 glEnd();
1291
1292 // bottom
1293 gld_BindFace(sb, faces + 1);
1294
1295 glBegin(GL_TRIANGLE_FAN);
1296 glTexCoord2f(0.0f, 0.0f);
1297 glVertex3f(+MAXCOORD, -MAXCOORD, -MAXCOORD);
1298 glTexCoord2f(1.0f, 0.0f);
1299 glVertex3f(-MAXCOORD, -MAXCOORD, -MAXCOORD);
1300 glTexCoord2f(1.0f, 1.0f);
1301 glVertex3f(-MAXCOORD, -MAXCOORD, +MAXCOORD);
1302 glTexCoord2f(0.0f, 1.0f);
1303 glVertex3f(+MAXCOORD, -MAXCOORD, +MAXCOORD);
1304 glEnd();
1305
1306 glPopMatrix();
1307
1308 glEnable(GL_ALPHA_TEST);
1309 glEnable(GL_DEPTH_TEST);
1310 glDepthMask(true);
1311
1312 SetTextureMode(TM_MODULATE);
1313
1314 return true;
1315 }
1316