merge in knghtbrd's work, minus his over-bright stuff (it causes textures to

not be drawn when multitexture is not available (or at least I think that's
the condition)). More specificly, his altered blend states.
This commit is contained in:
Bill Currie 2000-06-17 10:39:28 +00:00
parent acb5f4b21a
commit 18a9900b21
10 changed files with 259 additions and 731 deletions

View file

@ -223,7 +223,7 @@ void EmitWaterPolys (msurface_t *fa)
float *v;
int i;
float s, t, os, ot;
vec3_t nv;
for (p=fa->polys ; p ; p=p->next)
{
@ -240,80 +240,20 @@ void EmitWaterPolys (msurface_t *fa)
t *= (1.0/64);
glTexCoord2f (s, t);
glVertex3fv (v);
VectorCopy (v, nv);
nv[2] += r_waterripple->value
* turbsin[(int)((v[3]*0.125+realtime) * TURBSCALE) & 255]
* turbsin[(int)((v[4]*0.125+realtime) * TURBSCALE) & 255]
* (1.0 / 64.0);
glVertex3fv (nv);
}
glEnd ();
}
}
/*
=============
EmitSkyPolys
=============
*/
void EmitSkyPolys (msurface_t *fa)
{
glpoly_t *p;
float *v;
int i;
float s, t;
vec3_t dir;
float length;
for (p=fa->polys ; p ; p=p->next)
{
glBegin (GL_POLYGON);
for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
{
VectorSubtract (v, r_origin, dir);
dir[2] *= 3; // flatten the sphere
length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2];
length = sqrt (length);
length = 6*63/length;
dir[0] *= length;
dir[1] *= length;
s = (speedscale + dir[0]) * (1.0/128);
t = (speedscale + dir[1]) * (1.0/128);
glTexCoord2f (s, t);
glVertex3fv (v);
}
glEnd ();
}
}
/*
===============
EmitBothSkyLayers
Does a sky warp on the pre-fragmented glpoly_t chain
This will be called for brushmodels, the world
will have them chained together.
===============
*/
void EmitBothSkyLayers (msurface_t *fa)
{
GL_DisableMultitexture();
GL_Bind (solidskytexture);
speedscale = realtime*8;
speedscale -= (int)speedscale & ~127 ;
EmitSkyPolys (fa);
GL_Bind (alphaskytexture);
speedscale = realtime*16;
speedscale -= (int)speedscale & ~127 ;
EmitSkyPolys (fa);
}
/*
=================================================================
@ -620,7 +560,7 @@ void R_LoadSkys (char * skyname)
skyloaded = true;
for (i=0 ; i<6 ; i++)
{
GL_Bind (SKY_TEX + i);
glBindTexture (GL_TEXTURE_2D, SKY_TEX + i);
snprintf (name, sizeof(name),"env/%s%s.tga", skyname, suf[i]);
COM_FOpenFile (name, &f);
if (!f)
@ -630,13 +570,10 @@ void R_LoadSkys (char * skyname)
continue;
}
LoadTGA (f);
// LoadPCX (f);
glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba);
// glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pcx_rgb);
free (targa_rgba);
// free (pcx_rgb);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -646,353 +583,188 @@ void R_LoadSkys (char * skyname)
skyname);
}
vec3_t skyclip[6] = {
{1,1,0},
{1,-1,0},
{0,-1,1},
{0,1,1},
{1,0,1},
{-1,0,1}
};
int c_sky;
// 1 = s, 2 = t, 3 = 2048
int st_to_vec[6][3] =
void
R_SkyBoxPolyVec(vec5_t v)
{
{3,-1,2},
{-3,1,2},
// avoid interpolation seams
// s = s * (254.0/256.0) + (1.0/256.0);
// t = t * (254.0/256.0) + (1.0/256.0);
glTexCoord2fv (v);
glVertex3f (r_refdef.vieworg[0] + v[2],
r_refdef.vieworg[1] + v[3],
r_refdef.vieworg[2] + v[4]);
}
{1,3,2},
{-1,-3,2},
#define ftc(x) (x * (254.0/256.0) + (1.0/256.0))
{-2,-1,3}, // 0 degrees yaw, look straight up
{2,-1,-3} // look straight down
// {-1,2,3},
// {1,2,-3}
vec5_t skyvec[6][4] = {
{
// right
{ftc(1), ftc(0), 1024, 1024, 1024},
{ftc(1), ftc(1), 1024, 1024, -1024},
{ftc(0), ftc(1), -1024, 1024, -1024},
{ftc(0), ftc(0), -1024, 1024, 1024}
},
{
// back
{ftc(1), ftc(0), -1024, 1024, 1024},
{ftc(1), ftc(1), -1024, 1024, -1024},
{ftc(0), ftc(1), -1024, -1024, -1024},
{ftc(0), ftc(0), -1024, -1024, 1024}
},
{
// left
{ftc(1), ftc(0), -1024, -1024, 1024},
{ftc(1), ftc(1), -1024, -1024, -1024},
{ftc(0), ftc(1), 1024, -1024, -1024},
{ftc(0), ftc(0), 1024, -1024, 1024}
},
{
// front
{ftc(1), ftc(0), 1024, -1024, 1024},
{ftc(1), ftc(1), 1024, -1024, -1024},
{ftc(0), ftc(1), 1024, 1024, -1024},
{ftc(0), ftc(0), 1024, 1024, 1024}
},
{
// up
{ftc(1), ftc(0), 1024, -1024, 1024},
{ftc(1), ftc(1), 1024, 1024, 1024},
{ftc(0), ftc(1), -1024, 1024, 1024},
{ftc(0), ftc(0), -1024, -1024, 1024}
},
{
// down
{ftc(1), ftc(0), 1024, 1024, -1024},
{ftc(1), ftc(1), 1024, -1024, -1024},
{ftc(0), ftc(1), -1024, -1024, -1024},
{ftc(0), ftc(0), -1024, 1024, -1024}
}
};
// s = [0]/[2], t = [1]/[2]
int vec_to_st[6][3] =
#undef ftc
void
R_DrawSkyBox (void)
{
{-2,3,1},
{2,3,-1},
int i, j;
{1,3,2},
{-1,3,-2},
GL_DisableMultitexture ();
glEnable (GL_DEPTH_TEST);
glDepthFunc (GL_ALWAYS);
// glDisable (GL_BLEND);
// glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDepthRange (gldepthmax, gldepthmax);
glColor3f (0.5, 0.5, 0.5);
{-2,-1,3},
{-2,1,-3}
// {-1,2,3},
// {1,2,-3}
};
float skymins[2][6], skymaxs[2][6];
void DrawSkyPolygon (int nump, vec3_t vecs)
{
int i,j;
vec3_t v, av;
float s, t, dv;
int axis;
float *vp;
c_sky++;
// decide which face it maps to
VectorCopy (vec3_origin, v);
for (i=0, vp=vecs ; i<nump ; i++, vp+=3)
for (i = 0; i < 6; i++)
{
VectorAdd (vp, v, v);
}
av[0] = fabs(v[0]);
av[1] = fabs(v[1]);
av[2] = fabs(v[2]);
if (av[0] > av[1] && av[0] > av[2])
{
if (v[0] < 0)
axis = 1;
else
axis = 0;
}
else if (av[1] > av[2] && av[1] > av[0])
{
if (v[1] < 0)
axis = 3;
else
axis = 2;
}
else
{
if (v[2] < 0)
axis = 5;
else
axis = 4;
glBindTexture(GL_TEXTURE_2D, SKY_TEX + i);
glBegin(GL_QUADS);
for (j = 0; j < 4; j++)
R_SkyBoxPolyVec(skyvec[i][j]);
glEnd();
}
// project new texture coords
for (i=0 ; i<nump ; i++, vecs+=3)
{
j = vec_to_st[axis][2];
if (j > 0)
dv = vecs[j - 1];
else
dv = -vecs[-j - 1];
j = vec_to_st[axis][0];
if (j < 0)
s = -vecs[-j -1] / dv;
else
s = vecs[j-1] / dv;
j = vec_to_st[axis][1];
if (j < 0)
t = -vecs[-j -1] / dv;
else
t = vecs[j-1] / dv;
if (s < skymins[0][axis])
skymins[0][axis] = s;
if (t < skymins[1][axis])
skymins[1][axis] = t;
if (s > skymaxs[0][axis])
skymaxs[0][axis] = s;
if (t > skymaxs[1][axis])
skymaxs[1][axis] = t;
}
}
#define MAX_CLIP_VERTS 64
void ClipSkyPolygon (int nump, vec3_t vecs, int stage)
{
float *norm;
float *v;
qboolean front, back;
float d, e;
float dists[MAX_CLIP_VERTS];
int sides[MAX_CLIP_VERTS];
vec3_t newv[2][MAX_CLIP_VERTS];
int newc[2];
int i, j;
if (nump > MAX_CLIP_VERTS-2)
Sys_Error ("ClipSkyPolygon: MAX_CLIP_VERTS");
if (stage == 6)
{ // fully clipped, so draw it
DrawSkyPolygon (nump, vecs);
return;
}
front = back = false;
norm = skyclip[stage];
for (i=0, v = vecs ; i<nump ; i++, v+=3)
{
d = DotProduct (v, norm);
if (d > ON_EPSILON)
{
front = true;
sides[i] = SIDE_FRONT;
}
else if (d < ON_EPSILON)
{
back = true;
sides[i] = SIDE_BACK;
}
else
sides[i] = SIDE_ON;
dists[i] = d;
}
if (!front || !back)
{ // not clipped
ClipSkyPolygon (nump, vecs, stage+1);
return;
}
// clip it
sides[i] = sides[0];
dists[i] = dists[0];
VectorCopy (vecs, (vecs+(i*3)) );
newc[0] = newc[1] = 0;
for (i=0, v = vecs ; i<nump ; i++, v+=3)
{
switch (sides[i])
{
case SIDE_FRONT:
VectorCopy (v, newv[0][newc[0]]);
newc[0]++;
break;
case SIDE_BACK:
VectorCopy (v, newv[1][newc[1]]);
newc[1]++;
break;
case SIDE_ON:
VectorCopy (v, newv[0][newc[0]]);
newc[0]++;
VectorCopy (v, newv[1][newc[1]]);
newc[1]++;
break;
}
if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
continue;
d = dists[i] / (dists[i] - dists[i+1]);
for (j=0 ; j<3 ; j++)
{
e = v[j] + d*(v[j+3] - v[j]);
newv[0][newc[0]][j] = e;
newv[1][newc[1]][j] = e;
}
newc[0]++;
newc[1]++;
}
// continue
ClipSkyPolygon (newc[0], newv[0][0], stage+1);
ClipSkyPolygon (newc[1], newv[1][0], stage+1);
}
/*
=================
R_DrawSkyChain
=================
*/
void R_DrawSkyChain (msurface_t *s)
{
msurface_t *fa;
int i;
vec3_t verts[MAX_CLIP_VERTS];
glpoly_t *p;
if (allowskybox && skyloaded)
{
c_sky = 0;
GL_Bind(solidskytexture);
// calculate vertex values for sky box
for (fa=s ; fa ; fa=fa->texturechain)
{
for (p=fa->polys ; p ; p=p->next)
{
for (i=0 ; i<p->numverts ; i++)
{
VectorSubtract (p->verts[i], r_origin, verts[i]);
}
ClipSkyPolygon (p->numverts, verts[0], 0);
}
}
} else {
// skies have no lightmap to prevent overbrighting --KB
glColor3f (0.5, 0.5, 0.5);
GL_DisableMultitexture();
// used when gl_texsort is on
GL_Bind(solidskytexture);
speedscale = realtime*8;
speedscale -= (int)speedscale & ~127 ;
for (fa=s ; fa ; fa=fa->texturechain)
EmitSkyPolys (fa);
GL_Bind (alphaskytexture);
speedscale = realtime*16;
speedscale -= (int)speedscale & ~127 ;
for (fa=s ; fa ; fa=fa->texturechain)
EmitSkyPolys (fa);
// the rest of the texture chain does though --KB
glColor3f (1.0, 1.0, 1.0);
}
glColor3f (1,1,1);
glDepthFunc (GL_LEQUAL);
glEnable (GL_DEPTH_TEST);
glDepthRange(gldepthmin, gldepthmax);
}
/*
==============
R_ClearSkyBox
==============
*/
void R_ClearSkyBox (void)
vec3_t domescale;
void
R_DrawSkyLayer (float s)
{
int i;
for (i=0 ; i<6 ; i++)
float a, b, x, y, a1x, a1y, a2x, a2y;
vec3_t v;
for (a = 0; a < 1; a += (1.0 / 32.0))
{
skymins[0][i] = skymins[1][i] = 9999;
skymaxs[0][i] = skymaxs[1][i] = -9999;
}
}
a1x = cos(a * M_PI * 2);
a1y = -sin(a * M_PI * 2);
a2x = cos((a+(1.0/32.0)) * M_PI * 2);
a2y = -sin((a+(1.0/32.0)) * M_PI * 2);
glBegin (GL_TRIANGLE_STRIP);
for (b = 0; b <= 1; b += (1.0 / 32.0))
{
x = cos(b * M_PI * 2);
y = -sin(b * M_PI * 2);
void MakeSkyVec (float s, float t, int axis)
{
vec3_t v, b;
int j, k;
v[0] = a1x*x * domescale[0];
v[1] = a1y*x * domescale[1];
v[2] = y * domescale[2];
glTexCoord2f((v[0] + s) * (1.0 / 128.0),
(v[1] + s) * (1.0 / 128.0));
glVertex3f(v[0] + r_refdef.vieworg[0],
v[1] + r_refdef.vieworg[1],
v[2] + r_refdef.vieworg[2]);
b[0] = s*2048;
b[1] = t*2048;
b[2] = 2048;
for (j=0 ; j<3 ; j++)
{
k = st_to_vec[axis][j];
if (k < 0)
v[j] = -b[-k - 1];
else
v[j] = b[k - 1];
v[j] += r_origin[j];
}
// avoid bilerp seam
s = (s+1)*0.5;
t = (t+1)*0.5;
if (s < 1.0/512)
s = 1.0/512;
else if (s > 511.0/512)
s = 511.0/512;
if (t < 1.0/512)
t = 1.0/512;
else if (t > 511.0/512)
t = 511.0/512;
t = 1.0 - t;
glTexCoord2f (s, t);
glVertex3fv (v);
}
/*
==============
R_DrawSkyBox
==============
*/
int skytexorder[6] = {0,2,1,3,4,5};
void R_DrawSkyBox (void)
{
int i;
for (i=0 ; i<6 ; i++)
{
if (skymins[0][i] >= skymaxs[0][i]
|| skymins[1][i] >= skymaxs[1][i])
continue;
GL_Bind (SKY_TEX+skytexorder[i]);
glBegin (GL_QUADS);
MakeSkyVec (skymins[0][i], skymins[1][i], i);
MakeSkyVec (skymins[0][i], skymaxs[1][i], i);
MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);
MakeSkyVec (skymaxs[0][i], skymins[1][i], i);
v[0] = a2x*x * domescale[0];
v[1] = a2y*x * domescale[1];
v[2] = y * domescale[2];
glTexCoord2f((v[0] + s) * (1.0 / 128.0),
(v[1] + s) * (1.0 / 128.0));
glVertex3f(v[0] + r_refdef.vieworg[0],
v[1] + r_refdef.vieworg[1],
v[2] + r_refdef.vieworg[2]);
}
glEnd ();
}
}
void
R_DrawSkyDome (void)
{
GL_DisableMultitexture ();
glEnable (GL_DEPTH_TEST);
glDepthFunc (GL_ALWAYS);
// glDisable (GL_BLEND);
// glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthRange (gldepthmax, gldepthmax);
glColor3f (0.5, 0.5, 0.5);
// base sky
glBindTexture (GL_TEXTURE_2D, solidskytexture);
domescale[0] = 512;
domescale[1] = 512;
domescale[2] = 128;
speedscale = realtime*8;
speedscale -= (int)speedscale & ~127;
R_DrawSkyLayer (speedscale);
glEnable (GL_BLEND);
// clouds
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
domescale[0] = 512;
domescale[1] = 512;
domescale[2] = 128;
speedscale = realtime*16;
speedscale -= (int)speedscale & ~127;
R_DrawSkyLayer (speedscale);
// glDisable (GL_BLEND);
glColor3f (1,1,1);
glDepthFunc (GL_LEQUAL);
glEnable (GL_DEPTH_TEST);
glDepthRange (gldepthmin, gldepthmax);
}
void
R_DrawSky ( void )
{
if (skyloaded)
R_DrawSkyBox();
else
R_DrawSkyDome();
}
//===============================================================
/*
@ -1036,7 +808,7 @@ void R_InitSky (texture_t *mt)
if (!solidskytexture)
solidskytexture = texture_extension_number++;
GL_Bind (solidskytexture );
glBindTexture (GL_TEXTURE_2D, solidskytexture );
glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@ -1054,7 +826,7 @@ void R_InitSky (texture_t *mt)
if (!alphaskytexture)
alphaskytexture = texture_extension_number++;
GL_Bind(alphaskytexture);
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);