vbos-glsl patch version 18

This commit is contained in:
Richard Allen 2011-07-20 19:17:44 +00:00
parent 9fc3c6a1eb
commit f385aa2807
11 changed files with 1552 additions and 876 deletions

View File

@ -120,6 +120,39 @@ ADD_ALL_EXTENSION_FUNCTIONS
#undef HANDLE_EXT_FUNC
// GL_ARB_texture_compression
extern void (APIENTRY * qglCompressedTexImage3DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
extern void (APIENTRY * qglCompressedTexImage2DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
GLint border, GLsizei imageSize, const GLvoid *data);
extern void (APIENTRY * qglCompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border,
GLsizei imageSize, const GLvoid *data);
extern void (APIENTRY * qglCompressedTexSubImage3DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
extern void (APIENTRY * qglCompressedTexSubImage2DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
extern void (APIENTRY * qglCompressedTexSubImage1DARB)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format,
GLsizei imageSize, const GLvoid *data);
extern void (APIENTRY * qglGetCompressedTexImageARB)(GLenum target, GLint lod,
GLvoid *img);
// GL_NVX_gpu_memory_info
#ifndef GL_NVX_gpu_memory_info
#define GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
#define GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
#define GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
#define GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
#define GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
#endif
// GL_ATI_meminfo
#ifndef GL_ATI_meminfo
#define VBO_FREE_MEMORY_ATI 0x87FB
#define TEXTURE_FREE_MEMORY_ATI 0x87FC
#define RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
#endif
#if defined(WIN32)
// WGL_ARB_create_context
#ifndef WGL_ARB_create_context

View File

@ -40,7 +40,7 @@ int c_subdivisions;
int c_gridVerts;
//===============================================================================
#if 1
static void HSVtoRGB( float h, float s, float v, float rgb[3] )
{
int i;
@ -168,14 +168,19 @@ R_LoadLightmaps
*/
#define LIGHTMAP_SIZE 128
static void R_LoadLightmaps( lump_t *l ) {
#if 0
byte *buf, *buf_p;
int len;
byte image[LIGHTMAP_SIZE*LIGHTMAP_SIZE*4];
int i, j;
int i, j, numLightmaps;
float maxIntensity = 0;
double sumIntensity = 0;
if (r_mergeLightmaps->integer)
{
tr.fatLightmapSize = 4096;
tr.fatLightmapStep = 32;
}
len = l->filelen;
if ( !len ) {
return;
@ -186,23 +191,90 @@ static void R_LoadLightmaps( lump_t *l ) {
R_SyncRenderThread();
// create all the lightmaps
tr.numLightmaps = len / (LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3);
if ( tr.numLightmaps == 1 ) {
//FIXME: HACK: maps with only one lightmap turn up fullbright for some reason.
//this avoids this, but isn't the correct solution.
tr.numLightmaps++;
numLightmaps = len / (LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3);
if (tr.worldDeluxeMapping)
{
numLightmaps >>= 1;
}
// if we are in r_vertexLight mode, we don't need the lightmaps at all
if ( r_vertexLight->integer || glConfig.hardwareType == GLHW_PERMEDIA2 ) {
return;
if(numLightmaps == 1)
{
//FIXME: HACK: maps with only one lightmap turn up fullbright for some reason.
//this avoids this, but isn't the correct solution.
numLightmaps++;
}
else if (r_mergeLightmaps->integer && numLightmaps >= tr.fatLightmapStep * tr.fatLightmapStep )
{
// FIXME: fat light maps don't support more than 1024 light maps
ri.Printf(PRINT_WARNING, "WARNING: number of lightmaps > %d\n", tr.fatLightmapStep * tr.fatLightmapStep);
numLightmaps = tr.fatLightmapStep * tr.fatLightmapStep;
}
// use a fat lightmap of an appropriate size
if (r_mergeLightmaps->integer)
{
if(numLightmaps < 65)
{
tr.fatLightmapSize = 1024;
tr.fatLightmapStep = 8;
}
else if(numLightmaps < 256)
{
tr.fatLightmapSize = 2048;
tr.fatLightmapStep = 16;
}
// allocate one fat lightmap
tr.numLightmaps = 1;
}
else
{
tr.numLightmaps = numLightmaps;
}
tr.lightmaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
for ( i = 0 ; i < tr.numLightmaps ; i++ ) {
// expand the 24 bit on-disk to 32 bit
buf_p = buf + i * LIGHTMAP_SIZE*LIGHTMAP_SIZE * 3;
if (tr.worldDeluxeMapping || r_deluxeMapping->integer == 2)
{
tr.deluxemaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
}
if (r_mergeLightmaps->integer)
{
tr.fatLightmap = R_CreateImage(va("_fatlightmap%d", 0), NULL, tr.fatLightmapSize, tr.fatLightmapSize, qfalse, qfalse, GL_CLAMP_TO_EDGE );
tr.lightmaps[0] = tr.fatLightmap;
if (tr.worldDeluxeMapping || r_deluxeMapping->integer == 2)
{
tr.fatDeluxemap = R_CreateImage(va("_fatdeluxemap%d", 0), NULL, tr.fatLightmapSize, tr.fatLightmapSize, qfalse, qfalse, GL_CLAMP_TO_EDGE );
tr.deluxemaps[0] = tr.fatDeluxemap;
}
}
for(i = 0; i < numLightmaps; i++)
{
int xoff = 0, yoff = 0;
// expand the 24 bit on-disk to 32 bit
if (tr.worldDeluxeMapping)
{
buf_p = buf + (i * 2) * LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3;
}
else
{
buf_p = buf + i * LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3;
}
if (r_mergeLightmaps->integer)
{
xoff = (i % tr.fatLightmapStep) * LIGHTMAP_SIZE;
yoff = (i / tr.fatLightmapStep) * LIGHTMAP_SIZE;
}
// if (tr.worldLightmapping)
{
if ( r_lightmap->integer == 2 )
{ // color code by intensity as development tool (FIXME: check range)
for ( j = 0; j < LIGHTMAP_SIZE * LIGHTMAP_SIZE; j++ )
@ -238,120 +310,14 @@ static void R_LoadLightmaps( lump_t *l ) {
image[j*4+3] = 255;
}
}
tr.lightmaps[i] = R_CreateImage( va("*lightmap%d",i), image,
LIGHTMAP_SIZE, LIGHTMAP_SIZE, qfalse, qfalse, GL_CLAMP_TO_EDGE );
}
if ( r_lightmap->integer == 2 ) {
ri.Printf( PRINT_ALL, "Brightest lightmap value: %d\n", ( int ) ( maxIntensity * 255 ) );
}
#else
int len;
int numLightmaps;
int i;
byte *buf, *buf_p;
//int BIGSIZE=2048;
//int BIGNUM=16;
byte *fatbuffer;
byte *fatbuffer2;
int xoff, yoff, x, y;
//float scale = 0.9f;
tr.fatLightmapSize = 4096;
tr.fatLightmapStep = 32;
len = l->filelen;
if(!len)
if (r_mergeLightmaps->integer)
{
return;
}
buf = fileBase + l->fileofs;
// we are about to upload textures
R_SyncRenderThread();
// create all the lightmaps
numLightmaps = len / (LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3);
if (tr.worldDeluxeMapping)
{
numLightmaps >>= 1;
}
if(numLightmaps == 1)
{
//FIXME: HACK: maps with only one lightmap turn up fullbright for some reason.
//this avoids this, but isn't the correct solution.
numLightmaps++;
}
else if(numLightmaps >= tr.fatLightmapStep * tr.fatLightmapStep )
{
// FIXME: fat light maps don't support more than 1024 light maps
ri.Printf(PRINT_WARNING, "WARNING: number of lightmaps > %d\n", tr.fatLightmapStep * tr.fatLightmapStep);
numLightmaps = tr.fatLightmapStep * tr.fatLightmapStep;
}
// use a fat lightmap of an appropriate size
if(numLightmaps < 65)
{
tr.fatLightmapSize = 1024;
tr.fatLightmapStep = 8;
}
else if(numLightmaps < 256)
{
tr.fatLightmapSize = 2048;
tr.fatLightmapStep = 16;
}
// allocate one fat lightmap
tr.numLightmaps = 1;
tr.lightmaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
// This is going to be huge (4, 16, or 64MB), so don't use ri.Malloc()
fatbuffer = ri.Hunk_AllocateTempMemory(sizeof(byte) * tr.fatLightmapSize * tr.fatLightmapSize * 4);
Com_Memset(fatbuffer, 128, tr.fatLightmapSize * tr.fatLightmapSize * 4);
if (tr.worldDeluxeMapping)
{
tr.deluxemaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
fatbuffer2 = ri.Hunk_AllocateTempMemory(sizeof(byte) * tr.fatLightmapSize * tr.fatLightmapSize * 4);
Com_Memset(fatbuffer2, 128, tr.fatLightmapSize * tr.fatLightmapSize * 4);
}
for(i = 0; i < numLightmaps; i++)
{
// expand the 24 bit on-disk to 32 bit
if (tr.worldDeluxeMapping)
{
buf_p = buf + (i * 2) * LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3;
R_UpdateSubImage(tr.fatLightmap, image, xoff, yoff, LIGHTMAP_SIZE, LIGHTMAP_SIZE);
}
else
{
buf_p = buf + i * LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3;
}
xoff = i % tr.fatLightmapStep;
yoff = i / tr.fatLightmapStep;
// if (tr.worldLightmapping)
{
for(y = 0; y < LIGHTMAP_SIZE; y++)
{
for(x = 0; x < LIGHTMAP_SIZE; x++)
{
int index =
(x + (y * tr.fatLightmapSize)) + ((xoff * LIGHTMAP_SIZE) + (yoff * tr.fatLightmapSize * LIGHTMAP_SIZE));
fatbuffer[(index * 4) + 0] = buf_p[((x + (y * LIGHTMAP_SIZE)) * 3) + 0];
fatbuffer[(index * 4) + 1] = buf_p[((x + (y * LIGHTMAP_SIZE)) * 3) + 1];
fatbuffer[(index * 4) + 2] = buf_p[((x + (y * LIGHTMAP_SIZE)) * 3) + 2];
fatbuffer[(index * 4) + 3] = 255;
R_ColorShiftLightingBytes(&fatbuffer[(index * 4) + 0], &fatbuffer[(index * 4) + 0]);
}
tr.lightmaps[i] = R_CreateImage( va("*lightmap%d",i), image, LIGHTMAP_SIZE, LIGHTMAP_SIZE, qfalse, qfalse, GL_CLAMP_TO_EDGE );
}
}
@ -359,34 +325,120 @@ static void R_LoadLightmaps( lump_t *l ) {
{
buf_p = buf + (i * 2 + 1) * LIGHTMAP_SIZE * LIGHTMAP_SIZE * 3;
for(y = 0; y < LIGHTMAP_SIZE; y++)
for ( j = 0 ; j < LIGHTMAP_SIZE * LIGHTMAP_SIZE; j++ ) {
image[j*4+0] = buf_p[j*3+0];
image[j*4+1] = buf_p[j*3+1];
image[j*4+2] = buf_p[j*3+2];
image[j*4+3] = 255;
}
if (r_mergeLightmaps->integer)
{
for(x = 0; x < LIGHTMAP_SIZE; x++)
R_UpdateSubImage(tr.fatDeluxemap, image, xoff, yoff, LIGHTMAP_SIZE, LIGHTMAP_SIZE);
}
else
{
int index =
(x + (y * tr.fatLightmapSize)) + ((xoff * LIGHTMAP_SIZE) + (yoff * tr.fatLightmapSize * LIGHTMAP_SIZE));
fatbuffer2[(index * 4) + 0] = buf_p[((x + (y * LIGHTMAP_SIZE)) * 3) + 0];
fatbuffer2[(index * 4) + 1] = buf_p[((x + (y * LIGHTMAP_SIZE)) * 3) + 1];
fatbuffer2[(index * 4) + 2] = buf_p[((x + (y * LIGHTMAP_SIZE)) * 3) + 2];
fatbuffer2[(index * 4) + 3] = 255;
tr.deluxemaps[i] = R_CreateImage( va("*deluxemap%d",i), image, LIGHTMAP_SIZE, LIGHTMAP_SIZE, qfalse, qfalse, GL_CLAMP_TO_EDGE );
}
}
}
}
tr.fatLightmap = R_CreateImage(va("_fatlightmap%d", 0), fatbuffer, tr.fatLightmapSize, tr.fatLightmapSize, qfalse, qfalse, GL_CLAMP_TO_EDGE );
tr.lightmaps[0] = tr.fatLightmap;
ri.Hunk_FreeTempMemory(fatbuffer);
if (tr.worldDeluxeMapping)
else if ( r_deluxeMapping->integer == 2 )
{
tr.fatDeluxemap = R_CreateImage(va("_fatdeluxemap%d", 0), fatbuffer2, tr.fatLightmapSize, tr.fatLightmapSize, qfalse, qfalse, GL_CLAMP_TO_EDGE );
tr.deluxemaps[0] = tr.fatDeluxemap;
// approximate a deluxe map using magic.
for ( j = 0 ; j < LIGHTMAP_SIZE * LIGHTMAP_SIZE; j++ ) {
int x, y, dx, dy, dz, count, value;
ri.Hunk_FreeTempMemory(fatbuffer2);
x = j % LIGHTMAP_SIZE;
y = j / LIGHTMAP_SIZE;
value = buf_p[j*3+0] + buf_p[j*3+1] + buf_p[j*3+2];
dx = 0;
count = 0;
if (x > 0)
{
int k = j - 1;
dx += value - buf_p[k*3+0] + buf_p[k*3+1] + buf_p[k*3+2];
count++;
}
if (x < LIGHTMAP_SIZE - 1)
{
int k = j + 1;
dx += buf_p[k*3+0] + buf_p[k*3+1] + buf_p[k*3+2] - value;
count++;
}
if (count)
{
dx /= count;
}
dy = 0;
count = 0;
if (y > 0)
{
int k = j - LIGHTMAP_SIZE;
dy += value - (buf_p[k*3+0] + buf_p[k*3+1] + buf_p[k*3+2]);
count++;
}
if (y < LIGHTMAP_SIZE - 1)
{
int k = j + LIGHTMAP_SIZE;
dy += buf_p[k*3+0] + buf_p[k*3+1] + buf_p[k*3+2] - value;
count++;
}
if (count)
{
dy /= count;
}
dx /= 3;
dy /= 3;
if (dx < -255)
dx = -255;
if (dx > 255)
dx = 255;
if (dy < -255)
dy = -255;
if (dy > 255)
dy = 255;
dz = sqrt(255*255 - dx*dx - dy*dy);
dx = dx / 2 + 127;
dy = dy / 2 + 127;
dz = dz / 2 + 127;
image[j*4+0] = dx;
image[j*4+1] = dy;
image[j*4+2] = dz;
image[j*4+3] = 255;
}
if (r_mergeLightmaps->integer)
{
R_UpdateSubImage(tr.fatDeluxemap, image, xoff, yoff, LIGHTMAP_SIZE, LIGHTMAP_SIZE);
}
else
{
tr.deluxemaps[i] = R_CreateImage( va("*deluxemap%d",i), image, LIGHTMAP_SIZE, LIGHTMAP_SIZE, qfalse, qfalse, GL_CLAMP_TO_EDGE );
}
}
}
if ( r_lightmap->integer == 2 ) {
ri.Printf( PRINT_ALL, "Brightest lightmap value: %d\n", ( int ) ( maxIntensity * 255 ) );
}
#endif
}
@ -416,15 +468,18 @@ static float FatPackV(float input, int lightmapnum)
static int FatLightmap(int lightmapnum)
{
if (tr.fatLightmapSize > 0)
{
if (lightmapnum < 0)
return lightmapnum;
if (tr.fatLightmapSize > 0)
{
return 0;
}
if (tr.worldDeluxeMapping)
return lightmapnum >> 1;
return lightmapnum;
}
@ -909,7 +964,6 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, msurface_t *surf, i
}
#endif
}
#endif
#if 1
/*

File diff suppressed because it is too large Load Diff

View File

@ -679,6 +679,10 @@ static void Upload32( unsigned *data,
}
else
{
if ( glConfig.textureCompression == TC_S3TC_ARB )
{
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
}
if ( r_texturebits->integer == 16 )
{
internalFormat = GL_RGBA4;
@ -785,6 +789,155 @@ done:
ri.Hunk_FreeTempMemory( resampledBuffer );
}
static void EmptyTexture( int width, int height, qboolean mipmap,
qboolean picmip, qboolean lightMap, int *format, int *pUploadWidth,
int *pUploadHeight )
{
int samples;
int scaled_width, scaled_height;
GLenum internalFormat = GL_RGB;
//
// convert to exact power of 2 sizes
//
for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
;
for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
;
if ( r_roundImagesDown->integer && scaled_width > width )
scaled_width >>= 1;
if ( r_roundImagesDown->integer && scaled_height > height )
scaled_height >>= 1;
if ( scaled_width != width || scaled_height != height ) {
width = scaled_width;
height = scaled_height;
}
//
// perform optional picmip operation
//
if ( picmip ) {
scaled_width >>= r_picmip->integer;
scaled_height >>= r_picmip->integer;
}
//
// clamp to minimum size
//
if (scaled_width < 1) {
scaled_width = 1;
}
if (scaled_height < 1) {
scaled_height = 1;
}
//
// clamp to the current upper OpenGL limit
// scale both axis down equally so we don't have to
// deal with a half mip resampling
//
while ( scaled_width > glConfig.maxTextureSize
|| scaled_height > glConfig.maxTextureSize ) {
scaled_width >>= 1;
scaled_height >>= 1;
}
//
// scan the texture for each channel's max values
// and verify if the alpha channel is being used or not
//
samples = 3;
if(lightMap)
{
if(r_greyscale->integer)
internalFormat = GL_LUMINANCE;
else
internalFormat = GL_RGB;
}
else
{
samples = 4;
if(r_greyscale->integer)
{
if(r_texturebits->integer == 16)
internalFormat = GL_LUMINANCE8_ALPHA8;
else if(r_texturebits->integer == 32)
internalFormat = GL_LUMINANCE16_ALPHA16;
else
internalFormat = GL_LUMINANCE_ALPHA;
}
else
{
if ( glConfig.textureCompression == TC_S3TC_ARB )
{
internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
}
if ( r_texturebits->integer == 16 )
{
internalFormat = GL_RGBA4;
}
else if ( r_texturebits->integer == 32 )
{
internalFormat = GL_RGBA8;
}
else
{
internalFormat = GL_RGBA;
}
}
}
*pUploadWidth = scaled_width;
*pUploadHeight = scaled_height;
*format = internalFormat;
qglTexImage2D (GL_TEXTURE_2D, 0, internalFormat, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
if (mipmap)
{
int miplevel;
miplevel = 0;
while (scaled_width > 1 || scaled_height > 1)
{
scaled_width >>= 1;
scaled_height >>= 1;
if (scaled_width < 1)
scaled_width = 1;
if (scaled_height < 1)
scaled_height = 1;
miplevel++;
qglTexImage2D (GL_TEXTURE_2D, miplevel, internalFormat, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
}
}
if (mipmap)
{
if ( glRefConfig.textureFilterAnisotropic )
qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
(GLint)Com_Clamp( 1, glRefConfig.maxAnisotropy, r_ext_max_anisotropy->integer ) );
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
else
{
if ( glRefConfig.textureFilterAnisotropic )
qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 );
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
}
GL_CheckErrors();
}
static image_t *R_AllocImage(const char* name, int width, int height, qboolean mipmap, qboolean allowPicmip, int glWrapClampMode)
{
image_t *image;
@ -874,23 +1027,28 @@ image_t *R_CreateImage2( const char *name, const byte *pic, int width, int heigh
{
GL_Bind(image);
Upload32( (unsigned *)pic, image->width, image->height,
image->mipmap,
allowPicmip,
isLightmap,
&image->internalFormat,
&image->uploadWidth,
if (pic)
{
Upload32( (unsigned *)pic, image->width, image->height, image->mipmap,
allowPicmip, isLightmap, &image->internalFormat, &image->uploadWidth,
&image->uploadHeight );
}
else
{
EmptyTexture(image->width, image->height, image->mipmap, allowPicmip,
isLightmap, &image->internalFormat, &image->uploadWidth,
&image->uploadHeight );
}
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode );
}
qglBindTexture( GL_TEXTURE_2D, 0 );
if ( image->TMU == 1 ) {
GL_SelectTexture( 0 );
}
hash = generateHashValue(name);
image->next = hashTable[hash];
hashTable[hash] = image;
return image;
}
@ -907,6 +1065,149 @@ image_t *R_CreateCubeImage( const char *name, const byte *pic, int width, int he
return R_CreateImage2( name, pic, width, height, mipmap, allowPicmip, glWrapClampMode, qtrue);
}
void R_UpdateSubImage( image_t *image, const byte *pic, int x, int y, int width, int height)
{
unsigned *scaledBuffer = NULL;
unsigned *resampledBuffer = NULL;
int scaled_width, scaled_height, scaled_x, scaled_y;
unsigned *data = (unsigned *)pic;
//
// convert to exact power of 2 sizes
//
for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
;
for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
;
if ( r_roundImagesDown->integer && scaled_width > width )
scaled_width >>= 1;
if ( r_roundImagesDown->integer && scaled_height > height )
scaled_height >>= 1;
if ( scaled_width != width || scaled_height != height ) {
resampledBuffer = ri.Hunk_AllocateTempMemory( scaled_width * scaled_height * 4 );
ResampleTexture ( data, width, height, resampledBuffer, scaled_width, scaled_height);
data = resampledBuffer;
x = x * scaled_width / width;
y = y * scaled_height / height;
width = scaled_width;
height = scaled_height;
}
//
// perform optional picmip operation
//
if ( image->allowPicmip ) {
scaled_width >>= r_picmip->integer;
scaled_height >>= r_picmip->integer;
}
//
// clamp to minimum size
//
if (scaled_width < 1) {
scaled_width = 1;
}
if (scaled_height < 1) {
scaled_height = 1;
}
//
// clamp to the current upper OpenGL limit
// scale both axis down equally so we don't have to
// deal with a half mip resampling
//
while ( scaled_width > glConfig.maxTextureSize
|| scaled_height > glConfig.maxTextureSize ) {
scaled_width >>= 1;
scaled_height >>= 1;
}
scaledBuffer = ri.Hunk_AllocateTempMemory( sizeof( unsigned ) * scaled_width * scaled_height );
if ( qglActiveTextureARB ) {
GL_SelectTexture( image->TMU );
}
GL_Bind(image);
// copy or resample data as appropriate for first MIP level
if ( ( scaled_width == width ) &&
( scaled_height == height ) ) {
if (!image->mipmap)
{
scaled_x = x * scaled_width / width;
scaled_y = y * scaled_height / height;
qglTexSubImage2D( GL_TEXTURE_2D, 0, scaled_x, scaled_y, scaled_width, scaled_height, GL_RGBA, GL_UNSIGNED_BYTE, data );
GL_CheckErrors();
goto done;
}
Com_Memcpy (scaledBuffer, data, width*height*4);
}
else
{
// use the normal mip-mapping function to go down from here
while ( width > scaled_width || height > scaled_height ) {
R_MipMap( (byte *)data, width, height );
width >>= 1;
height >>= 1;
x >>= 1;
y >>= 1;
if ( width < 1 ) {
width = 1;
}
if ( height < 1 ) {
height = 1;
}
}
Com_Memcpy( scaledBuffer, data, width * height * 4 );
}
R_LightScaleTexture (scaledBuffer, scaled_width, scaled_height, !image->mipmap );
scaled_x = x * scaled_width / width;
scaled_y = y * scaled_height / height;
qglTexSubImage2D( GL_TEXTURE_2D, 0, scaled_x, scaled_y, scaled_width, scaled_height, GL_RGBA, GL_UNSIGNED_BYTE, scaledBuffer );
if (image->mipmap)
{
int miplevel;
miplevel = 0;
while (scaled_width > 1 || scaled_height > 1)
{
R_MipMap( (byte *)scaledBuffer, scaled_width, scaled_height );
scaled_width >>= 1;
scaled_height >>= 1;
if (scaled_width < 1)
scaled_width = 1;
if (scaled_height < 1)
scaled_height = 1;
miplevel++;
if ( r_colorMipLevels->integer ) {
R_BlendOverTexture( (byte *)scaledBuffer, scaled_width * scaled_height, mipBlendColors[miplevel] );
}
scaled_x = x * scaled_width / width;
scaled_y = y * scaled_height / height;
qglTexSubImage2D( GL_TEXTURE_2D, 0, scaled_x, scaled_y, scaled_width, scaled_height, GL_RGBA, GL_UNSIGNED_BYTE, scaledBuffer );
}
}
done:
GL_SelectTexture( 0 );
GL_CheckErrors();
if ( scaledBuffer != 0 )
ri.Hunk_FreeTempMemory( scaledBuffer );
if ( resampledBuffer != 0 )
ri.Hunk_FreeTempMemory( resampledBuffer );
}
//===================================================================
typedef struct
@ -1252,7 +1553,7 @@ void R_CreateBuiltinImages( void ) {
if (glRefConfig.vertexBufferObject && r_arb_vertex_buffer_object->integer
&& glRefConfig.glsl && r_arb_shader_objects->integer)
{
if (r_dlightShadows->integer)
if (r_dlightMode->integer >= 2)
{
for( x = 0; x < MAX_DLIGHTS; x++)
{

View File

@ -32,6 +32,7 @@ float displayAspect = 0.0f;
glstate_t glState;
static void GfxInfo_f( void );
static void GfxMemInfo_f( void );
cvar_t *r_flareSize;
cvar_t *r_flareFade;
@ -107,7 +108,8 @@ cvar_t *r_deluxeMapping;
cvar_t *r_parallaxMapping;
cvar_t *r_normalAmbient;
cvar_t *r_recalcMD3Normals;
cvar_t *r_dlightShadows;
cvar_t *r_mergeLightmaps;
cvar_t *r_dlightMode;
cvar_t *r_pshadowDist;
cvar_t *r_ignoreGLErrors;
@ -1039,6 +1041,58 @@ void GfxInfo_f( void )
}
}
/*
================
GfxMemInfo_f
================
*/
void GfxMemInfo_f( void )
{
switch (glRefConfig.memInfo)
{
case MI_NONE:
{
ri.Printf(PRINT_ALL, "No extension found for GPU memory info.\n");
}
break;
case MI_NVX:
{
int value;
qglGetIntegerv(GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &value);
ri.Printf(PRINT_ALL, "GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX: %ikb\n", value);
qglGetIntegerv(GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &value);
ri.Printf(PRINT_ALL, "GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX: %ikb\n", value);
qglGetIntegerv(GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &value);
ri.Printf(PRINT_ALL, "GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX: %ikb\n", value);
qglGetIntegerv(GPU_MEMORY_INFO_EVICTION_COUNT_NVX, &value);
ri.Printf(PRINT_ALL, "GPU_MEMORY_INFO_EVICTION_COUNT_NVX: %i\n", value);
qglGetIntegerv(GPU_MEMORY_INFO_EVICTED_MEMORY_NVX, &value);
ri.Printf(PRINT_ALL, "GPU_MEMORY_INFO_EVICTED_MEMORY_NVX: %ikb\n", value);
}
break;
case MI_ATI:
{
// GL_ATI_meminfo
int value[4];
qglGetIntegerv(VBO_FREE_MEMORY_ATI, &value[0]);
ri.Printf(PRINT_ALL, "VBO_FREE_MEMORY_ATI: %ikb total %ikb largest aux: %ikb total %ikb largest\n", value[0], value[1], value[2], value[3]);
qglGetIntegerv(TEXTURE_FREE_MEMORY_ATI, &value[0]);
ri.Printf(PRINT_ALL, "TEXTURE_FREE_MEMORY_ATI: %ikb total %ikb largest aux: %ikb total %ikb largest\n", value[0], value[1], value[2], value[3]);
qglGetIntegerv(RENDERBUFFER_FREE_MEMORY_ATI, &value[0]);
ri.Printf(PRINT_ALL, "RENDERBUFFER_FREE_MEMORY_ATI: %ikb total %ikb largest aux: %ikb total %ikb largest\n", value[0], value[1], value[2], value[3]);
}
break;
}
}
/*
===============
R_Register
@ -1098,9 +1152,10 @@ void R_Register( void )
r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_normalAmbient = ri.Cvar_Get( "r_normalAmbient", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_dlightShadows = ri.Cvar_Get( "r_dlightShadows", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_dlightMode = ri.Cvar_Get( "r_dlightMode", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_pshadowDist = ri.Cvar_Get( "r_pshadowDist", "128", CVAR_ARCHIVE );
r_recalcMD3Normals = ri.Cvar_Get( "r_recalcMD3Normals", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_mergeLightmaps = ri.Cvar_Get( "r_mergeLightmaps", "1", CVAR_ARCHIVE | CVAR_LATCH );
//
// temporary latched variables that can only change over a restart
@ -1210,6 +1265,7 @@ void R_Register( void )
ri.Cmd_AddCommand( "screenshot", R_ScreenShot_f );
ri.Cmd_AddCommand( "screenshotJPEG", R_ScreenShotJPEG_f );
ri.Cmd_AddCommand( "gfxinfo", GfxInfo_f );
ri.Cmd_AddCommand( "gfxmeminfo", GfxMemInfo_f );
}
void R_InitQueries(void)

View File

@ -56,11 +56,11 @@ typedef unsigned int glIndex_t;
#define MAX_STATES_PER_SHADER 32
#define MAX_STATE_NAME 32
#define MAX_VISCOUNTS 5
#define MAX_VBOS 4096
#define MAX_IBOS 4096
typedef struct dlight_s {
vec3_t origin;
vec3_t color; // range from 0.0 to 1.0, should be color normalized
@ -821,7 +821,8 @@ enum
GENERIC_UNIFORM_DEFORMPARAMS,
GENERIC_UNIFORM_COLORGEN,
GENERIC_UNIFORM_ALPHAGEN,
GENERIC_UNIFORM_COLOR,
GENERIC_UNIFORM_BASECOLOR,
GENERIC_UNIFORM_VERTCOLOR,
GENERIC_UNIFORM_AMBIENTLIGHT,
GENERIC_UNIFORM_DIRECTEDLIGHT,
GENERIC_UNIFORM_LIGHTORIGIN,
@ -830,7 +831,7 @@ enum
GENERIC_UNIFORM_FOGDISTANCE,
GENERIC_UNIFORM_FOGDEPTH,
GENERIC_UNIFORM_FOGEYET,
GENERIC_UNIFORM_FOGADJUSTCOLORS,
GENERIC_UNIFORM_FOGCOLORMASK,
GENERIC_UNIFORM_MODELMATRIX,
GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX,
GENERIC_UNIFORM_TIME,
@ -1560,6 +1561,12 @@ typedef struct {
matrix_t modelviewProjection;
} glstate_t;
typedef enum {
MI_NONE,
MI_NVX,
MI_ATI
} memInfo_t;
// We can't change glConfig_t without breaking DLL/vms compatibility, so
// store extensions we have here.
typedef struct {
@ -1585,6 +1592,8 @@ typedef struct {
qboolean shaderObjects;
qboolean vertexShader;
qboolean glsl;
memInfo_t memInfo;
} glRefConfig_t;
@ -1934,9 +1943,10 @@ extern cvar_t *r_specularMapping;
extern cvar_t *r_deluxeMapping;
extern cvar_t *r_parallaxMapping;
extern cvar_t *r_normalAmbient;
extern cvar_t *r_dlightShadows;
extern cvar_t *r_dlightMode;
extern cvar_t *r_pshadowDist;
extern cvar_t *r_recalcMD3Normals;
extern cvar_t *r_mergeLightmaps;
extern cvar_t *r_greyscale;
@ -2073,6 +2083,7 @@ image_t *R_FindImageFile( const char *name, qboolean mipmap, qboolean allowPicm
image_t *R_CreateImage( const char *name, const byte *pic, int width, int height, qboolean mipmap
, qboolean allowPicmip, int wrapClampMode );
void R_UpdateSubImage( image_t *image, const byte *pic, int x, int y, int width, int height);
qboolean R_GetModeInfo( int *width, int *height, float *windowAspect, int mode );
void R_SetColorMappings( void );

View File

@ -2347,7 +2347,7 @@ void R_RenderPshadowMaps(const refdef_t *fd)
{
trRefEntity_t fakeEnt;
pshadow_t *shadow = &tr.refdef.pshadows[i];
vec3_t right;
vec3_t up;
vec3_t lightDir;
#if 0
@ -2367,16 +2367,16 @@ void R_RenderPshadowMaps(const refdef_t *fd)
VectorMA(shadow->viewOrigin, shadow->viewRadius, lightDir, shadow->lightOrigin);
// make up a projection, spin doesn't matter
// make up a projection, up doesn't matter
VectorScale(lightDir, -1.0f, shadow->lightViewAxis[0]);
VectorSet(right, 0, 0, -1);
VectorSet(up, 0, 0, -1);
if ( abs(DotProduct(right, shadow->lightViewAxis[0])) > 0.9f )
if ( abs(DotProduct(up, shadow->lightViewAxis[0])) > 0.9f )
{
VectorSet(right, -1, 0, 0);
VectorSet(up, -1, 0, 0);
}
CrossProduct(shadow->lightViewAxis[0], right, shadow->lightViewAxis[1]);
CrossProduct(shadow->lightViewAxis[0], up, shadow->lightViewAxis[1]);
VectorNormalize(shadow->lightViewAxis[1]);
CrossProduct(shadow->lightViewAxis[0], shadow->lightViewAxis[1], shadow->lightViewAxis[2]);

View File

@ -404,7 +404,7 @@ void RE_RenderScene( const refdef_t *fd ) {
tr.sceneCount++;
// SmileTheory: playing with shadow mapping
if (!( fd->rdflags & RDF_NOWORLDMODEL ) && tr.refdef.num_dlights && r_dlightShadows->integer
if (!( fd->rdflags & RDF_NOWORLDMODEL ) && tr.refdef.num_dlights && r_dlightMode->integer >= 2
&& glRefConfig.vertexBufferObject && r_arb_vertex_buffer_object->integer
&& glRefConfig.glsl && r_arb_shader_objects->integer)
{

View File

@ -1192,7 +1192,8 @@ static void ProjectDlightTextureVBOGLSL( void ) {
}
static qboolean ComputeHelperColor( shaderStage_t *pStage, vec4_t color);
static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t vertColor );
static void ComputeFogColorMask( shaderStage_t *pStage, vec4_t fogColorMask );
static void ComputeFogValues(vec4_t fogDistanceVector, vec4_t fogDepthVector, float *eyeT)
{
@ -1334,18 +1335,26 @@ static void ForwardDlightVBOGLSL( void ) {
}
if ( input->fogNum ) {
vec4_t fogColorMask;
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDISTANCE, fogDistanceVector);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDEPTH, fogDepthVector);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_FOGEYET, eyeT);
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_FOGADJUSTCOLORS, pStage->adjustColorsForFog);
}
else
{
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_FOGADJUSTCOLORS, 0);
ComputeFogColorMask(pStage, fogColorMask);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGCOLORMASK, fogColorMask);
}
if (ComputeHelperColor(pStage, vector))
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_COLOR, vector);
{
vec4_t baseColor;
vec4_t vertColor;
ComputeShaderColors(pStage, baseColor, vertColor);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_BASECOLOR, baseColor);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_VERTCOLOR, vertColor);
}
if (pStage->alphaGen == AGEN_PORTAL)
{
@ -1384,7 +1393,7 @@ static void ForwardDlightVBOGLSL( void ) {
if (pStage->bundle[TB_SPECULARMAP].image[0])
R_BindAnimatedImageToTMU( &pStage->bundle[TB_SPECULARMAP], TB_SPECULARMAP);
if (r_dlightShadows->integer)
if (r_dlightMode->integer >= 2)
{
GL_SelectTexture(TB_SHADOWMAP);
GL_BindCubemap(tr.shadowCubemaps[l]);
@ -1416,7 +1425,6 @@ static void ForwardDlightVBOGLSL( void ) {
static void ProjectPshadowVBOGLSL( void ) {
int l;
vec3_t origin;
float scale;
float radius;
int deformGen;
@ -1442,7 +1450,6 @@ static void ProjectPshadowVBOGLSL( void ) {
ps = &backEnd.refdef.pshadows[l];
VectorCopy( ps->lightOrigin, origin );
radius = ps->lightRadius;
scale = 1.0f / radius;
sp = &tr.pshadowShader;
@ -1454,15 +1461,15 @@ static void ProjectPshadowVBOGLSL( void ) {
vector[3] = 1.0f;
GLSL_SetUniformVec4(sp, PSHADOW_UNIFORM_LIGHTORIGIN, vector);
VectorScale(ps->lightViewAxis[0], -1.0f / ps->viewRadius, vector);
VectorScale(ps->lightViewAxis[0], 1.0f / ps->viewRadius, vector);
GLSL_SetUniformVec3(sp, PSHADOW_UNIFORM_LIGHTFORWARD, vector);
VectorScale(ps->lightViewAxis[1], 1.0f / ps->viewRadius, vector);
GLSL_SetUniformVec3(sp, PSHADOW_UNIFORM_LIGHTUP, vector);
VectorScale(ps->lightViewAxis[2], -1.0f / ps->viewRadius, vector);
GLSL_SetUniformVec3(sp, PSHADOW_UNIFORM_LIGHTRIGHT, vector);
VectorScale(ps->lightViewAxis[2], 1.0f / ps->viewRadius, vector);
GLSL_SetUniformVec3(sp, PSHADOW_UNIFORM_LIGHTUP, vector);
GLSL_SetUniformFloat(sp, PSHADOW_UNIFORM_LIGHTRADIUS, radius);
// include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
@ -1811,43 +1818,78 @@ static void ComputeColors( shaderStage_t *pStage )
}
}
static qboolean ComputeHelperColor( shaderStage_t *pStage, vec4_t color)
static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t vertColor )
{
qboolean set = qfalse;
color[0] =
color[1] =
color[2] =
color[3] = 1.0f;
//
// rgbGen
//
switch ( pStage->rgbGen )
{
case CGEN_IDENTITY:
set = qtrue;
baseColor[0] =
baseColor[1] =
baseColor[2] =
baseColor[3] = 1.0f;
vertColor[0] =
vertColor[1] =
vertColor[2] =
vertColor[3] = 0.0f;
break;
case CGEN_IDENTITY_LIGHTING:
color[0] =
color[1] =
color[2] =
color[3] = tr.identityLight; // FIXME: Code was like this in quake 3, is this a bug?
set = qtrue;
baseColor[0] =
baseColor[1] =
baseColor[2] = tr.identityLight;
baseColor[3] = 1.0f;
vertColor[0] =
vertColor[1] =
vertColor[2] =
vertColor[3] = 0.0f;
break;
case CGEN_EXACT_VERTEX:
baseColor[0] =
baseColor[1] =
baseColor[2] =
baseColor[3] = 0.0f;
vertColor[0] =
vertColor[1] =
vertColor[2] =
vertColor[3] = 1.0f;
break;
case CGEN_CONST:
color[0] = pStage->constantColor[0] / 255.0f;
color[1] = pStage->constantColor[1] / 255.0f;
color[2] = pStage->constantColor[2] / 255.0f;
color[3] = pStage->constantColor[3] / 255.0f;
set = qtrue;
baseColor[0] = pStage->constantColor[0] / 255.0f;
baseColor[1] = pStage->constantColor[1] / 255.0f;
baseColor[2] = pStage->constantColor[2] / 255.0f;
baseColor[3] = pStage->constantColor[3] / 255.0f;
vertColor[0] =
vertColor[1] =
vertColor[2] =
vertColor[3] = 0.0f;
break;
case CGEN_VERTEX:
baseColor[0] =
baseColor[1] =
baseColor[2] =
baseColor[3] = 0.0f;
vertColor[0] =
vertColor[1] =
vertColor[2] = tr.identityLight;
vertColor[3] = 1.0f;
break;
case CGEN_ONE_MINUS_VERTEX:
color[0] =
color[1] =
color[2] = tr.identityLight;
set = qtrue;
baseColor[0] =
baseColor[1] =
baseColor[2] = tr.identityLight;
baseColor[3] = 1.0f;
vertColor[0] =
vertColor[1] =
vertColor[2] = -tr.identityLight;
vertColor[3] = 0.0f;
break;
case CGEN_FOG:
{
@ -1855,12 +1897,16 @@ static qboolean ComputeHelperColor( shaderStage_t *pStage, vec4_t color)
fog = tr.world->fogs + tess.fogNum;
color[0] = ((unsigned char *)(&fog->colorInt))[0] / 255.0f;
color[1] = ((unsigned char *)(&fog->colorInt))[1] / 255.0f;
color[2] = ((unsigned char *)(&fog->colorInt))[2] / 255.0f;
color[3] = ((unsigned char *)(&fog->colorInt))[3] / 255.0f;
baseColor[0] = ((unsigned char *)(&fog->colorInt))[0] / 255.0f;
baseColor[1] = ((unsigned char *)(&fog->colorInt))[1] / 255.0f;
baseColor[2] = ((unsigned char *)(&fog->colorInt))[2] / 255.0f;
baseColor[3] = ((unsigned char *)(&fog->colorInt))[3] / 255.0f;
}
set = qtrue;
vertColor[0] =
vertColor[1] =
vertColor[2] =
vertColor[3] = 0.0f;
break;
case CGEN_WAVEFORM:
{
@ -1881,35 +1927,56 @@ static qboolean ComputeHelperColor( shaderStage_t *pStage, vec4_t color)
glow = 1;
}
color[0] =
color[1] =
color[2] = glow;
baseColor[0] =
baseColor[1] =
baseColor[2] = glow;
baseColor[3] = 1.0f;
}
set = qtrue;
vertColor[0] =
vertColor[1] =
vertColor[2] =
vertColor[3] = 0.0f;
break;
case CGEN_ENTITY:
if (backEnd.currentEntity)
{
color[0] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[0] / 255.0f;
color[1] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[1] / 255.0f;
color[2] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[2] / 255.0f;
color[3] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f;
baseColor[0] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[0] / 255.0f;
baseColor[1] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[1] / 255.0f;
baseColor[2] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[2] / 255.0f;
baseColor[3] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f;
}
set = qtrue;
vertColor[0] =
vertColor[1] =
vertColor[2] =
vertColor[3] = 0.0f;
break;
case CGEN_ONE_MINUS_ENTITY:
if (backEnd.currentEntity)
{
color[0] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[0] / 255.0f;
color[1] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[1] / 255.0f;
color[2] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[2] / 255.0f;
color[3] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f;
baseColor[0] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[0] / 255.0f;
baseColor[1] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[1] / 255.0f;
baseColor[2] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[2] / 255.0f;
baseColor[3] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f;
}
set = qtrue;
vertColor[0] =
vertColor[1] =
vertColor[2] =
vertColor[3] = 0.0f;
break;
case CGEN_LIGHTING_DIFFUSE:
case CGEN_EXACT_VERTEX:
case CGEN_BAD:
baseColor[0] =
baseColor[1] =
baseColor[2] =
baseColor[3] = 1.0f;
vertColor[0] =
vertColor[1] =
vertColor[2] =
vertColor[3] = 0.0f;
break;
}
@ -1919,15 +1986,14 @@ static qboolean ComputeHelperColor( shaderStage_t *pStage, vec4_t color)
switch ( pStage->alphaGen )
{
case AGEN_SKIP:
set = qtrue;
break;
case AGEN_IDENTITY:
color[3] = 1.0f;
set = qtrue;
baseColor[3] = 1.0f;
vertColor[3] = 0.0f;
break;
case AGEN_CONST:
color[3] = pStage->constantColor[3] / 255.0f;
set = qtrue;
baseColor[3] = pStage->constantColor[3] / 255.0f;
vertColor[3] = 0.0f;
break;
case AGEN_WAVEFORM:
// From RB_CalcWaveAlpha
@ -1935,37 +2001,41 @@ static qboolean ComputeHelperColor( shaderStage_t *pStage, vec4_t color)
float glow;
waveForm_t *wf = &pStage->alphaWave;
glow = EvalWaveFormClamped( wf );
color[3] = glow;
baseColor[3] = glow;
}
set = qtrue;
vertColor[3] = 0.0f;
break;
case AGEN_ENTITY:
if (backEnd.currentEntity)
{
color[3] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f;
baseColor[3] = ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f;
}
set = qtrue;
vertColor[3] = 0.0f;
break;
case AGEN_ONE_MINUS_ENTITY:
if (backEnd.currentEntity)
{
color[3] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f;
baseColor[3] = 1.0f - ((unsigned char *)backEnd.currentEntity->e.shaderRGBA)[3] / 255.0f;
}
set = qtrue;
vertColor[3] = 0.0f;
break;
case AGEN_VERTEX:
baseColor[3] = 0.0f;
vertColor[3] = 1.0f;
break;
case AGEN_ONE_MINUS_VERTEX:
baseColor[3] = 1.0f;
vertColor[3] = -1.0f;
break;
case AGEN_LIGHTING_SPECULAR:
case AGEN_VERTEX:
case AGEN_ONE_MINUS_VERTEX:
case AGEN_PORTAL:
case AGEN_FRESNEL:
// Done entirely in vertex program
baseColor[3] = 1.0f;
vertColor[3] = 0.0f;
break;
}
//
// pStage->adjustColorsForFog is done in the vertex program now
//
// FIXME: find some way to implement this.
#if 0
// if in greyscale rendering mode turn all color values into greyscale.
@ -1980,10 +2050,40 @@ static qboolean ComputeHelperColor( shaderStage_t *pStage, vec4_t color)
}
}
#endif
return set;
}
static void ComputeFogColorMask( shaderStage_t *pStage, vec4_t fogColorMask )
{
switch(pStage->adjustColorsForFog)
{
case ACFF_MODULATE_RGB:
fogColorMask[0] =
fogColorMask[1] =
fogColorMask[2] = 1.0f;
fogColorMask[3] = 0.0f;
break;
case ACFF_MODULATE_ALPHA:
fogColorMask[0] =
fogColorMask[1] =
fogColorMask[2] = 0.0f;
fogColorMask[3] = 1.0f;
break;
case ACFF_MODULATE_RGBA:
fogColorMask[0] =
fogColorMask[1] =
fogColorMask[2] =
fogColorMask[3] = 1.0f;
break;
default:
fogColorMask[0] =
fogColorMask[1] =
fogColorMask[2] =
fogColorMask[3] = 0.0f;
break;
}
}
/*
===============
ComputeColorMatrix
@ -2684,10 +2784,17 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
if (pStage->glslShaderGroup)
{
int index = pStage->glslShaderIndex;
if (backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity)
{
index |= LIGHTDEF_ENTITY;
}
if (r_lightmap->integer && index & LIGHTDEF_USE_LIGHTMAP)
{
index = LIGHTDEF_USE_LIGHTMAP;
}
sp = &pStage->glslShaderGroup[index];
if (pStage->glslShaderGroup == tr.lightallShader)
@ -2725,13 +2832,15 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
GL_State( pStage->stateBits );
{
vec4_t color;
vec4_t baseColor;
vec4_t vertColor;
if (ComputeHelperColor(pStage, color))
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_COLOR, color);
ComputeShaderColors(pStage, baseColor, vertColor);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_BASECOLOR, baseColor);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_VERTCOLOR, vertColor);
}
if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE)
{
vec4_t vec;
@ -2759,11 +2868,11 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
if ( input->fogNum )
{
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_FOGADJUSTCOLORS, pStage->adjustColorsForFog);
}
else
{
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_FOGADJUSTCOLORS, 0);
vec4_t fogColorMask;
ComputeFogColorMask(pStage, fogColorMask);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGCOLORMASK, fogColorMask);
}
ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix );
@ -3164,7 +3273,8 @@ void RB_StageIteratorGenericVBO( void )
&& !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) {
if (glRefConfig.glsl && r_arb_shader_objects->integer)
{
if (tess.shader->numUnfoggedPasses == 1 && tess.xstages[0]->glslShaderGroup == tr.lightallShader)
if (tess.shader->numUnfoggedPasses == 1 && tess.xstages[0]->glslShaderGroup == tr.lightallShader
&& r_dlightMode->integer)
{
ForwardDlightVBOGLSL();
}

View File

@ -658,6 +658,27 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
ri.Printf( PRINT_WARNING, "WARNING: R_FindImageFile could not find '%s' in shader '%s'\n", token, shader.name );
return qfalse;
}
//if ( r_autoFindNormalMap->integer )
{
char filename[MAX_QPATH];
COM_StripExtension(token, filename, sizeof(filename));
Q_strcat(filename, sizeof(filename), "_normal");
stage->bundle[TB_NORMALMAP].image[0] = R_FindImageFile( filename, !shader.noMipMaps, !shader.noPicMip, GL_REPEAT );
}
//if ( r_autoFindSpecularMap->integer )
{
char filename[MAX_QPATH];
COM_StripExtension(token, filename, sizeof(filename));
Q_strcat(filename, sizeof(filename), "_specular");
stage->bundle[TB_SPECULARMAP].image[0] = R_FindImageFile( filename, !shader.noMipMaps, !shader.noPicMip, GL_REPEAT );
stage->specularReflectance = 0.04f;
}
}
}
//
@ -2089,7 +2110,7 @@ static qboolean CollapseMultitexture( void ) {
static void CollapseStagesToLightall(shaderStage_t *diffuse,
shaderStage_t *normal, shaderStage_t *specular, shaderStage_t *lightmap,
qboolean isWorld, qboolean parallax, qboolean environment)
qboolean useLightVector, qboolean parallax, qboolean environment)
{
int defs = 0;
@ -2105,14 +2126,12 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse,
defs |= LIGHTDEF_USE_LIGHTMAP;
}
if (tr.worldDeluxeMapping && lightmap)
if ((tr.worldDeluxeMapping || r_deluxeMapping->integer == 2) && lightmap)
{
//ri.Printf(PRINT_ALL, ", deluxemap");
diffuse->bundle[TB_DELUXEMAP] = lightmap->bundle[0];
diffuse->bundle[TB_DELUXEMAP].image[0] = tr.deluxemaps[shader.lightmapIndex];
defs |= LIGHTDEF_USE_DELUXEMAP;
if (parallax)
defs |= LIGHTDEF_USE_PARALLAXMAP;
}
if (normal)
@ -2120,6 +2139,15 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse,
//ri.Printf(PRINT_ALL, ", normalmap %s", normal->bundle[0].image[0]->imgName);
diffuse->bundle[TB_NORMALMAP] = normal->bundle[0];
defs |= LIGHTDEF_USE_NORMALMAP;
if (parallax)
defs |= LIGHTDEF_USE_PARALLAXMAP;
}
else if (diffuse->bundle[TB_NORMALMAP].image[0])
{
image_t *tmpImg = diffuse->bundle[TB_NORMALMAP].image[0];
diffuse->bundle[TB_NORMALMAP] = diffuse->bundle[TB_DIFFUSEMAP];
diffuse->bundle[TB_NORMALMAP].image[0] = tmpImg;
defs |= LIGHTDEF_USE_NORMALMAP;
}
if (specular)
@ -2129,10 +2157,17 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse,
diffuse->specularReflectance = specular->specularReflectance;
defs |= LIGHTDEF_USE_SPECULARMAP;
}
if (!isWorld)
else if (diffuse->bundle[TB_SPECULARMAP].image[0])
{
defs |= LIGHTDEF_ENTITY | LIGHTDEF_USE_LIGHT_VECTOR;
image_t *tmpImg = diffuse->bundle[TB_SPECULARMAP].image[0];
diffuse->bundle[TB_SPECULARMAP] = diffuse->bundle[TB_DIFFUSEMAP];
diffuse->bundle[TB_SPECULARMAP].image[0] = tmpImg;
defs |= LIGHTDEF_USE_SPECULARMAP;
}
if (useLightVector)
{
defs |= LIGHTDEF_USE_LIGHT_VECTOR;
}
if (environment)
@ -2193,6 +2228,12 @@ static qboolean CollapseStagesToGLSL(void)
if (!pStage->active)
continue;
if (pStage->adjustColorsForFog)
{
skip = qtrue;
break;
}
if (pStage->bundle[0].isLightmap)
{
int blendBits = pStage->stateBits & ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
@ -2216,22 +2257,9 @@ static qboolean CollapseStagesToGLSL(void)
break;
}
switch(pStage->rgbGen)
{
//case CGEN_LIGHTING_DIFFUSE:
case CGEN_EXACT_VERTEX:
case CGEN_VERTEX:
case CGEN_ONE_MINUS_VERTEX:
skip = qtrue;
break;
default:
break;
}
switch(pStage->alphaGen)
{
case AGEN_LIGHTING_SPECULAR:
case AGEN_VERTEX:
case AGEN_ONE_MINUS_VERTEX:
case AGEN_PORTAL:
case AGEN_FRESNEL:
skip = qtrue;
@ -2248,7 +2276,7 @@ static qboolean CollapseStagesToGLSL(void)
{
shaderStage_t *pStage = &stages[i];
shaderStage_t *diffuse, *normal, *specular, *lightmap;
qboolean parallax, environment, world;
qboolean parallax, environment, entity;
if (!pStage->active)
continue;
@ -2261,13 +2289,13 @@ static qboolean CollapseStagesToGLSL(void)
if (pStage->bundle[0].isLightmap)
continue;
diffuse = NULL;
diffuse = pStage;
normal = NULL;
parallax = qfalse;
specular = NULL;
lightmap = NULL;
// find matching normal, specular, and lightmap for this diffuse stage
// we have a diffuse map, find matching normal, specular, and lightmap
for (j = i + 1; j < MAX_SHADER_STAGES; j++)
{
shaderStage_t *pStage2 = &stages[j];
@ -2311,21 +2339,19 @@ static qboolean CollapseStagesToGLSL(void)
}
}
diffuse = pStage;
environment = qfalse;
if (diffuse->bundle[0].tcGen == TCGEN_ENVIRONMENT_MAPPED)
{
environment = qtrue;
}
world = qtrue;
entity = qfalse;
if (diffuse->rgbGen == CGEN_LIGHTING_DIFFUSE)
{
world = qfalse;
entity = qtrue;
}
CollapseStagesToLightall(diffuse, normal, specular, lightmap, world, parallax, environment);
CollapseStagesToLightall(diffuse, normal, specular, lightmap, entity, parallax, environment);
}
// deactivate lightmap stages

View File

@ -209,6 +209,23 @@ ADD_ALL_EXTENSION_FUNCTIONS;
#undef HANDLE_EXT_FUNC
// GL_ARB_texture_compression
void (APIENTRY * qglCompressedTexImage3DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
void (APIENTRY * qglCompressedTexImage2DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
GLint border, GLsizei imageSize, const GLvoid *data);
void (APIENTRY * qglCompressedTexImage1DARB)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border,
GLsizei imageSize, const GLvoid *data);
void (APIENTRY * qglCompressedTexSubImage3DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
void (APIENTRY * qglCompressedTexSubImage2DARB)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
void (APIENTRY * qglCompressedTexSubImage1DARB)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format,
GLsizei imageSize, const GLvoid *data);
void (APIENTRY * qglGetCompressedTexImageARB)(GLenum target, GLint lod,
GLvoid *img);
#if defined(WIN32)
// WGL_ARB_create_context
HGLRC(APIENTRY * qwglCreateContextAttribsARB) (HDC hdC, HGLRC hShareContext, const int *attribList);
@ -744,6 +761,14 @@ static void GLimp_InitExtensions( void )
{
glConfig.textureCompression = TC_S3TC_ARB;
ri.Printf( PRINT_ALL, "...using GL_EXT_texture_compression_s3tc\n" );
qglCompressedTexImage3DARB = SDL_GL_GetProcAddress( "glCompressedTexImage3DARB" );
qglCompressedTexImage2DARB = SDL_GL_GetProcAddress( "glCompressedTexImage2DARB" );
qglCompressedTexImage1DARB = SDL_GL_GetProcAddress( "glCompressedTexImage1DARB" );
qglCompressedTexSubImage3DARB = SDL_GL_GetProcAddress( "glCompressedTexSubImage3DARB" );
qglCompressedTexSubImage2DARB = SDL_GL_GetProcAddress( "glCompressedTexSubImage2DARB" );
qglCompressedTexSubImage1DARB = SDL_GL_GetProcAddress( "glCompressedTexSubImage1DARB" );
qglGetCompressedTexImageARB = SDL_GL_GetProcAddress( "glGetCompressedTexImageARB" );
}
else
{
@ -1182,6 +1207,17 @@ static void GLimp_InitExtensions( void )
(glRefConfig.vertexBufferObject && r_arb_vertex_buffer_object->integer);
glRefConfig.memInfo = MI_NONE;
if( GLimp_HaveExtension( "GL_NVX_gpu_memory_info"))
{
glRefConfig.memInfo = MI_NVX;
}
else if( GLimp_HaveExtension( "GL_ATI_meminfo"))
{
glRefConfig.memInfo = MI_ATI;
}
}
#define R_MODE_FALLBACK 3 // 640 * 480