2
Copyright (C) 1996-1997 Id Software, Inc.
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
as published by the Free Software Foundation; either version 2
7
of the License, or (at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
See the GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program; if not, write to the Free Software
17
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
// gl_warp.c -- sky and water polygons
25
extern model_t *loadmodel;
29
float speedscale; // for top sky and bottom sky
34
static msurface_t *warpface;
36
static void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs)
41
mins[0] = mins[1] = mins[2] = 9999;
42
maxs[0] = maxs[1] = maxs[2] = -9999;
44
for (i=0 ; i<numverts ; i++)
45
for (j=0 ; j<3 ; j++, v++)
54
static void SubdividePolygon (int numverts, float *verts)
60
vec3_t front[64], back[64];
68
Sys_Error ("numverts = %i", numverts);
70
BoundPoly (numverts, verts, mins, maxs);
74
m = (mins[i] + maxs[i]) * 0.5;
75
m = gl_subdivide_size.value * floor (m/gl_subdivide_size.value + 0.5);
83
for (j=0 ; j<numverts ; j++, v+= 3)
89
VectorCopy (verts, v);
93
for (j=0 ; j<numverts ; j++, v+= 3)
97
VectorCopy (v, front[f]);
102
VectorCopy (v, back[b]);
105
if (dist[j] == 0 || dist[j+1] == 0)
107
if ( (dist[j] > 0) != (dist[j+1] > 0) )
110
frac = dist[j] / (dist[j] - dist[j+1]);
111
for (k=0 ; k<3 ; k++)
112
front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]);
118
SubdividePolygon (f, front[0]);
119
SubdividePolygon (b, back[0]);
123
poly = Hunk_Alloc (sizeof(glpoly_t) + (numverts-4) * VERTEXSIZE*sizeof(float));
124
poly->next = warpface->polys;
125
warpface->polys = poly;
126
poly->numverts = numverts;
127
for (i=0 ; i<numverts ; i++, verts+= 3)
129
VectorCopy (verts, poly->verts[i]);
130
s = DotProduct (verts, warpface->texinfo->vecs[0]);
131
t = DotProduct (verts, warpface->texinfo->vecs[1]);
132
poly->verts[i][3] = s;
133
poly->verts[i][4] = t;
141
Breaks a polygon up along axial 64 unit
142
boundaries so that turbulent and sky warps
143
can be done reasonably.
146
void GL_SubdivideSurface (msurface_t *fa)
157
// convert edges back to a normal polygon
160
for (i=0 ; i<fa->numedges ; i++)
162
lindex = loadmodel->surfedges[fa->firstedge + i];
165
vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position;
167
vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position;
168
VectorCopy (vec, verts[numverts]);
172
SubdividePolygon (numverts, verts[0]);*/
177
GL_BuildSkySurfacePoly
179
Just build the gl polys, don't subdivide
182
void GL_BuildSkySurfacePolys (msurface_t *fa)
193
// convert edges back to a normal polygon
196
for (i=0 ; i<fa->numedges ; i++)
198
lindex = loadmodel->surfedges[fa->firstedge + i];
201
vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position;
203
vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position;
204
VectorCopy (vec, verts[numverts]);
208
poly = Hunk_Alloc (sizeof(glpoly_t) + (numverts-4) * VERTEXSIZE*sizeof(float));
211
poly->numverts = numverts;
213
for (i=0 ; i<numverts ; i++, vert+= 3)
214
VectorCopy (vert, poly->verts[i]);*/
217
//=========================================================
220
// speed up sin calculations - Ed
223
#include "gl_warp_sin.h"
225
#define TURBSCALE (256.0 / (2 * M_PI))
228
#define TURBWARP_OLD(s, t) \
229
((s + turbsin[(int) ((t * 0.125 + r_refdef2.time) * TURBSCALE) & 255]) * 1 / 64.0f)
231
#define TURBWARP_NEW(s, t) \
232
((s + turbsin[(int) ((t * 2) + r_refdef2.time * TURBSCALE) & 255]) * 1 / 64.0f)
239
Does a water warp on the pre-fragmented glpoly_t chain
242
void EmitWaterPolys (msurface_t *fa)
249
for (p=fa->polys ; p ; p=p->next)
251
glBegin (GL_POLYGON);
252
for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
254
glTexCoord2f (TURBWARP_NEW(v[3], v[4]), TURBWARP_NEW(v[4], v[3]));
266
static void EmitSkyPolys (msurface_t *fa)
275
for (p=fa->polys ; p ; p=p->next)
277
glBegin (GL_POLYGON);
278
for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
280
VectorSubtract (v, r_origin, dir);
281
dir[2] *= 3; // flatten the sphere
283
length = VectorLength (dir);
284
length = 6*63/length;
289
s = (speedscale + dir[0]) * (1.0/128);
290
t = (speedscale + dir[1]) * (1.0/128);
304
void EmitFlatPoly (msurface_t *fa)
310
for (p=fa->polys ; p ; p=p->next)
312
glBegin (GL_POLYGON);
313
for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
323
Does a sky warp on the pre-fragmented glpoly_t chain
324
This will be called for brushmodels, the world
325
will have them chained together.
328
void EmitBothSkyLayers (msurface_t *fa)
330
/* GL_DisableMultitexture();
332
if (r_fastsky.value) {
333
glDisable (GL_TEXTURE_2D);
334
glColor3ubv ((byte *)&d_8to24table[(byte)r_skycolor.value]);
338
glEnable (GL_TEXTURE_2D);
343
GL_Bind (solidskytexture);
344
speedscale = r_refdef2.time*8;
345
speedscale -= (int)speedscale & ~127;
350
GL_Bind (alphaskytexture);
351
speedscale = r_refdef2.time*16;
352
speedscale -= (int)speedscale & ~127;
356
glDisable (GL_BLEND);*/
359
//===============================================================
365
A sky texture is 256*128, with the right side being a masked overlay
368
void R_InitSky (texture_t *mt)
372
unsigned trans[128*128];
377
src = (byte *)mt + mt->offsets[0];
379
// make an average value for the back to avoid
380
// a fringe on the top level
383
for (i=0 ; i<128 ; i++)
384
for (j=0 ; j<128 ; j++)
386
p = src[i*256 + j + 128];
387
rgba = &d_8to24table[p];
388
trans[(i*128) + j] = *rgba;
389
r += ((byte *)rgba)[0];
390
g += ((byte *)rgba)[1];
391
b += ((byte *)rgba)[2];
394
((byte *)&transpix)[0] = r/(128*128);
395
((byte *)&transpix)[1] = g/(128*128);
396
((byte *)&transpix)[2] = b/(128*128);
397
((byte *)&transpix)[3] = 0;
400
if (!solidskytexture)
401
solidskytexture = texture_extension_number++;
402
GL_Bind (solidskytexture );
403
glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
404
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
405
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
408
for (i=0 ; i<128 ; i++)
409
for (j=0 ; j<128 ; j++)
413
trans[(i*128) + j] = transpix;
415
trans[(i*128) + j] = d_8to24table[p];
418
if (!alphaskytexture)
419
alphaskytexture = texture_extension_number++;
420
GL_Bind(alphaskytexture);
421
glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
422
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
423
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);*/
428
=================================================================
430
Quake 2 environment sky
432
=================================================================
441
static char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
442
void R_SetSky (char *name)
447
char pathname[MAX_OSPATH];
451
r_skyboxloaded = false;
455
for (i=0 ; i<6 ; i++)
457
Q_snprintfz (pathname, sizeof(pathname), "env/%s%s.tga", name, suf[i]);
458
LoadTGA (pathname, &pic, &width, &height);
461
Com_Printf ("Couldn't load %s\n", pathname);
462
r_skyboxloaded = false;
465
if (width > 512 || height > 512) // just a sanity check
467
Com_Printf ("Bad image dimensions in %s\n", pathname);
468
Q_free (pic); // Q_malloc'ed by LoadTGA
469
r_skyboxloaded = false;
473
// FIXME, scale image down if larger than gl_max_size
474
// We're gonna run into trouble on a Voodoo
476
GL_Bind (skyboxtextures + i);
477
glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pic);
478
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
479
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
481
Q_free (pic); // Q_malloc'ed by LoadTGA
484
r_skyboxloaded = true;*/
488
static vec3_t skyclip[6] = {
497
#define skybox_range 2400.0
499
// 1 = s, 2 = t, 3 = 2048
500
static int st_to_vec[6][3] =
508
{-2,-1,3}, // 0 degrees yaw, look straight up
509
{2,-1,-3} // look straight down
515
// s = [0]/[2], t = [1]/[2]
516
static int vec_to_st[6][3] =
531
static float skymins[2][6], skymaxs[2][6];
533
static void DrawSkyPolygon (int nump, vec3_t vecs)
541
// decide which face it maps to
543
for (i=0, vp=vecs ; i<nump ; i++, vp+=3)
545
VectorAdd (vp, v, v);
550
if (av[0] > av[1] && av[0] > av[2])
557
else if (av[1] > av[2] && av[1] > av[0])
572
// project new texture coords
573
for (i=0 ; i<nump ; i++, vecs+=3)
575
j = vec_to_st[axis][2];
581
j = vec_to_st[axis][0];
583
s = -vecs[-j -1] / dv;
586
j = vec_to_st[axis][1];
588
t = -vecs[-j -1] / dv;
592
if (s < skymins[0][axis])
593
skymins[0][axis] = s;
594
if (t < skymins[1][axis])
595
skymins[1][axis] = t;
596
if (s > skymaxs[0][axis])
597
skymaxs[0][axis] = s;
598
if (t > skymaxs[1][axis])
599
skymaxs[1][axis] = t;
603
#define MAX_CLIP_VERTS 64
604
static void ClipSkyPolygon (int nump, vec3_t vecs, int stage)
610
float dists[MAX_CLIP_VERTS];
611
int sides[MAX_CLIP_VERTS];
612
vec3_t newv[2][MAX_CLIP_VERTS];
616
if (nump > MAX_CLIP_VERTS-2)
617
Sys_Error ("ClipSkyPolygon: MAX_CLIP_VERTS");
619
{ // fully clipped, so draw it
620
DrawSkyPolygon (nump, vecs);
624
front = back = false;
625
norm = skyclip[stage];
626
for (i=0, v = vecs ; i<nump ; i++, v+=3)
628
d = DotProduct (v, norm);
632
sides[i] = SIDE_FRONT;
634
else if (d < ON_EPSILON)
637
sides[i] = SIDE_BACK;
646
ClipSkyPolygon (nump, vecs, stage+1);
653
VectorCopy (vecs, (vecs+(i*3)) );
654
newc[0] = newc[1] = 0;
656
for (i=0, v = vecs ; i<nump ; i++, v+=3)
661
VectorCopy (v, newv[0][newc[0]]);
665
VectorCopy (v, newv[1][newc[1]]);
669
VectorCopy (v, newv[0][newc[0]]);
671
VectorCopy (v, newv[1][newc[1]]);
676
if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
679
d = dists[i] / (dists[i] - dists[i+1]);
680
for (j=0 ; j<3 ; j++)
682
e = v[j] + d*(v[j+3] - v[j]);
683
newv[0][newc[0]][j] = e;
684
newv[1][newc[1]][j] = e;
691
ClipSkyPolygon (newc[0], newv[0][0], stage+1);
692
ClipSkyPolygon (newc[1], newv[1][0], stage+1);*/
700
void R_AddSkyBoxSurface (msurface_t *fa)
703
vec3_t verts[MAX_CLIP_VERTS];
706
// calculate vertex values for sky box
707
for (p=fa->polys ; p ; p=p->next)
709
for (i=0 ; i<p->numverts ; i++)
711
VectorSubtract (p->verts[i], r_origin, verts[i]);
713
ClipSkyPolygon (p->numverts, verts[0], 0);
723
void R_ClearSky (void)
727
for (i=0 ; i<6 ; i++)
729
skymins[0][i] = skymins[1][i] = 9999;
730
skymaxs[0][i] = skymaxs[1][i] = -9999;
734
static void MakeSkyVec (float s, float t, int axis)
739
b[0] = s*skybox_range;
740
b[1] = t*skybox_range;
743
for (j=0 ; j<3 ; j++)
745
k = st_to_vec[axis][j];
759
else if (s > 511.0/512)
763
else if (t > 511.0/512)
776
static int skytexorder[6] = {0,2,1,3,4,5};
777
static void R_DrawSkyBox (void)
781
for (i = 0; i < 6; i++)
783
if ((skymins[0][i] >= skymaxs[0][i] || skymins[1][i] >= skymaxs[1][i]))
786
GL_Bind (skyboxtextures + skytexorder[i]);
789
MakeSkyVec (skymins[0][i], skymins[1][i], i);
790
MakeSkyVec (skymins[0][i], skymaxs[1][i], i);
791
MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);
792
MakeSkyVec (skymaxs[0][i], skymins[1][i], i);
797
static void EmitSkyVert (vec3_t v)
803
VectorSubtract (v, r_origin, dir);
804
dir[2] *= 3; // flatten the sphere
806
length = VectorLength (dir);
807
length = 6*63/length;
812
s = (speedscale + dir[0]) * (1.0/128);
813
t = (speedscale + dir[1]) * (1.0/128);
819
// s and t range from -1 to 1
820
static void MakeSkyVec2 (float s, float t, int axis, vec3_t v)
825
b[0] = s*skybox_range;
826
b[1] = t*skybox_range;
829
for (j=0 ; j<3 ; j++)
831
k = st_to_vec[axis][j];
841
#define SUBDIVISIONS 10
843
static void DrawSkyFace (int axis)
849
float fstep = 2.0 / SUBDIVISIONS;
853
for (i = 0; i < SUBDIVISIONS; i++)
855
s = (float)(i*2 - SUBDIVISIONS) / SUBDIVISIONS;
857
if (s + fstep < skymins[0][axis] || s > skymaxs[0][axis])
860
for (j = 0; j < SUBDIVISIONS; j++) {
861
t = (float)(j*2 - SUBDIVISIONS) / SUBDIVISIONS;
863
if (t + fstep < skymins[1][axis] || t > skymaxs[1][axis])
866
MakeSkyVec2 (s, t, axis, vecs[0]);
867
MakeSkyVec2 (s, t + fstep, axis, vecs[1]);
868
MakeSkyVec2 (s + fstep, t + fstep, axis, vecs[2]);
869
MakeSkyVec2 (s + fstep, t, axis, vecs[3]);
871
EmitSkyVert (vecs[0]);
872
EmitSkyVert (vecs[1]);
873
EmitSkyVert (vecs[2]);
874
EmitSkyVert (vecs[3]);
882
static void R_DrawSkyDome (void)
886
GL_DisableMultitexture();
887
GL_Bind (solidskytexture);
889
speedscale = r_refdef2.time*8;
890
speedscale -= (int)speedscale & ~127;
892
for (i = 0; i < 6; i++) {
893
if ((skymins[0][i] >= skymaxs[0][i] || skymins[1][i] >= skymaxs[1][i]))
899
GL_Bind (alphaskytexture);
901
speedscale = r_refdef2.time*16;
902
speedscale -= (int)speedscale & ~127;
904
for (i = 0; i < 6; i++) {
905
if ((skymins[0][i] >= skymaxs[0][i] || skymins[1][i] >= skymaxs[1][i]))
915
Draw either the classic cloudy quake sky or a skybox
918
void R_DrawSky (void)
922
extern msurface_t *skychain;
924
GL_DisableMultitexture ();
926
if (r_fastsky.value) {
927
glDisable (GL_TEXTURE_2D);
928
glColor3ubv ((byte *)&d_8to24table[(byte)r_skycolor.value]);
930
for (fa = skychain; fa; fa = fa->texturechain)
934
glEnable (GL_TEXTURE_2D);
939
if (r_viewleaf->contents == CONTENTS_SOLID) {
940
// always draw if we're in a solid leaf (probably outside the level)
941
// FIXME: we don't really want to add all six planes every time!
942
// FIXME: also handle r_fastsky case
944
for (i = 0; i < 6; i++) {
945
skymins[0][i] = skymins[1][i] = -1;
946
skymaxs[0][i] = skymaxs[1][i] = 1;
952
return; // no sky at all
954
// figure out how much of the sky box we need to draw
955
for (fa = skychain; fa; fa = fa->texturechain)
956
R_AddSkyBoxSurface (fa);
961
// turn off Z tests & writes to avoid problems on large maps
962
glDisable (GL_DEPTH_TEST);
964
// draw a skybox or classic quake clouds
970
glEnable (GL_DEPTH_TEST);
972
// draw the sky polys into the Z buffer
973
// don't need depth test yet
975
glDisable(GL_TEXTURE_2D);
976
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
979
glBlendFunc(GL_ZERO, GL_ONE);
981
for (fa = skychain; fa; fa = fa->texturechain)
984
glEnable (GL_TEXTURE_2D);
985
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
987
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
995
This works better (with gl_ztrick 0) on aerowalk where otherwise the sky
996
shows in bright pixels through holes in walls, of which on aerowalk there
998
But problems arise on large maps like q1dm17 where the sky tends
999
to hide parts of the level.
1000
We could just put the far clip plane further of course...
1002
void R_DrawSky (void)
1006
extern cvar_t gl_ztrick;
1007
extern int gl_ztrickframe;
1008
extern msurface_t *skychain;
1010
GL_DisableMultitexture ();
1012
if (r_fastsky.value) {
1013
glDisable (GL_TEXTURE_2D);
1014
glColor3ubv ((byte *)&d_8to24table[(byte)r_skycolor.value]);
1016
for (fa = skychain; fa; fa = fa->texturechain)
1020
glEnable (GL_TEXTURE_2D);
1021
glColor3f (1, 1, 1);
1025
if (r_viewleaf->contents == CONTENTS_SOLID) {
1026
// always draw if we're in a solid leaf (probably outside the level)
1027
// FIXME: we don't really want to add all six planes every time!
1029
for (i = 0; i < 6; i++) {
1030
skymins[0][i] = skymins[1][i] = -1;
1031
skymaxs[0][i] = skymaxs[1][i] = 1;
1037
return; // no sky at all
1039
// figure out how much of the sky box we need to draw
1040
for (fa = skychain; fa; fa = fa->texturechain)
1041
R_AddSkyBoxSurface (fa);
1046
// draw the sky polys into the Z buffer
1048
glDisable(GL_TEXTURE_2D);
1049
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1052
glBlendFunc(GL_ZERO, GL_ONE);
1054
for (fa = skychain; fa; fa = fa->texturechain)
1057
glEnable (GL_TEXTURE_2D);
1058
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1059
glDisable(GL_BLEND);
1060
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1064
// only write portions of the sky behind the Z polygons we rendered
1065
if (gl_ztrick.value && !gl_ztrickframe)
1066
glDepthFunc (GL_LEQUAL);
1068
glDepthFunc (GL_GEQUAL);
1070
glDepthMask (GL_FALSE); // don't bother writing Z
1073
// draw a skybox or classic quake clouds
1080
// back to normal Z test
1081
if (gl_ztrick.value && !gl_ztrickframe)
1082
glDepthFunc (GL_GEQUAL);
1084
glDepthFunc (GL_LEQUAL);
1086
glDepthMask (GL_TRUE); // re-enable Z writes