533 lines
13 KiB
C
533 lines
13 KiB
C
/*
|
|
Copyright (C) 1996-1997 Id Software, Inc.
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
// REDO: recode skybox
|
|
// gl_sky.c all sky related stuff
|
|
//
|
|
#include "quakedef.h"
|
|
|
|
int solidskytexture;
|
|
int alphaskytexture;
|
|
float speedscale; // for top sky and bottom sky
|
|
|
|
|
|
char skyname[256];
|
|
char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
|
|
int skytexture[6];
|
|
|
|
|
|
// Tei sky customs
|
|
extern cvar_t sv_skyvalue;
|
|
extern cvar_t sv_skydim;
|
|
extern cvar_t sv_skyspeedscale;
|
|
extern cvar_t sv_skyflattern;
|
|
// Tei sky customs
|
|
|
|
// Tei autofx
|
|
void R_ParticleSnow (vec3_t origin);
|
|
void R_ParticleRain (vec3_t origin);
|
|
extern cvar_t r_autosnow;
|
|
extern cvar_t r_autorain;
|
|
extern cvar_t r_autometeor;
|
|
extern cvar_t r_autolightday;
|
|
void R_ParticleDay (vec3_t origin);
|
|
// Tei autofx
|
|
|
|
void DefineFlare(vec3_t origin, int radius, int mode, int alfa) ;
|
|
|
|
extern sfx_t *cl_zing_sfx;//Tei rain zing
|
|
extern sfx_t *cl_zing2_sfx;//Tei rain zing
|
|
extern sfx_t *cl_zing3_sfx;//Tei rain zing
|
|
|
|
/*
|
|
=============
|
|
EmitSkyPolys
|
|
=============
|
|
*/
|
|
|
|
extern cvar_t sv_stepsize; //Tei
|
|
extern cvar_t r_autozing;
|
|
void R_SuperZing (vec3_t start, vec3_t end);
|
|
void R_ParticleMeteor (vec3_t origin);
|
|
|
|
|
|
void EmitSkyPolys (msurface_t *s)
|
|
{
|
|
glpoly_t *p;
|
|
float *v;
|
|
int i;
|
|
float r, t;
|
|
vec3_t dir, hit;
|
|
float length;
|
|
qboolean dummy;
|
|
|
|
|
|
int frain, fsnow, flight; //Tei wheater fx
|
|
|
|
|
|
|
|
|
|
// Tei fix for skybox
|
|
//No draw if skybox
|
|
if (skyname[0])
|
|
dummy = true;
|
|
else
|
|
dummy = false;
|
|
// Tei fix for skybox
|
|
|
|
|
|
if(!dummy)
|
|
glBindTexture (GL_TEXTURE_2D, solidskytexture);
|
|
|
|
// Tei slow sky
|
|
//speedscale = realtime*8;
|
|
speedscale = realtime * sv_skyvalue.value * 0.1;//1
|
|
// Tei slow sky
|
|
|
|
|
|
// Tei wheater particle fx
|
|
|
|
// Force fx with name skysnow --> force snow
|
|
|
|
frain = s->texinfo->texture->frain;
|
|
fsnow = s->texinfo->texture->fsnow;
|
|
flight = s->texinfo->texture->flight;
|
|
|
|
// Tei wheater particle fx
|
|
|
|
|
|
glShadeModel (GL_SMOOTH);//XFX
|
|
|
|
speedscale -= (int)speedscale & ~127;
|
|
|
|
for (p=s->polys ; p ; p=p->next)
|
|
{
|
|
if(!dummy)
|
|
glBegin (GL_POLYGON);
|
|
|
|
for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
|
|
{
|
|
VectorSubtract (v, r_origin, dir);
|
|
//Tei More flat sky
|
|
dir[2] *= sv_skydim.value;//32; // flatten the sphere //tei2 16
|
|
//Tei More flat sky
|
|
|
|
length = 378/Length (dir); // Tomaz - Speed
|
|
|
|
dir[0] *= length;
|
|
dir[1] *= length;
|
|
|
|
r = (speedscale + dir[0]) * (0.0078125); // Tomaz - Speed
|
|
t = (speedscale + dir[1]) * (0.0078125); // Tomaz - Speed
|
|
|
|
// Tei autofx
|
|
if (r_autorain.value || frain)
|
|
{
|
|
//if (rand()&1) // fixme
|
|
//if ( rand() & 4095)
|
|
//if ( rand()%32000 < (32000/8) ) // RAND_MAX?
|
|
if ( teirand(100)<(9 + r_autorain.value) )
|
|
{
|
|
R_ParticleRain (v);
|
|
}
|
|
}
|
|
if (r_autometeor.value )
|
|
{
|
|
if ( teirand(30000)<(1 + r_autometeor.value) )
|
|
{
|
|
R_ParticleMeteor(v);
|
|
}
|
|
}
|
|
if (r_autozing.value)
|
|
if ( teirand(2200)<r_autozing.value )
|
|
if ( teirand(2200)*100<r_autozing.value )
|
|
{
|
|
/* Generating a random Zing */
|
|
|
|
VectorCopy(v,hit);
|
|
//DefineFlare();
|
|
hit[2] -= 5;
|
|
|
|
DefineFlare(hit, 600, 0, 90);//FLASH!
|
|
|
|
hit[2] -= 1000;
|
|
hit[0] += lhrandom(-100,100);
|
|
hit[1] += lhrandom(-100,100);
|
|
R_SuperZing(v,hit);//Ray!
|
|
hit[0] += lhrandom(-100,100);
|
|
hit[1] += lhrandom(-100,100);
|
|
R_SuperZing(v,hit);//Ray!
|
|
hit[0] += lhrandom(-100,100);
|
|
hit[1] += lhrandom(-100,100);
|
|
R_SuperZing(v,hit);//Ray!
|
|
if (cl_zing_sfx && cl_zing2_sfx && cl_zing3_sfx)
|
|
{
|
|
VectorCopy(v,hit);
|
|
hit[2] -= 128;
|
|
if (rand()&1)
|
|
S_StartSound (-1, 0, cl_zing_sfx,hit , 1, 1);
|
|
if (rand()&1)
|
|
S_StartSound (-1, 1, cl_zing2_sfx,hit , 1, 1);
|
|
//if (rand()&1)
|
|
S_StartSound (-1, 2, cl_zing3_sfx,hit , 1, 1);
|
|
}
|
|
|
|
/* with 3 the effect is realistic */
|
|
}
|
|
|
|
|
|
if (r_autosnow.value || fsnow)
|
|
{
|
|
///if (rand()&127>62) // fixme
|
|
//if (rand() & 4095 )
|
|
if ( teirand(100)<(1+r_autosnow.value) )
|
|
//if ( rand()%32000 < (32000/256) ) // RAND_MAX?
|
|
R_ParticleSnow (v);
|
|
|
|
}
|
|
if (r_autolightday.value || flight)
|
|
{
|
|
//if (rand()&1)
|
|
//if (rand()&231>230)
|
|
//if ( rand()%32000 < (32000/64) )
|
|
if ( teirand(100)<(2+r_autolightday.value) )
|
|
R_ParticleDay (v);
|
|
}
|
|
/*
|
|
else
|
|
if (r_autolightday.value == 2)
|
|
{
|
|
VectorCopy(v, k);
|
|
k[2] -= 3 + rand()&1;
|
|
if (rand()&1)
|
|
if (rand()&231>230)
|
|
R_ParticleDream (k);
|
|
//R_ParticleDay (v);
|
|
|
|
}*/
|
|
|
|
// Tei autofx
|
|
if(!dummy){
|
|
|
|
glTexCoord2f (r, t);
|
|
glVertex3fv (v);
|
|
}
|
|
}
|
|
if(!dummy)
|
|
glEnd ();
|
|
}
|
|
|
|
if(dummy)
|
|
return;//Tei nodraw while skybox
|
|
|
|
glBindTexture (GL_TEXTURE_2D, alphaskytexture);
|
|
|
|
|
|
|
|
// Tei slow sky
|
|
//speedscale = realtime*16;
|
|
speedscale = realtime*sv_skyspeedscale.value * 0.1;//2
|
|
// Tei slow sky
|
|
|
|
speedscale -= (int)speedscale & ~127;
|
|
|
|
for (p=s->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
|
|
dir[2] *= sv_skyflattern.value;//16; // tei2
|
|
|
|
length = 378/Length (dir); // Tomaz - Speed
|
|
|
|
dir[0] *= length;
|
|
dir[1] *= length;
|
|
|
|
r = (speedscale + dir[0]) * (0.0078125); // Tomaz - Speed
|
|
t = (speedscale + dir[1]) * (0.0078125); // Tomaz - Speed
|
|
|
|
glTexCoord2f (r, t);
|
|
glVertex3fv (v);
|
|
|
|
}
|
|
glEnd ();
|
|
}
|
|
|
|
// EmitUnderwaterPolys2(s);//XFX --humm...glass in the sky?
|
|
}
|
|
|
|
|
|
/*
|
|
==================
|
|
R_LoadSkys
|
|
==================
|
|
*/
|
|
void R_LoadSkys (void)
|
|
{
|
|
int i;
|
|
char name[64];
|
|
|
|
for (i=0 ; i<6 ; i++)
|
|
{
|
|
//sprintf (name, "gfx/env/%s%s", skyname, suf[i]);
|
|
sprintf (name, "gfx/sky/%s%s", skyname, suf[i]);
|
|
skytexture[i] = loadtextureimage(name, false ,true);
|
|
//Tei, tenebrae env style
|
|
if (skytexture[i] == 0)
|
|
{
|
|
//sprintf (name, "env/%s%s", skyname, suf[i]);
|
|
sprintf (name, "gfx/sky/%s%s", skyname, suf[i]);
|
|
skytexture[i] = loadtextureimage(name, true ,true);
|
|
}
|
|
//Tei, tenebrae env style
|
|
if (skytexture[i] == 0)
|
|
{
|
|
//sprintf (name, "gfx/env/tomazsky%s", suf[i]);
|
|
sprintf (name, "gfx/sky/%s%s", skyname, suf[i]);
|
|
skytexture[i] = loadtextureimage(name, true ,true);
|
|
}
|
|
}
|
|
}
|
|
void R_SetSkyBox (char *sky)
|
|
{
|
|
strcpy(skyname, sky);
|
|
R_LoadSkys ();
|
|
}
|
|
|
|
void LoadSky_f (void)
|
|
{
|
|
switch (Cmd_Argc())
|
|
{
|
|
case 1:
|
|
if (skyname[0])
|
|
Con_Printf("Current sky: %s\n", skyname);
|
|
else
|
|
Con_Printf("Error: No skybox has been set\n");
|
|
break;
|
|
case 2:
|
|
R_SetSkyBox(Cmd_Argv(1));
|
|
break;
|
|
default:
|
|
Con_Printf("Usage: loadsky skyname\n");
|
|
break;
|
|
}
|
|
}
|
|
// Tomaz - Skybox End
|
|
|
|
/*
|
|
=================
|
|
R_DrawSky
|
|
=================
|
|
*/
|
|
void R_DrawSky (msurface_t *s)
|
|
{
|
|
for ( ; s ; s=s->texturechain)
|
|
EmitSkyPolys (s);
|
|
}
|
|
|
|
|
|
/*
|
|
==============
|
|
R_DrawSkyBox
|
|
==============
|
|
*/
|
|
int skytexorder[6] = {0,2,1,3,4,5};
|
|
|
|
#define R_SkyBoxPolyVec(s,t,x,y,z) \
|
|
glTexCoord2f(s, t);\
|
|
glVertex3f((x) + r_refdef.vieworg[0], (y) + r_refdef.vieworg[1], (z) + r_refdef.vieworg[2]);
|
|
|
|
extern int skybox_initialised;
|
|
void CheckForNextSkybox ();
|
|
void SetActualFeaturesSkybox();
|
|
|
|
void R_DrawSkyBox (void)
|
|
{
|
|
if (gl_fogenable.value)
|
|
glDisable(GL_FOG);
|
|
|
|
if (skybox_initialised)
|
|
CheckForNextSkybox();
|
|
|
|
glBindTexture(GL_TEXTURE_2D, skytexture[skytexorder[3]]); // front
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
SetActualFeaturesSkybox();//Tei animated skybox
|
|
|
|
R_SkyBoxPolyVec(0.998047f, 0.001953f, 3072, -3072, 3072);
|
|
R_SkyBoxPolyVec(0.998047f, 0.998047f, 3072, -3072, -3072);
|
|
R_SkyBoxPolyVec(0.001953f, 0.998047f, 3072, 3072, -3072);
|
|
R_SkyBoxPolyVec(0.001953f, 0.001953f, 3072, 3072, 3072);
|
|
glEnd();
|
|
|
|
glBindTexture(GL_TEXTURE_2D, skytexture[skytexorder[2]]); // back
|
|
glBegin(GL_QUADS);
|
|
|
|
SetActualFeaturesSkybox();//Tei animated skybox
|
|
|
|
R_SkyBoxPolyVec(0.998047f, 0.001953f, -3072, 3072, 3072);
|
|
R_SkyBoxPolyVec(0.998047f, 0.998047f, -3072, 3072, -3072);
|
|
R_SkyBoxPolyVec(0.001953f, 0.998047f, -3072, -3072, -3072);
|
|
R_SkyBoxPolyVec(0.001953f, 0.001953f, -3072, -3072, 3072);
|
|
glEnd();
|
|
|
|
glBindTexture(GL_TEXTURE_2D, skytexture[skytexorder[0]]); // right
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
SetActualFeaturesSkybox();//Tei animated skybox
|
|
|
|
R_SkyBoxPolyVec(0.998047f, 0.001953f, 3072, 3072, 3072);
|
|
R_SkyBoxPolyVec(0.998047f, 0.998047f, 3072, 3072, -3072);
|
|
R_SkyBoxPolyVec(0.001953f, 0.998047f, -3072, 3072, -3072);
|
|
R_SkyBoxPolyVec(0.001953f, 0.001953f, -3072, 3072, 3072);
|
|
glEnd();
|
|
|
|
glBindTexture(GL_TEXTURE_2D, skytexture[skytexorder[1]]); // left
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
SetActualFeaturesSkybox();//Tei animated skybox
|
|
|
|
R_SkyBoxPolyVec(0.998047f, 0.001953f, -3072, -3072, 3072);
|
|
R_SkyBoxPolyVec(0.998047f, 0.998047f, -3072, -3072, -3072);
|
|
R_SkyBoxPolyVec(0.001953f, 0.998047f, 3072, -3072, -3072);
|
|
R_SkyBoxPolyVec(0.001953f, 0.001953f, 3072, -3072, 3072);
|
|
glEnd();
|
|
|
|
glBindTexture(GL_TEXTURE_2D, skytexture[skytexorder[4]]); // up
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
SetActualFeaturesSkybox();//Tei animated skybox
|
|
|
|
R_SkyBoxPolyVec(0.998047f, 0.001953f, 3072, -3072, 3072);
|
|
R_SkyBoxPolyVec(0.998047f, 0.998047f, 3072, 3072, 3072);
|
|
R_SkyBoxPolyVec(0.001953f, 0.998047f, -3072, 3072, 3072);
|
|
R_SkyBoxPolyVec(0.001953f, 0.001953f, -3072, -3072, 3072);
|
|
glEnd();
|
|
|
|
glBindTexture(GL_TEXTURE_2D, skytexture[skytexorder[5]]); // down
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
SetActualFeaturesSkybox();//Tei animated skybox
|
|
|
|
R_SkyBoxPolyVec(0.998047f, 0.001953f, 3072, 3072, -3072);
|
|
R_SkyBoxPolyVec(0.998047f, 0.998047f, 3072, -3072, -3072);
|
|
R_SkyBoxPolyVec(0.001953f, 0.998047f, -3072, -3072, -3072);
|
|
R_SkyBoxPolyVec(0.001953f, 0.001953f, -3072, 3072, -3072);
|
|
glEnd();
|
|
|
|
if (gl_fogenable.value)
|
|
glEnable(GL_FOG);
|
|
}
|
|
|
|
|
|
|
|
//===============================================================
|
|
|
|
/*
|
|
=============
|
|
R_InitSky
|
|
|
|
A sky texture is 256*128, with the right side being a masked overlay
|
|
==============
|
|
*/
|
|
void R_InitSky (byte *src, int bytesperpixel)
|
|
{
|
|
int i, j, p;
|
|
unsigned trans[128*128];
|
|
unsigned transpix;
|
|
int r, g, b;
|
|
unsigned *rgba;
|
|
|
|
// if (isDedicated)
|
|
// return;
|
|
|
|
// Con_Printf("heaven\n");//xfx
|
|
|
|
if (bytesperpixel == 4)
|
|
{
|
|
for (i = 0;i < 128;i++)
|
|
for (j = 0;j < 128;j++)
|
|
trans[(i*128) + j] = src[i*256+j+128];
|
|
}
|
|
else
|
|
{
|
|
// make an average value for the back to avoid
|
|
// a fringe on the top level
|
|
r = g = b = 0;
|
|
for (i=0 ; i<128 ; i++)
|
|
for (j=0 ; j<128 ; j++)
|
|
{
|
|
p = src[i*256 + j + 128];
|
|
rgba = &d_8to24table[p];
|
|
trans[(i*128) + j] = *rgba;
|
|
r += ((byte *)rgba)[0];
|
|
g += ((byte *)rgba)[1];
|
|
b += ((byte *)rgba)[2];
|
|
}
|
|
|
|
((byte *)&transpix)[0] = r/(128*128);
|
|
((byte *)&transpix)[1] = g/(128*128);
|
|
((byte *)&transpix)[2] = b/(128*128);
|
|
((byte *)&transpix)[3] = 0;
|
|
}
|
|
|
|
if (!solidskytexture)
|
|
solidskytexture = texture_extension_number++;
|
|
|
|
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);
|
|
|
|
|
|
if (bytesperpixel == 4)
|
|
{
|
|
for (i = 0;i < 128;i++)
|
|
for (j = 0;j < 128;j++)
|
|
trans[(i*128) + j] = src[i*256+j];
|
|
}
|
|
else
|
|
{
|
|
for (i=0 ; i<128 ; i++)
|
|
for (j=0 ; j<128 ; j++)
|
|
{
|
|
p = src[i*256 + j];
|
|
if (p == 0)
|
|
trans[(i*128) + j] = transpix;
|
|
else
|
|
trans[(i*128) + j] = d_8to24table[p];
|
|
}
|
|
}
|
|
|
|
if (!alphaskytexture)
|
|
alphaskytexture = texture_extension_number++;
|
|
|
|
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);
|
|
}
|