- Fixed crash for fragment shader effects being loaded for unsupported hardware

- unfinished texture dumping mode, r_texdump would save jpegs of any texture that loads....upside down. The purpose of this is to make compact content builds with only the used textures (without bloat)
- the eager beginning of a water refraction/reflection buffer
- some map texture listing fixes
- very unfinished revolution environment maps
- very unfinished 'crazy' lighting changes
- some pointless whitepsaces added for no reason other than to open file, add something, remove it later, and leave it changed
This commit is contained in:
leilei-
2014-06-14 07:30:15 -04:00
parent 1947afbe2e
commit 43d6a97c43
15 changed files with 805 additions and 106 deletions

View File

@@ -82,18 +82,6 @@ typedef struct fxAtive_s {
int beenUsed;
} fxActive_t;
typedef struct fxEntity_s {
struct fxEntity_s *next;
const fxRunEmitter_t *emitter;
int flags;
int startTime;
float traceTime;
float moveTime, lifeScale;
vec3_t origin, velocity;
} fxEntity_t;
//Making any changes to this order you'll also need to modify the mask/unpacking stuff
typedef struct {
vec3_t origin;

View File

@@ -1694,6 +1694,7 @@ const void *RB_SwapBuffers( const void *data ) {
backEnd.projection2D = qfalse;
backEnd.doneBloom = qfalse;
backEnd.donewater = qfalse;
backEnd.donepostproc = qfalse;
backEnd.doneAltBrightness = qfalse;
backEnd.doneFilm = qfalse;
@@ -1759,6 +1760,7 @@ void RB_ExecuteRenderCommands( const void *data ) {
case RC_STRETCH_PIC:
//Check if it's time for BLOOM!
leifxmode = 0;
R_WaterScreen(); // do this first
R_PostprocessScreen();
R_BloomScreen();
R_FilmScreen();
@@ -1774,6 +1776,7 @@ void RB_ExecuteRenderCommands( const void *data ) {
case RC_SWAP_BUFFERS:
//Check if it's time for BLOOM!
leifxmode = 0;
R_WaterScreen(); // do this first
R_PostprocessScreen();
R_BloomScreen();
R_FilmScreen();

View File

@@ -17,7 +17,8 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// tr_bloom.c: 2D lighting post process effect
// tr_bloom.c: General post-processing shader stuff including bloom, leifx, and everything else
// that's postprocessed. Maintained by leilei and Hitchiker
#include "tr_local.h"
@@ -39,6 +40,16 @@ extern cvar_t *r_overBrightBits;
extern cvar_t *r_gamma;
static cvar_t *r_bloom_reflection; // LEILEI
static cvar_t *r_bloom_sky_only; // LEILEI
cvar_t *r_film;
extern int force32upload;
int leifxmode;
@@ -69,6 +80,20 @@ static float Diamond8x[8][8] =
{ 0.0f, 0.0f, 0.0f, 0.1f, 0.1f, 0.0f, 0.0f, 0.0f }
};
static float Star8x[8][8] =
{
{ 0.4f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 0.4f, },
{ 0.1f, 0.6f, 0.2f, 0.0f, 0.0f, 0.2f, 0.6f, 0.1f, },
{ 0.0f, 0.2f, 0.7f, 0.6f, 0.6f, 0.7f, 0.2f, 0.0f, },
{ 0.0f, 0.0f, 0.6f, 0.9f, 0.9f, 0.6f, 0.0f, 0.0f, },
{ 0.0f, 0.0f, 0.6f, 0.9f, 0.9f, 0.6f, 0.0f, 0.0f, },
{ 0.0f, 0.2f, 0.7f, 0.6f, 0.6f, 0.7f, 0.2f, 0.0f, },
{ 0.1f, 0.6f, 0.2f, 0.0f, 0.0f, 0.2f, 0.6f, 0.1f, },
{ 0.4f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 0.4f, }
};
static float Diamond6x[6][6] =
{
{ 0.0f, 0.0f, 0.1f, 0.1f, 0.0f, 0.0f, },
@@ -109,6 +134,31 @@ static struct {
qboolean started;
} bloom;
static struct {
struct {
image_t *texture;
int width, height;
float readW, readH;
} effect;
struct {
image_t *texture;
int width, height;
float readW, readH;
} effect2;
struct {
image_t *texture;
int width, height;
float readW, readH;
} screen;
struct {
int width, height;
} work;
qboolean started;
} water;
static struct {
struct {
image_t *texture;
@@ -478,6 +528,67 @@ else
}
// leilei - experimental water effect
static void R_Water_InitTextures( void )
{
byte *data;
// find closer power of 2 to screen size
for (water.screen.width = 1;water.screen.width< glConfig.vidWidth;water.screen.width *= 2);
for (water.screen.height = 1;water.screen.height < glConfig.vidHeight;water.screen.height *= 2);
water.screen.readW = glConfig.vidWidth / (float)water.screen.width;
water.screen.readH = glConfig.vidHeight / (float)water.screen.height;
// find closer power of 2 to effect size
water.work.width = 256;
water.work.height = water.work.width * ( glConfig.vidWidth / glConfig.vidHeight );
for (water.effect.width = 1;water.effect.width < water.work.width;water.effect.width *= 2);
for (water.effect.height = 1;water.effect.height < water.work.height;water.effect.height *= 2);
water.effect.readW = water.work.width / (float)water.effect.width;
water.effect.readH = water.work.height / (float)water.effect.height;
water.effect2.readW=water.effect.readW;
water.effect2.readH=water.effect.readH;
water.effect2.width=water.effect.width;
water.effect2.height=water.effect.height;
// disable waters if we can't handle a texture of that size
if( water.screen.width > glConfig.maxTextureSize ||
water.screen.height > glConfig.maxTextureSize ||
water.effect.width > glConfig.maxTextureSize ||
water.effect.height > glConfig.maxTextureSize ||
water.work.width > glConfig.vidWidth ||
water.work.height > glConfig.vidHeight
) {
ri.Cvar_Set( "r_leiwater", "0" );
Com_Printf( S_COLOR_YELLOW"WARNING: 'R_InitWaterTextures' too high resolution for water, effect disabled\n" );
return;
}
// leilei - let's not do that water disabling anymore
force32upload = 1;
data = ri.Hunk_AllocateTempMemory( water.screen.width * water.screen.height * 4 );
Com_Memset( data, 0, water.screen.width * water.screen.height * 4 );
water.screen.texture = R_CreateImage( "***water screen texture***", data, water.screen.width, water.screen.height, qfalse, qfalse, GL_CLAMP_TO_EDGE );
ri.Hunk_FreeTempMemory( data );
data = ri.Hunk_AllocateTempMemory( water.effect.width * water.effect.height * 4 );
Com_Memset( data, 0, water.effect.width * water.effect.height * 4 );
tr.waterImage = R_CreateImage( "*water", data, water.effect.width, water.effect.height, IMGTYPE_COLORALPHA, IMGFLAG_CLAMPTOEDGE, 0 );
//tr.waterImage = R_CreateImage( "*waterimage", data, water.effect.width, water.effect.height, qfalse, qfalse, GL_CLAMP_TO_EDGE );;
ri.Hunk_FreeTempMemory( data );
water.started = qtrue;
force32upload = 0;
}
/*
=================
R_InitBloomTextures
@@ -491,6 +602,14 @@ void R_InitBloomTextures( void )
R_Bloom_InitTextures ();
}
void R_InitWaterTextures( void )
{
if( !r_leiwater->integer )
return;
memset( &water, 0, sizeof( water ));
R_Water_InitTextures ();
}
/*
=================
R_InitPostprocessTextures
@@ -739,8 +858,14 @@ static void R_Bloom_WarsowEffect( void )
diamond = &Diamond6x[0][0];
scale = r_bloom_intensity->value * 0.5f;
break;
case 9:
k = 4;
diamond = &Star8x[0][0];
scale = r_bloom_intensity->value * 0.3f;
break;
default:
// case 8:
case 8:
k = 4;
diamond = &Diamond8x[0][0];
scale = r_bloom_intensity->value * 0.3f;
@@ -773,6 +898,11 @@ static void R_Bloom_BackupScreen( void ) {
GL_Bind( bloom.screen.texture );
qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight );
}
static void R_Water_BackupScreen( void ) {
GL_Bind( water.screen.texture );
qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight );
}
/*
=================
R_Postprocess_BackupScreen
@@ -857,6 +987,15 @@ static void R_Bloom_RestoreScreen( void ) {
bloom.work.height / (float)bloom.screen.height );
}
}
static void R_Water_RestoreScreen( void ) {
GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
GL_Bind( water.screen.texture );
qglColor4f( 1,1,1, 1 );
R_Bloom_Quad( water.screen.width, water.screen.height, 0, 0,
1.f,
1.f );
}
/*
=================
@@ -1130,6 +1269,49 @@ void R_BloomScreen( void )
R_Bloom_LensEffect ();
}
static void R_WaterWorks( void )
{
int i, j, k;
float intensity, scale, *diamond;
qglColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
GL_Bind( water.screen.texture );
//GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
R_Bloom_Quad( water.work.width, water.work.height, 0, 0, water.screen.readW, water.screen.readH );
//Copy downscaled framebuffer into a texture
GL_Bind( tr.waterImage );
qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, water.work.width, water.work.height );
}
void R_WaterScreen( void )
{
if( !r_leiwater->integer )
return;
if ( backEnd.donewater )
return;
if ( !backEnd.doneSurfaces )
return;
backEnd.donewater= qtrue;
if( !water.started ) {
R_Water_InitTextures();
if( !water.started )
return;
}
if ( !backEnd.projection2D )
RB_SetGL2D();
//// All we want to do is copy the thing
R_Water_BackupScreen();
R_WaterWorks ();
R_Water_RestoreScreen();
}
/*
=================
R_PostprocessScreen
@@ -1143,6 +1325,8 @@ void R_PostprocessScreen( void )
return;
if ( !backEnd.doneSurfaces )
return;
if ( !vertexShaders )
return; // leilei - cards without support for this should not ever activate this
backEnd.donepostproc = qtrue;
if( !postproc.started ) {
R_Postprocess_InitTextures();
@@ -1217,6 +1401,8 @@ void R_LeiFXPostprocessDitherScreen( void )
return;
if ( backEnd.doneleifx)
return;
if ( !vertexShaders )
return; // leilei - cards without support for this should not ever activate this
// if ( !backEnd.doneSurfaces )
// return;
// backEnd.doneleifx = qtrue;
@@ -1255,6 +1441,8 @@ void R_LeiFXPostprocessFilterScreen( void )
return;
if ( backEnd.doneleifx)
return;
if ( !vertexShaders )
return; // leilei - cards without support for this should not ever activate this
// if ( !backEnd.doneSurfaces )
// return;
if( !postproc.started ) {
@@ -1310,6 +1498,8 @@ void R_TVScreen( void )
return;
if ( backEnd.donetv)
return;
if ( !vertexShaders )
return; // leilei - cards without support for this should not ever activate this
if( !postproc.started ) {
force32upload = 1;
R_Postprocess_InitTextures();
@@ -1359,6 +1549,8 @@ void R_RetroAAScreen( void )
return;
if ( backEnd.doneraa)
return;
if ( !vertexShaders )
return; // leilei - cards without support for this should not ever activate this
if( !postproc.started ) {
force32upload = 1;
R_Postprocess_InitTextures();
@@ -1393,6 +1585,8 @@ void R_AnimeScreen( void )
return;
if ( !backEnd.doneSurfaces )
return;
if ( !vertexShaders )
return; // leilei - cards without support for this should not ever activate this
if( !postproc.started ) {
force32upload = 1;
R_Postprocess_InitTextures();
@@ -1431,6 +1625,8 @@ void R_MblurScreen( void )
return;
if ( !backEnd.doneSurfaces )
return;
if ( !vertexShaders )
return; // leilei - cards without support for this should not ever activate this
if( !postproc.started ) {
force32upload = 1;
R_Postprocess_InitTextures();
@@ -1456,6 +1652,8 @@ void R_MblurScreenPost( void )
return;
if ( !backEnd.doneSurfaces )
return;
if ( !vertexShaders )
return; // leilei - cards without support for this should not ever activate this
if( !postproc.started ) {
force32upload = 1;
R_Postprocess_InitTextures();
@@ -1499,6 +1697,11 @@ void R_BloomInit( void ) {
r_bloom_sky_only = ri.Cvar_Get( "r_bloom_sky_only", "0", CVAR_ARCHIVE );
}
void R_WaterInit( void ) {
memset( &water, 0, sizeof( water ));
}
void R_PostprocessingInit(void) {
memset( &postproc, 0, sizeof( postproc ));
}
@@ -1601,7 +1804,7 @@ void R_BrightScreen( void )
if ( !backEnd.projection2D )
RB_SetGL2D();
// Fragment shader
if (r_alternateBrightness->integer == 2)
if ((r_alternateBrightness->integer == 2) && (vertexShaders))
{
force32upload = 1;

View File

@@ -246,12 +246,10 @@ void GLimp_InitExtraExtensions()
if ( GLimp_HaveExtension( "GL_EXT_paletted_texture" ) )
{
if ( r_ext_paletted_texture->integer ) {
//qglCompressedTexImage2DARB = (GLvoid (APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) SDL_GL_GetProcAddress("glCompressedTexImage2DARB");
qglColorTableEXT = (GLvoid (APIENTRYP)(GLint, GLint, GLint, GLint, GLint, const GLvoid *)) SDL_GL_GetProcAddress("glColorTableEXT");
// SGI
qglColorTableSGI = (GLvoid (APIENTRYP)(GLint, GLint, GLint, GLint, GLint, const GLvoid *)) SDL_GL_GetProcAddress("glColorTableSGI");
//qglColorTableEXT = ( void ( APIENTRY * ) ( int, int, int, int, int, const void * ) ) qwglGetProcAddress( "glColorTableEXT" );
{
ri.Printf( PRINT_ALL, "...using GL_EXT_paletted_texture\n");
palettedTextureSupport = qtrue;

View File

@@ -1050,6 +1050,88 @@ int hqresample = 0; // leilei - high quality texture resampling
// Currently 0 as there is an alignment issue I haven't fixed.
int isicon; // leilei - for determining if it's an icon.
char dumpname[ MAX_QPATH ]; // leilei - name for texture dumping
static void DumpTex( unsigned *data,
int width, int height )
{
// leilei - Do crazy dumping crap
byte *scan;
byte *baffer, *alffer, *flipper;
scan = ((byte *)data);
size_t offset = 0, memcount;
int padlen;
int be, bi, ber, ba;
int scrale = width * height;
int scravg = width + height / 2;
int wit = width;
int hat = height;
int quality = 85; // estimate quality from total size
int hasalf = 0;
float countw, counth;
if (scravg > 511) quality = 42; // huge textures
else if (scravg > 255) quality = 62; // large textures
else if (scravg > 127) quality = 72; // large textures
else if (scravg < 127) quality = 95; // tiny textures
baffer = ri.Hunk_AllocateTempMemory( width * height * 3 );
flipper = ri.Hunk_AllocateTempMemory( width * height * 3 );
alffer = ri.Hunk_AllocateTempMemory( width * height * 3 );
// TODO: Save alpha separately
// I'm gonna flip......
int alfcnt = 0;
countw = 0;
counth = 0;
wit = width * 3;
hat = height * 3;
for (be=0; be<scrale; be++){
int bib;
if (countw > width)
countw = 0;
else
countw++;
ber = scrale - be - 1;
bib = be;
if (bib < 0) bib = 0;
if (bib > scrale) bib = 0;
baffer[bib*3] = scan[ber*4];
baffer[bib*3+1] = scan[ber*4+1];
baffer[bib*3+2] = scan[ber*4+2];
alffer[bib*3] = scan[ber*4+3];
alffer[bib*3+1] = scan[ber*4+3];
alffer[bib*3+2] = scan[ber*4+3];
if (scan[ber*4+3] > 1){ hasalf = 1;}
if (scan[ber*4+3] == 255){ alfcnt += 1; }
}
// NOW FIX IT
memcount = (width * 3 + padlen) * height;
if ((width > 16) && (height > 16)){
RE_SaveJPG( va("dump/%s.jpg", dumpname), 85,width, height, baffer, padlen);
if (hasalf)
RE_SaveJPG( va("dump/%s_alpha.jpg", dumpname), 85,width, height, alffer, padlen);
}
ri.Printf( PRINT_ALL, "TEXDUMP: %s \n", dumpname );
// if ( baffer != 0 )
ri.Hunk_FreeTempMemory( baffer );
// if ( alffer != 0 )
ri.Hunk_FreeTempMemory( alffer );
ri.Hunk_FreeTempMemory( flipper );
}
static void Upload32( unsigned *data,
int width, int height,
qboolean mipmap,
@@ -1240,6 +1322,9 @@ static void Upload32( unsigned *data,
}
}
if( r_greyscale->value )
{
// leilei - replaced with saturation processing
@@ -1350,7 +1435,7 @@ static void Upload32( unsigned *data,
}
if (detailhack) internalFormat = GL_LUMINANCE; // leilei - use paletted mono format for detail textures
if (force32upload) internalFormat = GL_RGB8; // leilei - gets bloom and postproc working on s3tc & 8bit & palettes
if (r_leifx->integer && !force32upload) internalFormat = GL_RGB5;
if ((r_leifx->integer) && (!force32upload)) internalFormat = GL_RGB5;
}
}
else if ( samples == 4 )
@@ -1396,7 +1481,7 @@ static void Upload32( unsigned *data,
internalFormat = GL_RGBA;
}
if (force32upload) internalFormat = GL_RGBA8; // leilei - gets bloom and postproc working on s3tc & 8bit & palettes
if (r_leifx->integer && !force32upload) internalFormat = GL_RGBA4;
if ((r_leifx->integer) && (!force32upload)) internalFormat = GL_RGBA4;
}
}
}
@@ -1406,6 +1491,8 @@ static void Upload32( unsigned *data,
else
{ temp_GLformat=GL_RGBA; temp_GLtype=GL_UNSIGNED_BYTE; }
// copy or resample data as appropriate for first MIP level
if ( ( scaled_width == width ) &&
( scaled_height == height ) ) {
@@ -1418,6 +1505,10 @@ static void Upload32( unsigned *data,
goto done;
}
Com_Memcpy (scaledBuffer, data, width*height*4);
}
else
@@ -1445,6 +1536,8 @@ static void Upload32( unsigned *data,
qglTexImage2D (GL_TEXTURE_2D, 0, internalFormat, scaled_width, scaled_height, 0, temp_GLformat, temp_GLtype, scaledBuffer );
if (mipmap)
{
int miplevel;
@@ -1470,11 +1563,14 @@ static void Upload32( unsigned *data,
R_BlendToGray( (byte *)scaledBuffer, scaled_width * scaled_height, miplevel );
}
qglTexImage2D (GL_TEXTURE_2D, miplevel, internalFormat, scaled_width, scaled_height, 0, temp_GLformat, temp_GLtype, scaledBuffer );
}
}
done:
if (mipmap)
{
if ( textureFilterAnisotropic )
@@ -1592,7 +1688,7 @@ static void Upload8( unsigned *data,
texsizey = glConfig.maxTextureSize;
if (r_leifx->integer && !force32upload){ // leilei
if ((r_leifx->integer) && (!force32upload)){ // leilei
texsizex = 256; // 3dfx
texsizey = 256; // 3dfx
}
@@ -1882,6 +1978,12 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height,
GL_Bind(image);
// leilei - texture dumping
if (r_texdump->integer){
COM_StripExtension( name, dumpname, MAX_QPATH ); // leilei - transfer name for texdump
DumpTex( (unsigned *)pic, image->width, image->height);
}
if (paletteavailable && r_texturebits->integer == 8 && !isLightmap && !depthimage && !force32upload)
Upload8( (unsigned *)pic, image->width, image->height,
image->flags & IMGFLAG_MIPMAP,
@@ -2073,10 +2175,7 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags )
// leilei - iconmip hack
if ( !Q_strncmp( name, "icons/", 5 ) ||
!Q_strncmp( name, "gfx/2d", 6 ) &&
Q_strncmp( name, "gfx/2d/bigchars", 14 )
){
if ( !Q_strncmp( name, "icons/", 5 ) || (!Q_strncmp( name, "gfx/2d", 6 )) && (Q_strncmp( name, "gfx/2d/bigchars", 14 ))){
isicon = 1;
}
else
@@ -2092,7 +2191,7 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags )
image = R_CreateImage( ( char * ) name, pic, width, height, type, flags, 0 );
ri.Free( pic );
ismaptexture = 0;
return image;
}
@@ -2189,6 +2288,8 @@ static void R_CreateDlightImage( void ) {
}
}
tr.dlightImage = R_CreateImage("*dlight", (byte *)data, DLIGHT_SIZE, DLIGHT_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_CLAMPTOEDGE, 0 );
// tr.dlightImage = R_CreateImage("*dlight", (byte *)data, DLIGHT_SIZE, DLIGHT_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_CLAMPTOEDGE, 0 );
}
@@ -2264,14 +2365,18 @@ static void R_CreateFogImage( void ) {
// S is distance, T is depth
for (x=0 ; x<FOG_S ; x++) {
for (y=0 ; y<FOG_T ; y++) {
// d = R_FogFactor( ( x + 0.5f ) / FOG_S, ( y + 0.5f ) / FOG_T );
d = R_FogFactor( ( x + 0.5f ) / FOG_S, ( y + 0.5f ) / FOG_T );
data[(y*FOG_S+x)*4+0] =
data[(y*FOG_S+x)*4+1] =
data[(y*FOG_S+x)*4+2] = 255;
data[(y*FOG_S+x)*4+3] = 255*d;
}
}
// standard openGL clamping doesn't really do what we want -- it includes
// the border color at the edges. OpenGL 1.2 has clamp-to-edge, which does
// what we want.
@@ -2359,8 +2464,12 @@ void R_CreateBuiltinImages( void ) {
tr.scratchImage[x] = R_CreateImage("*scratch", (byte *)data, DEFAULT_SIZE, DEFAULT_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_PICMIP | IMGFLAG_CLAMPTOEDGE, 0);
}
R_CreateDlightImage();
R_CreateFogImage();
//tr.fogImage = R_FindImageFile( "gfx/engine/fog.tga", 0, IMGFLAG_CLAMPTOEDGE )
//tr.dlightImage = R_FindImageFile( "gfx/engine/dlight.tga", 0, IMGFLAG_CLAMPTOEDGE );
}

View File

@@ -201,6 +201,7 @@ cvar_t *r_retroAA; // Leilei - old console AA
cvar_t *r_anime; // Leilei - anime filter
cvar_t *r_leidebug; // Leilei - debug
cvar_t *r_leidebugeye; // Leilei - eye debug
cvar_t *r_leiwater; // Leilei - water effect test
cvar_t *r_suggestiveThemes; // leilei - mature content control
@@ -212,6 +213,8 @@ cvar_t *r_slowness_cpu; // Leilei
cvar_t *r_slowness_gpu; // Leilei
cvar_t *r_texdump; // Leilei - debug - texture dump as they load, players should never need to use this!
// leilei - fallback shader hack
@@ -1253,6 +1256,8 @@ void R_Register( void )
r_mockvr = ri.Cvar_Get( "r_mockvr", "0" , CVAR_ARCHIVE | CVAR_CHEAT);
r_leifx = ri.Cvar_Get( "r_leifx", "0" , CVAR_ARCHIVE | CVAR_LATCH);
r_leiwater = ri.Cvar_Get( "r_leiwater", "0" , CVAR_ARCHIVE | CVAR_LATCH);
//r_tvMode = ri.Cvar_Get( "r_tvMode", "0" , CVAR_ARCHIVE | CVAR_LATCH);
r_retroAA = ri.Cvar_Get( "r_retroAA", "0" , CVAR_ARCHIVE | CVAR_LATCH);
@@ -1270,6 +1275,9 @@ void R_Register( void )
r_iconmip = ri.Cvar_Get ("r_iconmip", "1", CVAR_ARCHIVE | CVAR_LATCH ); // leilei - icon mip
r_texdump = ri.Cvar_Get( "r_texdump", "0", CVAR_CHEAT ); // leilei - debug - texture dumping
// make sure all the commands added here are also
// removed in R_Shutdown
ri.Cmd_AddCommand( "imagelist", R_ImageList_f );
@@ -1509,6 +1517,7 @@ void R_Init( void ) {
R_BloomInit();
R_PostprocessingInit();
R_AltBrightnessInit(); // leilei - alternate brightness
R_WaterInit(); // leilei - water test
max_polys = r_maxpolys->integer;
if (max_polys < MAX_POLYS)
max_polys = MAX_POLYS;

View File

@@ -148,7 +148,6 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) {
VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin );
for ( i = 0 ; i < 3 ; i++ ) {
float v;
float vA, vB, vC, vD;
v = lightOrigin[i]*tr.world->lightGridInverseSize[i];
@@ -263,17 +262,260 @@ static void R_SetupEntityLightingGrid_crazy( trRefEntity_t *ent ) {
vec3_t direction;
float totalFactor;
// Light 2 stuff
vec3_t lightOriginA;
float lightdist = r_leidebug->value;
int posA[3];
vec3_t directionA;
if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
// seperate lightOrigins are needed so an object that is
// sinking into the ground can still be lit, and so
// multi-part models can be lit identically
VectorCopy( ent->e.lightingOrigin, lightOrigin );
} else {
VectorCopy( ent->e.origin, lightOrigin );
}
VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin );
// Light 1
for ( i = 0 ; i < 3 ; i++ ) {
float v;
v = lightOrigin[i]*tr.world->lightGridInverseSize[i];
pos[i] = floor( v );
frac[i] = v - pos[i];
if ( pos[i] < 0 ) {
pos[i] = 0;
} else if ( pos[i] >= tr.world->lightGridBounds[i] - 1 ) {
pos[i] = tr.world->lightGridBounds[i] - 1;
}
}
VectorClear( ent->ambientLight );
VectorClear( ent->directedLight );
VectorClear( ent->dynamicLight );
VectorClear( direction );
assert( tr.world->lightGridData ); // NULL with -nolight maps
// trilerp the light value
gridStep[0] = 8;
gridStep[1] = 8 * tr.world->lightGridBounds[0];
gridStep[2] = 8 * tr.world->lightGridBounds[0] * tr.world->lightGridBounds[1];
gridData = tr.world->lightGridData + pos[0] * gridStep[0]
+ pos[1] * gridStep[1] + pos[2] * gridStep[2];
totalFactor = 0;
for ( i = 0 ; i < 8 ; i++ ) {
float factor;
byte *data;
int lat, lng;
vec3_t normal;
#if idppc
float d0, d1, d2, d3, d4, d5;
#endif
factor = 1.0;
data = gridData;
for ( j = 0 ; j < 3 ; j++ ) {
if ( i & (1<<j) ) {
factor *= frac[j];
data += gridStep[j];
} else {
factor *= (1.0f - frac[j]);
}
}
if ( !(data[0]+data[1]+data[2]) ) {
continue; // ignore samples in walls
}
totalFactor += factor;
#if idppc
d0 = data[0]; d1 = data[1]; d2 = data[2];
d3 = data[3]; d4 = data[4]; d5 = data[5];
ent->ambientLight[0] += factor * d0;
ent->ambientLight[1] += factor * d1;
ent->ambientLight[2] += factor * d2;
ent->directedLight[0] += factor * d3;
ent->directedLight[1] += factor * d4;
ent->directedLight[2] += factor * d5;
#else
ent->ambientLight[0] += factor * data[0];
ent->ambientLight[1] += factor * data[1];
ent->ambientLight[2] += factor * data[2];
ent->directedLight[0] += factor * data[3];
ent->directedLight[1] += factor * data[4];
ent->directedLight[2] += factor * data[5];
#endif
lat = data[7];
lng = data[6];
lat *= (FUNCTABLE_SIZE/256);
lng *= (FUNCTABLE_SIZE/256);
// decode X as cos( lat ) * sin( long )
// decode Y as sin( lat ) * sin( long )
// decode Z as cos( long )
normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
normal[1] = tr.sinTable[lat] * tr.sinTable[lng];
normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
VectorMA( direction, factor, normal, direction );
}
if ( totalFactor > 0 && totalFactor < 0.99 ) {
totalFactor = 1.0f / totalFactor;
VectorScale( ent->ambientLight, totalFactor, ent->ambientLight );
VectorScale( ent->directedLight, totalFactor, ent->directedLight );
}
VectorScale( ent->ambientLight, r_ambientScale->value, ent->ambientLight );
VectorScale( ent->directedLight, r_directedScale->value, ent->directedLight );
VectorNormalize2( direction, ent->lightDir );
// Light 2
// leilei - lighting hack
//
// Try to sample the lightgrid from four different positions
// so we can add in four more lights to the model
vec3_t dirr;
VectorSubtract( lightOrigin, backEnd.viewParms.or.origin, dirr );
//VectorCopy(backEnd.viewParms.or.orign, dirr);
VectorNormalize( dirr );
// VectorMA( lightOrigin, lightdist, dirr, lightOriginA );
// Reverse the light direction to check
VectorSubtract( ent->lightDir, lightOrigin, dirr );
VectorNormalize( dirr );
lightOriginA[0] = lightOrigin[0] - (dirr[0] * lightdist);
lightOriginA[1] = lightOrigin[1] - (dirr[1] * lightdist);
lightOriginA[2] = lightOrigin[2] - (dirr[2] * lightdist);
// VectorSubtract( lightOriginA, tr.world->lightGridOrigin, lightOriginA );
for ( i = 0 ; i < 3 ; i++ ) {
float v;
v = lightOriginA[i]*tr.world->lightGridInverseSize[i];
posA[i] = floor( v );
frac[i] = v - posA[i];
if ( posA[i] < 0 ) {
posA[i] = 0;
} else if ( posA[i] >= tr.world->lightGridBounds[i] - 1 ) {
posA[i] = tr.world->lightGridBounds[i] - 1;
}
}
VectorClear( ent->directedLightA );
VectorClear( directionA );
assert( tr.world->lightGridData ); // NULL with -nolight maps
// trilerp the light value
gridStep[0] = 8;
gridStep[1] = 8 * tr.world->lightGridBounds[0];
gridStep[2] = 8 * tr.world->lightGridBounds[0] * tr.world->lightGridBounds[1];
gridData = tr.world->lightGridData + posA[0] * gridStep[0]
+ posA[1] * gridStep[1] + posA[2] * gridStep[2];
totalFactor = 0;
for ( i = 0 ; i < 8 ; i++ ) {
float factor;
byte *data;
int lat, lng;
vec3_t normal;
#if idppc
float d0, d1, d2, d3, d4, d5;
#endif
factor = 1.0;
data = gridData;
for ( j = 0 ; j < 3 ; j++ ) {
if ( i & (1<<j) ) {
factor *= frac[j];
data += gridStep[j];
} else {
factor *= (1.0f - frac[j]);
}
}
if ( !(data[0]+data[1]+data[2]) ) {
continue; // ignore samples in walls
}
totalFactor += factor;
#if idppc
d0 = data[0]; d1 = data[1]; d2 = data[2];
d3 = data[3]; d4 = data[4]; d5 = data[5];
ent->directedLightA[0] += factor * d3;
ent->directedLightA[1] += factor * d4;
ent->directedLightA[2] += factor * d5;
#else
ent->directedLightA[0] += factor * data[3];
ent->directedLightA[1] += factor * data[4];
ent->directedLightA[2] += factor * data[5];
#endif
lat = data[7];
lng = data[6];
lat *= (FUNCTABLE_SIZE/256);
lng *= (FUNCTABLE_SIZE/256);
// decode X as cos( lat ) * sin( long )
// decode Y as sin( lat ) * sin( long )
// decode Z as cos( long )
normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
normal[1] = tr.sinTable[lat] * tr.sinTable[lng];
normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
VectorMA( direction, factor, normal, direction );
}
if ( totalFactor > 0 && totalFactor < 0.99 ) {
totalFactor = 1.0f / totalFactor;
VectorScale( ent->directedLightA, totalFactor, ent->directedLightA );
}
VectorScale( ent->directedLightA, r_directedScale->value, ent->directedLightA );
VectorNormalize2( direction, ent->lightDir );
}
static void R_SetupEntityLightingGrid_crazyed( trRefEntity_t *ent ) {
vec3_t lightOrigin;
int pos[3];
int i, j;
byte *gridData;
float frac[3];
int gridStep[3];
vec3_t direction;
float totalFactor;
byte *gridDataA;
float fracA[3];
float fracB[3];
float fracC[3];
float fracD[3];
int posA[3];
int posB[3];
int posC[3];
int posD[3];
vec3_t failed;
int lightdist = 128;
@@ -284,17 +526,10 @@ static void R_SetupEntityLightingGrid_crazy( trRefEntity_t *ent ) {
failed[1] = 666;
failed[2] = 666;
int failA, failB, failC, failD = 0;
int failA = 0;
vec3_t lightOriginA;
vec3_t lightOriginB;
vec3_t lightOriginC;
vec3_t lightOriginD;
vec3_t directionA;
vec3_t directionB;
vec3_t directionC;
vec3_t directionD;
qboolean shadey = qfalse;
//
// leilei - lighting hack
@@ -311,19 +546,7 @@ static void R_SetupEntityLightingGrid_crazy( trRefEntity_t *ent ) {
// lightOriginA[1] = dirr[1] * lightdist;
// lightOriginA[2] = dirr[2] * lightdist;
// Reverse the light direction to check
VectorSubtract( ent->lightDir, lightOrigin, dirr );
VectorNormalize( dirr );
lightOriginA[0] = lightOrigin[0] - (dirr[0] * lightdist);
lightOriginA[1] = lightOrigin[1] - (dirr[1] * lightdist);
lightOriginA[2] = lightOrigin[2] - (dirr[2] * lightdist);
lightOriginB[0] = lightdist;
lightOriginB[1] = lightdist;
lightOriginC[2] = -lightdist;
lightOriginD[2] = lightdist;
if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
@@ -335,20 +558,30 @@ static void R_SetupEntityLightingGrid_crazy( trRefEntity_t *ent ) {
VectorCopy( ent->e.origin, lightOrigin );
}
// Reverse the light direction to check
VectorSubtract( ent->lightDir, lightOrigin, dirr );
VectorNormalize( dirr );
lightOriginA[0] = lightOrigin[0] - (dirr[0] * lightdist);
lightOriginA[1] = lightOrigin[1] - (dirr[1] * lightdist);
lightOriginA[2] = lightOrigin[2] - (dirr[2] * lightdist);
VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin );
VectorSubtract( lightOriginA, tr.world->lightGridOrigin, lightOriginA );
//VectorAdd( lightOrigin, lightOriginA, lightOriginA );
VectorAdd( lightOrigin, lightOriginB, lightOriginB );
VectorAdd( lightOrigin, lightOriginC, lightOriginC );
VectorAdd( lightOrigin, lightOriginD, lightOriginD );
for ( i = 0 ; i < 3 ; i++ ) {
float v;
float vA, vB, vC, vD;
float vA;
v = lightOrigin[i]*tr.world->lightGridInverseSize[i];
@@ -362,37 +595,14 @@ static void R_SetupEntityLightingGrid_crazy( trRefEntity_t *ent ) {
vA = lightOriginA[i]*tr.world->lightGridInverseSize[i];
posA[i] = floor( vA );
posA[i] = ceil( vA );
fracA[i] = vA - posA[i];
if ( posA[i] < 0 ) {
posA[i] = 0;
} else if ( posA[i] >= tr.world->lightGridBounds[i] - 1 ) {
} else if ( posA[i] <= tr.world->lightGridBounds[i] - 1 ) {
posA[i] = tr.world->lightGridBounds[i] - 1;
}
vB = lightOriginB[i]*tr.world->lightGridInverseSize[i];
posB[i] = floor( vB );
fracB[i] = vB - posB[i];
if ( posB[i] < 0 ) {
posB[i] = 0;
} else if ( posB[i] >= tr.world->lightGridBounds[i] - 1 ) {
posB[i] = tr.world->lightGridBounds[i] - 1;
}
vC = lightOriginC[i]*tr.world->lightGridInverseSize[i];
posC[i] = floor( vC );
fracC[i] = vC - posC[i];
if ( posC[i] < 0 ) {
posC[i] = 0;
} else if ( posC[i] >= tr.world->lightGridBounds[i] - 1 ) {
posC[i] = tr.world->lightGridBounds[i] - 1;
}
vD = lightOriginD[i]*tr.world->lightGridInverseSize[i];
posD[i] = floor( vD );
fracD[i] = vD - posD[i];
if ( pos[i] < 0 ) {
posD[i] = 0;
} else if ( posD[i] >= tr.world->lightGridBounds[i] - 1 ) {
posD[i] = tr.world->lightGridBounds[i] - 1;
}
}
@@ -404,6 +614,7 @@ static void R_SetupEntityLightingGrid_crazy( trRefEntity_t *ent ) {
// leilei - lighting hack
VectorClear( directionA );
VectorClear( ent->directedLightA );
@@ -425,9 +636,6 @@ static void R_SetupEntityLightingGrid_crazy( trRefEntity_t *ent ) {
for ( i = 0 ; i < 8 ; i++ ) {
float factor;
float factorA;
float factorB;
float factorC;
float factorD;
byte *data;
byte *dataA;
@@ -438,9 +646,6 @@ static void R_SetupEntityLightingGrid_crazy( trRefEntity_t *ent ) {
#endif
factor = 1.0;
factorA = 1.0;
factorB = 1.0;
factorC = 1.0;
factorD = 1.0;
data = gridData;
dataA = gridDataA;
@@ -448,17 +653,11 @@ static void R_SetupEntityLightingGrid_crazy( trRefEntity_t *ent ) {
if ( i & (1<<j) ) {
factor *= frac[j];
factorA *= fracA[j];
factorB *= fracB[j];
factorC *= fracC[j];
factorD *= fracD[j];
data += gridStep[j];
dataA += gridStep[j];
} else {
factor *= (1.0f - frac[j]);
factorA *= (1.0f - fracA[j]);
factorB *= (1.0f - fracB[j]);
factorC *= (1.0f - fracC[j]);
factorD *= (1.0f - fracD[j]);
}
}
@@ -500,11 +699,7 @@ static void R_SetupEntityLightingGrid_crazy( trRefEntity_t *ent ) {
normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
VectorMA( direction, factor, normal, direction );
VectorMA( directionA, factorA, normal, directionA );
VectorMA( directionB, factorB, normal, directionB );
VectorMA( directionC, factorC, normal, directionC );
VectorMA( directionD, factorD, normal, directionD );
}
if ( totalFactor > 0 && totalFactor < 0.99 ) {
@@ -518,10 +713,9 @@ static void R_SetupEntityLightingGrid_crazy( trRefEntity_t *ent ) {
VectorScale( ent->ambientLight, r_ambientScale->value, ent->ambientLight );
VectorScale( ent->directedLight, r_directedScale->value, ent->directedLight );
VectorScale( ent->directedLightA, r_directedScale->value, ent->directedLightA );
VectorNormalize2( direction, ent->lightDir );
VectorNormalize2( directionA, ent->lightDirA );

View File

@@ -437,7 +437,6 @@ typedef struct {
int numDrawSurfs;
struct drawSurf_s *drawSurfs;
} trRefdef_t;
@@ -1027,6 +1026,7 @@ typedef struct {
qboolean doneSun; // leilei - done drawing a sun
qboolean doneSunFlare; // leilei - done drawing a sun flare
qboolean donemblur; // leilei - done motionblur this frame
qboolean donewater; // leilei - done water this frame
qboolean donetv; // leilei - tv this frame
qboolean doneraa; // leilei - done aa'ing this frame
qboolean doneSurfaces; // done any 3d surfaces already
@@ -1061,6 +1061,7 @@ typedef struct {
image_t *scratchImage[32];
image_t *fogImage;
image_t *dlightImage; // inverse-quare highlight for projective adding
image_t *waterImage;
image_t *flareImage;
image_t *whiteImage; // full of 0xff
image_t *identityLightImage; // full of tr.identityLightByte
@@ -1155,6 +1156,7 @@ typedef struct {
qboolean placeholderTextureAvail;
qboolean placeholderModelAvail;
qboolean placeholderAvail;
} trGlobals_t;
extern backEndState_t backEnd;
@@ -1293,6 +1295,7 @@ extern cvar_t *r_flaresDlight;
extern cvar_t *r_alternateBrightness; // leilei - alternate brightness
extern cvar_t *r_leifx; // Leilei - leifx nostalgia filter
extern cvar_t *r_leiwater; // Leilei - water test
extern cvar_t *r_tvMode; // Leilei - tv faking mode
@@ -1309,6 +1312,8 @@ extern cvar_t *r_leidebugeye; // Leilei - debug only!
extern cvar_t *r_iconmip; // leilei - icon mip - picmip for 2d icons
extern cvar_t *r_texdump; // leilei - texture dumping
//====================================================================
void R_SwapBuffers( int );
@@ -1995,6 +2000,7 @@ void RB_DeformTessGeometry( void );
void RB_CalcEnvironmentTexCoords( float *dstTexCoords );
void RB_CalcCelTexCoords( float *dstTexCoords ); // leilei - cel hack
void RB_CalcEnvironmentTexCoordsJO( float *dstTexCoords ); // leilei
void RB_CalcEnvironmentTexCoordsR( float *dstTexCoords ); // leilei
void RB_CalcEyes( float *st, qboolean theothereye); // leilei - eyes
void RB_CalcEnvironmentCelShadeTexCoords( float *dstTexCoords );
void RB_CalcEnvironmentTexCoordsNew( float *dstTexCoords );
@@ -2183,7 +2189,9 @@ void RE_TakeVideoFrame( int width, int height,
//Bloom Stuff
void R_BloomInit( void );
void R_WaterInit( void );
void R_BloomScreen( void );
void R_WaterScreen( void );
void R_AnimeScreen( void );
// Postprocessing

View File

@@ -1379,6 +1379,7 @@ void R_RenderView (viewParms_t *parms) {
R_GenerateDrawSurfs();
R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, tr.refdef.numDrawSurfs - firstDrawSurf );
// draw main system development information (surface outlines, etc)

View File

@@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
static qboolean R_LoadMD3(model_t *mod, int lod, void *buffer, const char *name );
static qboolean R_LoadMDR(model_t *mod, void *buffer, int filesize, const char *name );
extern int ismaptexture; // leilei - for listing map textures
/*
====================
R_RegisterMD3
@@ -507,7 +507,7 @@ static qboolean R_LoadMD3 (model_t *mod, int lod, void *buffer, const char *mod_
shader = (md3Shader_t *) ( (byte *)surf + surf->ofsShaders );
for ( j = 0 ; j < surf->numShaders ; j++, shader++ ) {
shader_t *sh;
ismaptexture = 0;
sh = R_FindShader( shader->name, LIGHTMAP_NONE, qtrue );
if ( sh->defaultShader ) {
shader->shaderIndex = 0;
@@ -773,6 +773,7 @@ static qboolean R_LoadMDR( model_t *mod, void *buffer, int filesize, const char
Q_strlwr( surf->name );
// register the shaders
ismaptexture = 0;
sh = R_FindShader(surf->shader, LIGHTMAP_NONE, qtrue);
if ( sh->defaultShader ) {
surf->shaderIndex = 0;

View File

@@ -31,7 +31,7 @@ static float identityMatrix[12] = {
0, 1, 0, 0,
0, 0, 1, 0
};
extern int ismaptexture; // leilei - for listing map textures
static qboolean IQM_CheckRange( iqmHeader_t *header, int offset,
int count,int size ) {
// return true if the range specified by offset, count and size
@@ -622,6 +622,7 @@ qboolean R_LoadIQM( model_t *mod, void *buffer, int filesize, const char *mod_na
surface->surfaceType = SF_IQM;
Q_strncpyz(surface->name, str + mesh->name, sizeof (surface->name));
Q_strlwr(surface->name); // lowercase the surface name so skin compares are faster
ismaptexture = 0;
surface->shader = R_FindShader( str + mesh->material, LIGHTMAP_NONE, qtrue );
if( surface->shader->defaultShader )
surface->shader = tr.defaultShader;

View File

@@ -1151,7 +1151,10 @@ static void ComputeTexCoords( shaderStage_t *pStage ) {
} // new dancing one
else if ( r_envMode->integer == 2 ) {
RB_CalcEnvironmentTexCoordsJO( ( float * ) tess.svars.texcoords[b] );
} // odin's
} // JO's
else if ( r_envMode->integer == 3 ) {
RB_CalcEnvironmentTexCoordsR( ( float * ) tess.svars.texcoords[b] );
} // Q3R's
else {
RB_CalcEnvironmentTexCoords( ( float * ) tess.svars.texcoords[b] );
} // old one

View File

@@ -235,6 +235,33 @@ void RB_CalcDeformNormals( deformStage_t *ds ) {
}
}
void RB_CalcDeformNormalsEvenMore( deformStage_t *ds ) {
int i;
float scale;
float *xyz = ( float * ) tess.xyz;
float *normal = ( float * ) tess.normal;
for ( i = 0; i < tess.numVertexes; i++, xyz += 4, normal += 4 ) {
scale = 5.98f;
scale = R_NoiseGet4f( xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
tess.shaderTime * ds->deformationWave.frequency );
normal[ 0 ] += ds->deformationWave.amplitude * scale;
scale = 5.98f;
scale = R_NoiseGet4f( 100 + xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
tess.shaderTime * ds->deformationWave.frequency );
normal[ 1 ] += ds->deformationWave.amplitude * scale;
scale = 5.98f;
scale = R_NoiseGet4f( 200 + xyz[0] * scale, xyz[1] * scale, xyz[2] * scale,
tess.shaderTime * ds->deformationWave.frequency );
normal[ 2 ] += ds->deformationWave.amplitude * scale;
VectorNormalizeFast( normal );
}
}
/*
========================
RB_CalcBulgeVertexes
@@ -1067,8 +1094,57 @@ void RB_CalcEnvironmentTexCoordsJO( float *st )
}
}
/*
** RB_CalcEnvironmentTexCoordsR
Inpsired by Revolution, reflect from the sun light position instead
*/
void RB_CalcEnvironmentTexCoordsR( float *st )
{
int i;
float *v, *normal;
vec3_t viewer, reflected, sunned;
float d;
vec3_t sundy;
float size;
float dist;
vec3_t origin, vec1, vec2;
v = tess.xyz[0];
normal = tess.normal[0];
dist = backEnd.viewParms.zFar / 1.75; // div sqrt(3)
size = dist * 0.4;
VectorScale( tr.sunDirection, dist, sundy);
PerpendicularVector( vec1, tr.sunDirection );
CrossProduct( tr.sunDirection, vec1, vec2 );
VectorScale( vec1, size, vec1 );
VectorScale( vec2, size, vec2 );
v = tess.xyz[0];
normal = tess.normal[0];
for (i = 0 ; i < tess.numVertexes ; i++, v += 4, normal += 4, st += 2 )
{
VectorSubtract (backEnd.or.viewOrigin, v, viewer);
VectorNormalizeFast (viewer);
VectorSubtract (sundy, v, sunned);
VectorNormalizeFast (sunned);
d = DotProduct (normal, viewer) + DotProduct (viewer, sunned);
reflected[0] = normal[0]*2*d - viewer[0];
reflected[1] = normal[1]*2*d - viewer[1];
reflected[2] = normal[2]*2*d - viewer[2];
st[0] = 0.5 + reflected[1] * 0.5;
st[1] = 0.5 - reflected[2] * 0.5;
}
}
/*
** RB_CalcCelTexCoords
@@ -1499,6 +1575,71 @@ static void RB_CalcDiffuseColor_scalar( unsigned char *colors )
// leilei - use FIVE (!) lighting points. Very expensive!
static void RB_CalcDiffuseColor_crazy( unsigned char *colors )
{
int i, j, k;
float *v, *normal;
float incoming, incomingA;
trRefEntity_t *ent;
int ambientLightInt;
vec3_t ambientLight;
vec3_t lightDir, lightDirA;
vec3_t directedLight, directedLightA;
int numVertexes;
ent = backEnd.currentEntity;
ambientLightInt = ent->ambientLightInt;
VectorCopy( ent->ambientLight, ambientLight );
VectorCopy( ent->directedLight, directedLight );
VectorCopy( ent->directedLightA, directedLightA );
VectorCopy( ent->lightDir, lightDir );
VectorCopy( ent->lightDirA, lightDirA );
ambientLight[0] *= 0.5f;
ambientLight[1] *= 0.5f;
ambientLight[2] *= 0.5f;
v = tess.xyz[0];
normal = tess.normal[0];
numVertexes = tess.numVertexes;
for (i = 0 ; i < numVertexes ; i++, v += 4, normal += 4) {
incoming = DotProduct (normal, lightDir);
incomingA = DotProduct (normal, lightDirA);
if ( incoming <= 0 ) {
*(int *)&colors[i*4] = ambientLightInt;
continue;
}
j = ri.ftol(ambientLight[0] + incoming * directedLight[0]);
k = ri.ftol(ambientLight[0] + incomingA * directedLightA[0]);
j += k;
if ( j > 255 ) {
j = 255;
}
colors[i*4+0] = j;
j = ri.ftol(ambientLight[1] + incoming * directedLight[1]);
k = ri.ftol(ambientLight[1] + incomingA * directedLightA[1]);
j += k;
if ( j > 255 ) {
j = 255;
}
colors[i*4+1] = j;
j = ri.ftol(ambientLight[2] + incoming * directedLight[2]);
k = ri.ftol(ambientLight[2] + incomingA * directedLightA[2]);
j += k;
if ( j > 255 ) {
j = 255;
}
colors[i*4+2] = j;
colors[i*4+3] = 255;
}
}
/*
static void RB_CalcDiffuseColor_crafzy( unsigned char *colors )
{
int i, j, jA;
float *v, *normal;
@@ -1596,7 +1737,7 @@ static void RB_CalcDiffuseColor_crazy( unsigned char *colors )
}
}
*/
// leilei - some slower, but bolder way of lighting
// i sure hope gcc unrolls this.

View File

@@ -1185,6 +1185,14 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
stage->bundle[0].image[0] = tr.whiteImage;
continue;
}
if ( !Q_stricmp( token, "$waterimage" ) )
{
stage->bundle[0].image[0] = tr.waterImage;
imgType_t type = IMGTYPE_COLORALPHA;
imgFlags_t flags = IMGFLAG_NONE;
continue;
}
else if ( !Q_stricmp( token, "$lightmap" ) )
{
stage->bundle[0].isLightmap = qtrue;
@@ -1232,6 +1240,11 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
stage->bundle[2].image[0] = tr.whiteImage;
continue;
}
if ( !Q_stricmp( token, "$waterimage" ) )
{
stage->bundle[2].image[0] = tr.waterImage;
continue;
}
else if ( !Q_stricmp( token, "$lightmap" ) )
{
stage->bundle[2].isLightmap = qtrue;
@@ -1279,6 +1292,11 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
stage->bundle[3].image[0] = tr.whiteImage;
continue;
}
if ( !Q_stricmp( token, "$waterimage" ) )
{
stage->bundle[3].image[0] = tr.waterImage;
continue;
}
else if ( !Q_stricmp( token, "$lightmap" ) )
{
stage->bundle[3].isLightmap = qtrue;
@@ -1326,6 +1344,11 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
stage->bundle[4].image[0] = tr.whiteImage;
continue;
}
if ( !Q_stricmp( token, "$waterimage" ) )
{
stage->bundle[4].image[0] = tr.waterImage;
continue;
}
else if ( !Q_stricmp( token, "$lightmap" ) )
{
stage->bundle[4].isLightmap = qtrue;
@@ -1373,6 +1396,11 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
stage->bundle[5].image[0] = tr.whiteImage;
continue;
}
if ( !Q_stricmp( token, "$waterimage" ) )
{
stage->bundle[5].image[0] = tr.waterImage;
continue;
}
else if ( !Q_stricmp( token, "$lightmap" ) )
{
stage->bundle[5].isLightmap = qtrue;
@@ -1420,6 +1448,11 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
stage->bundle[6].image[0] = tr.whiteImage;
continue;
}
if ( !Q_stricmp( token, "$waterimage" ) )
{
stage->bundle[6].image[0] = tr.waterImage;
continue;
}
else if ( !Q_stricmp( token, "$lightmap" ) )
{
stage->bundle[6].isLightmap = qtrue;
@@ -1467,6 +1500,11 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
stage->bundle[7].image[0] = tr.whiteImage;
continue;
}
if ( !Q_stricmp( token, "$waterimage" ) )
{
stage->bundle[7].image[0] = tr.waterImage;
continue;
}
else if ( !Q_stricmp( token, "$lightmap" ) )
{
stage->bundle[7].isLightmap = qtrue;

View File

@@ -145,6 +145,7 @@ typedef struct {
// text messages for deform text shaders
char text[MAX_RENDER_STRINGS][MAX_RENDER_STRING_LENGTH];
} refdef_t;
@@ -220,6 +221,7 @@ typedef struct {
qboolean isFullscreen;
qboolean stereoEnabled;
qboolean smpActive; // UNUSED, present for compatibility
} glconfig_t;
#endif // __TR_TYPES_H