03 Dec 2017

This commit is contained in:
g-cont 2017-12-03 00:00:00 +03:00 committed by Alibek Omarov
parent ed59113f71
commit a79b5f8d28
11 changed files with 187 additions and 179 deletions

View File

@ -90,7 +90,7 @@ typedef enum
// reserved
TF_CUBEMAP = (1<<6), // it's cubemap texture
TF_DEPTHMAP = (1<<7), // custom texture filter used
// reserved
TF_QUAKEPAL = (1<<8), // image has an quake1 palette
TF_LUMINANCE = (1<<9), // force image to grayscale
TF_SKYSIDE = (1<<10), // this is a part of skybox
TF_CLAMP = (1<<11), // clamp texcoords to [0..1] range

View File

@ -84,8 +84,8 @@ byte *CL_CreateRawTextureFromPixels( texture_t *tx, size_t *size, int topcolor,
// update palette
pal = (byte *)(tx + 1) + (tx->width * tx->height);
Image_PaletteHueReplace( pal, topcolor, tx->anim_min, tx->anim_max );
Image_PaletteHueReplace( pal, bottomcolor, tx->anim_max + 1, tx->anim_total );
Image_PaletteHueReplace( pal, topcolor, tx->anim_min, tx->anim_max, 3 );
Image_PaletteHueReplace( pal, bottomcolor, tx->anim_max + 1, tx->anim_total, 3 );
return (byte *)&pin;
}

View File

@ -1256,6 +1256,9 @@ static void GL_ProcessImage( gltexture_t *tex, rgbdata_t *pic, imgfilter_t *filt
if( pic->flags & IMAGE_HAS_LUMA )
tex->flags |= TF_HAS_LUMA;
if( pic->flags & IMAGE_QUAKEPAL )
tex->flags |= TF_QUAKEPAL;
// create luma texture from quake texture
if( tex->flags & TF_MAKELUMA )
{

View File

@ -453,7 +453,7 @@ void R_AliasInit( void );
//
// gl_warp.c
//
void R_InitSky( struct mip_s *mt, struct texture_s *tx );
void R_InitSky( struct mip_s *mt, struct texture_s *tx, qboolean custom_palette );
void R_AddSkyBoxSurface( msurface_t *fa );
void R_ClearSkyBox( void );
void R_DrawSkyBox( void );

View File

@ -436,8 +436,8 @@ texture_t *R_TextureAnimation( msurface_t *s )
if( base->name[0] == '-' )
{
int tx = (int)((s->texturemins[0] + (base->width << 16)) / base->width) % MOD_FRAMES;
int ty = (int)((s->texturemins[1] + (base->height << 16)) / base->height) % MOD_FRAMES;
int tx = (int)((s->texturemins[0] + (base->width << 16)) / base->width) % MOD_FRAMES;
int ty = (int)((s->texturemins[1] + (base->height << 16)) / base->height) % MOD_FRAMES;
reletive = rtable[tx][ty] % base->anim_total;
}
@ -445,8 +445,8 @@ texture_t *R_TextureAnimation( msurface_t *s )
{
int speed;
// GoldSrc and Quake1 has different animating speed
if( world.sky_sphere || world.version == Q1BSP_VERSION || world.version == QBSP2_VERSION )
// Quake1 textures uses 10 frames per second
if( FBitSet( R_GetTexture( base->gl_texturenum )->flags, TF_QUAKEPAL ))
speed = 10;
else speed = 20;

View File

@ -681,7 +681,7 @@ R_InitSky
A sky texture is 256*128, with the right side being a masked overlay
==============
*/
void R_InitSky( mip_t *mt, texture_t *tx )
void R_InitSky( mip_t *mt, texture_t *tx, qboolean custom_palette )
{
rgbdata_t r_temp, *r_sky;
uint *trans, *rgba;
@ -694,12 +694,9 @@ void R_InitSky( mip_t *mt, texture_t *tx )
if( mt->offsets[0] > 0 )
{
// NOTE: imagelib detect miptex version by size
// 770 additional bytes is indicated custom palette
int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
if( world.version == HLBSP_VERSION || world.version == XTBSP_VERSION )
size += sizeof( short ) + 768;
int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
if( custom_palette ) size += sizeof( short ) + 768;
r_sky = FS_LoadImage( texname, (byte *)mt, size );
}
else

View File

@ -486,6 +486,7 @@ typedef enum
IMAGE_DDS_FORMAT = BIT(7), // a hint for GL loader
IMAGE_MULTILAYER = BIT(8), // to differentiate from 3D texture
IMAGE_ONEBIT_ALPHA = BIT(9), // binary alpha
IMAGE_QUAKEPAL = BIT(10), // image has quake1 palette
// Image_Process manipulation flags
IMAGE_FLIP_X = BIT(16), // flip the image by width
@ -493,10 +494,10 @@ typedef enum
IMAGE_ROT_90 = BIT(18), // flip from upper left corner to down right corner
IMAGE_ROT180 = IMAGE_FLIP_X|IMAGE_FLIP_Y,
IMAGE_ROT270 = IMAGE_FLIP_X|IMAGE_FLIP_Y|IMAGE_ROT_90,
IMAGE_ROUND = BIT(19), // round image to nearest Pow2
// reserved
IMAGE_RESAMPLE = BIT(20), // resample image to specified dims
IMAGE_PALTO24 = BIT(21), // turn 32-bit palette into 24-bit mode (only for indexed images)
IMAGE_ROUNDFILLER = BIT(22), // round image to Pow2 and fill unused entries with single color
// reserved
// reserved
IMAGE_FORCE_RGBA = BIT(23), // force image to RGBA buffer
IMAGE_MAKE_LUMA = BIT(24), // create luma texture from indexed
IMAGE_QUANTIZE = BIT(25), // make indexed image from 24 or 32- bit image
@ -556,8 +557,8 @@ rgbdata_t *FS_CopyImage( rgbdata_t *in );
void FS_FreeImage( rgbdata_t *pack );
extern const bpc_desc_t PFDesc[]; // image get pixelformat
qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, imgfilter_t *filter );
void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end );
void Image_PaletteTranslate( byte *palSrc, int top, int bottom );
void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end, int pal_size );
void Image_PaletteTranslate( byte *palSrc, int top, int bottom, int pal_size );
void Image_SetForceFlags( uint flags ); // set image force flags on loading
size_t Image_DXTGetLinearSize( int type, int width, int height, int depth );

View File

@ -275,16 +275,13 @@ enum
extern imglib_t image;
void Image_RoundDimensions( int *scaled_width, int *scaled_height );
byte *Image_ResampleInternal( const void *indata, int in_w, int in_h, int out_w, int out_h, int intype, qboolean *done );
byte *Image_FlipInternal( const byte *in, word *srcwidth, word *srcheight, int type, int flags );
void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end );
rgbdata_t *Image_Load(const char *filename, const byte *buffer, size_t buffsize );
qboolean Image_Copy8bitRGBA( const byte *in, byte *out, int pixels );
qboolean Image_AddIndexedImageToPack( const byte *in, int width, int height );
qboolean Image_AddRGBAImageToPack( uint imageSize, const void* data );
void Image_Save( const char *filename, rgbdata_t *pix );
void Image_ConvertPalTo24bit( rgbdata_t *pic );
void Image_GetPaletteLMP( const byte *pal, int rendermode );
void Image_GetPaletteBMP( const byte *pal );
int Image_ComparePalette( const byte *pal );

View File

@ -240,18 +240,6 @@ void Image_AddCmdFlags( uint flags )
image.cmd_flags |= flags;
}
/*
=================
Image_RoundDimensions
=================
*/
void Image_RoundDimensions( int *width, int *height )
{
// find nearest power of two, rounding down
*width = NearestPOW( *width, true );
*height = NearestPOW( *height, true );
}
qboolean Image_ValidSize( const char *name )
{
if( image.width > IMAGE_MAXWIDTH || image.height > IMAGE_MAXHEIGHT || image.width <= 0 || image.height <= 0 )
@ -445,7 +433,7 @@ void Image_CopyPalette32bit( void )
memcpy( image.palette, image.d_currentpal, 1024 );
}
void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end )
void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end, int pal_size )
{
float r, g, b;
float maxcol, mincol;
@ -453,12 +441,13 @@ void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end )
int i;
hue = (float)(newHue * ( 360.0f / 255 ));
pal_size = bound( 3, pal_size, 4 );
for( i = start; i <= end; i++ )
{
r = palSrc[i*3+0];
g = palSrc[i*3+1];
b = palSrc[i*3+2];
r = palSrc[i*pal_size+0];
g = palSrc[i*pal_size+1];
b = palSrc[i*pal_size+2];
maxcol = max( max( r, g ), b ) / 255.0f;
mincol = min( min( r, g ), b ) / 255.0f;
@ -513,17 +502,18 @@ void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end )
}
}
palSrc[i*3+0] = (byte)(r * 255);
palSrc[i*3+1] = (byte)(g * 255);
palSrc[i*3+2] = (byte)(b * 255);
palSrc[i*pal_size+0] = (byte)(r * 255);
palSrc[i*pal_size+1] = (byte)(g * 255);
palSrc[i*pal_size+2] = (byte)(b * 255);
}
}
void Image_PaletteTranslate( byte *palSrc, int top, int bottom )
void Image_PaletteTranslate( byte *palSrc, int top, int bottom, int pal_size )
{
byte dst[256], src[256];
int i;
pal_size = bound( 3, pal_size, 4 );
for( i = 0; i < 256; i++ )
src[i] = i;
memcpy( dst, src, 256 );
@ -552,9 +542,9 @@ void Image_PaletteTranslate( byte *palSrc, int top, int bottom )
// last color isn't changed
for( i = 0; i < 255; i++ )
{
palSrc[i*3+0] = palette_q1[dst[i]*3+0];
palSrc[i*3+1] = palette_q1[dst[i]*3+1];
palSrc[i*3+2] = palette_q1[dst[i]*3+2];
palSrc[i*pal_size+0] = palette_q1[dst[i]*3+0];
palSrc[i*pal_size+1] = palette_q1[dst[i]*3+1];
palSrc[i*pal_size+2] = palette_q1[dst[i]*3+2];
}
}
@ -1119,63 +1109,6 @@ byte *Image_ResampleInternal( const void *indata, int inwidth, int inheight, int
return image.tempbuffer;
}
/*
================
Image_Flood
================
*/
byte *Image_FloodInternal( const byte *indata, int inwidth, int inheight, int outwidth, int outheight, int type, qboolean *resampled )
{
int samples = PFDesc[type].bpp;
int newsize, x, y, i;
byte *in, *out;
// nothing to reflood ?
if( inwidth == outwidth && inheight == outheight )
{
*resampled = false;
return (byte *)indata;
}
// alloc new buffer
switch( type )
{
case PF_INDEXED_24:
case PF_INDEXED_32:
case PF_RGB_24:
case PF_BGR_24:
case PF_BGRA_32:
case PF_RGBA_32:
in = ( byte *)indata;
newsize = outwidth * outheight * samples;
out = image.tempbuffer = (byte *)Mem_Realloc( host.imagepool, image.tempbuffer, newsize );
break;
default:
MsgDev( D_WARN, "Image_Flood: unsupported format %s\n", PFDesc[type].name );
*resampled = false;
return (byte *)indata;
}
if( samples == 1 ) memset( out, 0xFF, newsize ); // last palette color
else memset( out, 0x00808080, newsize ); // gray (alpha leaved 0x00)
for( y = 0; y < outheight; y++ )
{
for( x = 0; y < inheight && x < outwidth; x++ )
{
for( i = 0; i < samples; i++ )
{
if( x < inwidth )
*out++ = *in++;
else out++;
}
}
}
*resampled = true;
return image.tempbuffer;
}
/*
================
Image_Flip
@ -1198,7 +1131,7 @@ byte *Image_FlipInternal( const byte *in, word *srcwidth, word *srcheight, int t
byte *out;
// nothing to process
if( !( flags & (IMAGE_FLIP_X|IMAGE_FLIP_Y|IMAGE_ROT_90)))
if( !FBitSet( flags, IMAGE_FLIP_X|IMAGE_FLIP_Y|IMAGE_ROT_90 ))
return (byte *)in;
switch( type )
@ -1234,7 +1167,7 @@ byte *Image_FlipInternal( const byte *in, word *srcwidth, word *srcheight, int t
}
// update dims
if( flags & IMAGE_ROT_90 )
if( FBitSet( flags, IMAGE_ROT_90 ))
{
*srcwidth = height;
*srcheight = width;
@ -1438,6 +1371,8 @@ rgbdata_t *Image_LightGamma( rgbdata_t *pic )
qboolean Image_RemapInternal( rgbdata_t *pic, int topColor, int bottomColor )
{
int pal_size = 3;
switch( pic->type )
{
case PF_INDEXED_24:
@ -1458,13 +1393,13 @@ qboolean Image_RemapInternal( rgbdata_t *pic, int topColor, int bottomColor )
if( Image_ComparePalette( pic->palette ) == PAL_QUAKE1 )
{
Image_PaletteTranslate( pic->palette, topColor * 16, bottomColor * 16 );
Image_PaletteTranslate( pic->palette, topColor * 16, bottomColor * 16, pal_size );
}
else
{
// g-cont. preview images has a swapped top and bottom colors. I don't know why.
Image_PaletteHueReplace( pic->palette, topColor, SUIT_HUE_START, SUIT_HUE_END );
Image_PaletteHueReplace( pic->palette, bottomColor, PLATE_HUE_START, PLATE_HUE_END );
Image_PaletteHueReplace( pic->palette, topColor, SUIT_HUE_START, SUIT_HUE_END, pal_size );
Image_PaletteHueReplace( pic->palette, bottomColor, PLATE_HUE_START, PLATE_HUE_END, pal_size );
}
return true;
@ -1635,39 +1570,13 @@ qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, imgf
out = Image_FlipInternal( pic->buffer, &pic->width, &pic->height, pic->type, flags );
if( pic->buffer != out ) memcpy( pic->buffer, image.tempbuffer, pic->size );
if(( flags & IMAGE_RESAMPLE && width > 0 && height > 0 ) || ( flags & IMAGE_ROUND ) || ( flags & IMAGE_ROUNDFILLER ))
if( FBitSet( flags, IMAGE_RESAMPLE ) && width > 0 && height > 0 )
{
int w = bound( 1, width, IMAGE_MAXWIDTH ); // 1 - 4096
int h = bound( 1, height, IMAGE_MAXHEIGHT); // 1 - 4096
qboolean resampled = false;
int w, h;
if(( flags & IMAGE_ROUND ) || ( flags & IMAGE_ROUNDFILLER ))
{
w = pic->width;
h = pic->height;
// round to nearest pow
// NOTE: images with dims less than 8x8 may causing problems
if( flags & IMAGE_ROUNDFILLER )
{
// roundfiller always must roundup
w = NearestPOW( w, false );
h = NearestPOW( h, false );
}
else Image_RoundDimensions( &w, &h );
w = bound( 8, w, IMAGE_MAXWIDTH ); // 8 - 4096
h = bound( 8, h, IMAGE_MAXHEIGHT); // 8 - 4096
}
else
{
// custom size (user choise without limitations)
w = bound( 1, width, IMAGE_MAXWIDTH ); // 1 - 4096
h = bound( 1, height, IMAGE_MAXHEIGHT); // 1 - 4096
}
if( flags & IMAGE_ROUNDFILLER )
out = Image_FloodInternal( pic->buffer, pic->width, pic->height, w, h, pic->type, &resampled );
else out = Image_ResampleInternal((uint *)pic->buffer, pic->width, pic->height, w, h, pic->type, &resampled );
out = Image_ResampleInternal((uint *)pic->buffer, pic->width, pic->height, w, h, pic->type, &resampled );
if( resampled ) // resampled or filled
{
@ -1685,8 +1594,8 @@ qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, imgf
}
// quantize image
if( flags & IMAGE_QUANTIZE ) pic = Image_Quantize( pic );
if( flags & IMAGE_PALTO24 ) Image_ConvertPalTo24bit( pic );
if( FBitSet( flags, IMAGE_QUANTIZE ))
pic = Image_Quantize( pic );
*pix = pic;

View File

@ -394,7 +394,7 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, size_t filesize )
rendermode = LUMP_GRADIENT;
}
image.flags |= IMAGE_HAS_ALPHA;
SetBits( image.flags, IMAGE_HAS_ALPHA );
}
else
{
@ -418,6 +418,8 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, size_t filesize )
}
}
if( pal_type == PAL_QUAKE1 )
SetBits( image.flags, IMAGE_QUAKEPAL );
rendermode = LUMP_NORMAL;
}
@ -463,6 +465,7 @@ qboolean Image_LoadMIP( const char *name, const byte *buffer, size_t filesize )
}
}
SetBits( image.flags, IMAGE_QUAKEPAL );
Image_GetPaletteQ1();
}
else

View File

@ -141,6 +141,7 @@ void Mod_PrintBSPFileSizes_f( void )
Msg( "=== Total BSP file data space used: %s ===\n", Q_memprint( totalmemory ));
Msg( "World size ( %g %g %g ) units\n", world.size[0], world.size[1], world.size[2] );
Msg( "Supports transparency world water: %s\n", world.water_alpha ? "Yes" : "No" );
Msg( "Lighting: %s\n", FBitSet( w->flags, MODEL_COLORED_LIGHTING ) ? "colored" : "monochrome" );
Msg( "original name: ^1%s\n", worldmodel->name );
Msg( "internal name: %s\n", (world.message[0]) ? va( "^2%s", world.message ) : "none" );
Msg( "map compiler: %s\n", (world.compiler[0]) ? va( "^3%s", world.compiler ) : "unknown" );
@ -799,6 +800,7 @@ static void Mod_LoadTextures( const dlump_t *l )
texture_t *anims[10];
texture_t *altanims[10];
int num, max, altmax;
qboolean custom_palette;
char texname[64];
imgfilter_t *filter;
mip_t *mt;
@ -857,14 +859,36 @@ static void Mod_LoadTextures( const dlump_t *l )
Q_strnlwr( mt->name, mt->name, sizeof( mt->name ));
Q_strncpy( tx->name, mt->name, sizeof( tx->name ));
filter = R_FindTexFilter( tx->name ); // grab texture filter
custom_palette = false;
tx->width = mt->width;
tx->height = mt->height;
if( mt->offsets[0] > 0 )
{
int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
int next_dataofs, remaining;
// compute next dataofset to determine allocated miptex sapce
for( j = i + 1; j < loadmodel->numtextures; j++ )
{
next_dataofs = in->dataofs[j];
if( next_dataofs != -1 ) break;
}
if( j == loadmodel->numtextures )
next_dataofs = l->filelen;
// NOTE: imagelib detect miptex version by size
// 770 additional bytes is indicated custom palette
remaining = next_dataofs - (in->dataofs[i] + size);
if( remaining >= 770 ) custom_palette = true;
}
// check for multi-layered sky texture
if( world.loading && !Q_strncmp( mt->name, "sky", 3 ) && mt->width == 256 && mt->height == 128 )
{
R_InitSky( mt, tx ); // loadq quake sky
R_InitSky( mt, tx, custom_palette ); // load quake sky
if( tr.solidskyTexture && tr.alphaskyTexture )
world.sky_sphere = true;
@ -898,10 +922,9 @@ static void Mod_LoadTextures( const dlump_t *l )
{
// NOTE: imagelib detect miptex version by size
// 770 additional bytes is indicated custom palette
int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
if( bmodel_version == HLBSP_VERSION || bmodel_version == XTBSP_VERSION )
size += sizeof( short ) + 768;
int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
if( custom_palette ) size += sizeof( short ) + 768;
Q_snprintf( texname, sizeof( texname ), "#%s.mip", mt->name );
tx->gl_texturenum = GL_LoadTexture( texname, (byte *)mt, size, 0, filter );
}
@ -919,10 +942,9 @@ static void Mod_LoadTextures( const dlump_t *l )
{
// NOTE: imagelib detect miptex version by size
// 770 additional bytes is indicated custom palette
int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
if( bmodel_version == HLBSP_VERSION || bmodel_version == XTBSP_VERSION )
size += sizeof( short ) + 768;
int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
if( custom_palette ) size += sizeof( short ) + 768;
tx->fb_texturenum = GL_LoadTexture( texname, (byte *)mt, size, TF_MAKELUMA, NULL );
}
else
@ -1260,6 +1282,7 @@ static qboolean Mod_LoadColoredLighting( void )
loadmodel->lightdata = Mem_Alloc( loadmodel->mempool, litdatasize );
memcpy( loadmodel->lightdata, in + 8, litdatasize );
if( world.loading ) world.litdatasize = litdatasize;
SetBits( loadmodel->flags, MODEL_COLORED_LIGHTING );
Mem_Free( in );
return true;
@ -1270,11 +1293,15 @@ static qboolean Mod_LoadColoredLighting( void )
Mod_LoadLighting
=================
*/
static void Mod_LoadLighting( const dlump_t *l, dextrahdr_t *extrahdr )
static void Mod_LoadLighting( const dlump_t *l, const dlump_t *faces, dextrahdr_t *extrahdr )
{
byte d, *in;
color24 *out;
int i;
int i, count;
dface_t *in16;
dface2_t *in32;
msurface_t *surf;
byte d, *in;
int lightofs;
color24 *out;
if( !l->filelen )
{
@ -1291,10 +1318,9 @@ static void Mod_LoadLighting( const dlump_t *l, dextrahdr_t *extrahdr )
in = (void *)(mod_base + l->fileofs);
if( world.loading ) world.litdatasize = l->filelen;
switch( bmodel_version )
switch( world.lightmap_samples )
{
case Q1BSP_VERSION:
case QBSP2_VERSION:
case 1:
if( !Mod_LoadColoredLighting( ))
{
// expand the white lighting data
@ -1310,29 +1336,72 @@ static void Mod_LoadLighting( const dlump_t *l, dextrahdr_t *extrahdr )
}
}
break;
case HLBSP_VERSION:
case XTBSP_VERSION:
// load colored lighting
case 3: // load colored lighting
loadmodel->lightdata = Mem_Alloc( loadmodel->mempool, l->filelen );
memcpy( loadmodel->lightdata, in, l->filelen );
SetBits( loadmodel->flags, MODEL_COLORED_LIGHTING );
break;
default:
Host_Error( "Mod_LoadLighting: bad lightmap sample count %i\n", world.lightmap_samples );
break;
}
if( !world.loading ) return; // only world can have deluxedata (FIXME: what about quake models?)
// not supposed to be load ?
if( !FBitSet( host.features, ENGINE_LOAD_DELUXEDATA ))
if( world.loading )
{
world.deluxedata = NULL;
world.vecdatasize = 0;
return;
// only world can have deluxedata (FIXME: what about quake models?)
// not supposed to be load ?
if( FBitSet( host.features, ENGINE_LOAD_DELUXEDATA ))
{
// try to loading deluxemap too
if( extrahdr != NULL )
Mod_LoadLightVecs( &extrahdr->lumps[LUMP_LIGHTVECS] );
else Mod_LoadDeluxemap (); // old method
}
else
{
world.deluxedata = NULL;
world.vecdatasize = 0;
}
}
// try to loading deluxemap too
if( extrahdr != NULL )
Mod_LoadLightVecs( &extrahdr->lumps[LUMP_LIGHTVECS] );
else Mod_LoadDeluxemap (); // old method
// setup lightdata pointers
if( bmodel_version == QBSP2_VERSION )
{
in32 = (void *)(mod_base + faces->fileofs);
count = faces->filelen / sizeof( *in32 );
in16 = NULL;
}
else
{
in16 = (void *)(mod_base + faces->fileofs);
count = faces->filelen / sizeof( *in16 );
in32 = NULL;
}
surf = loadmodel->surfaces;
for( i = 0; i < count; i++, surf++ )
{
if( bmodel_version == QBSP2_VERSION )
{
lightofs = in32->lightofs;
in32++;
}
else
{
lightofs = in16->lightofs;
in16++;
}
if( loadmodel->lightdata && lightofs != -1 )
{
surf->samples = loadmodel->lightdata + (lightofs / world.lightmap_samples);
// if deluxemap is present setup it too
if( world.deluxedata )
surf->info->deluxemap = world.deluxedata + (lightofs / 3);
}
}
}
/*
@ -1455,6 +1524,8 @@ static void Mod_LoadSurfaces( const dlump_t *l )
msurface_t *out;
mextrasurf_t *info;
int test_lightsize = -1;
int next_lightofs = -1;
int prev_lightofs = -1;
int i, j, count;
int lightofs;
@ -1478,7 +1549,11 @@ static void Mod_LoadSurfaces( const dlump_t *l )
loadmodel->numsurfaces = count;
loadmodel->surfaces = out = Mem_Alloc( loadmodel->mempool, count * sizeof( msurface_t ));
info = Mem_Alloc( loadmodel->mempool, count * sizeof( mextrasurf_t ));
world.lightmap_samples = 1; // assume monochrome lighting
// predict samplecount based on bspversion
if( bmodel_version == Q1BSP_VERSION || bmodel_version == QBSP2_VERSION )
world.lightmap_samples = 1;
else world.lightmap_samples = 3;
for( i = 0; i < count; i++, out++, info++ )
{
@ -1572,25 +1647,28 @@ static void Mod_LoadSurfaces( const dlump_t *l )
// grab the second sample to detect colored lighting
if( test_lightsize > 0 && lightofs != -1 )
{
world.lightmap_samples = lightofs / test_lightsize;
MsgDev( D_REPORT, "lighting: %s\n", (world.lightmap_samples == 1) ? "monochrome" : "colored" );
world.lightmap_samples = Q_max( world.lightmap_samples, 1 ); // avoid division by zero
test_lightsize = 0; // finish samples detect
if( lightofs > prev_lightofs && lightofs < next_lightofs )
next_lightofs = lightofs;
}
// grab the first sample to determine lightmap size
if( !lightofs && test_lightsize == -1 )
if( lightofs != -1 && test_lightsize == -1 )
{
int sample_size = Mod_SampleSizeForFace( out );
int smax = (info->lightextents[0] / sample_size) + 1;
int tmax = (info->lightextents[1] / sample_size) + 1;
int lightstyles = 0;
test_lightsize = ((info->lightextents[0] / sample_size) + 1) * ((info->lightextents[1] / sample_size) + 1);
test_lightsize = smax * tmax;
// count styles to right compute test_lightsize
for( j = 0; j < MAXLIGHTMAPS && out->styles[j] != 255; j++ )
lightstyles++;
test_lightsize *= lightstyles;
}
test_lightsize *= lightstyles;
prev_lightofs = lightofs;
next_lightofs = 99999999;
}
#if 0
if( loadmodel->lightdata && lightofs != -1 )
{
out->samples = loadmodel->lightdata + (lightofs / world.lightmap_samples);
@ -1599,10 +1677,30 @@ static void Mod_LoadSurfaces( const dlump_t *l )
if( world.deluxedata )
out->info->deluxemap = world.deluxedata + (lightofs / 3);
}
#endif
if( out->flags & SURF_DRAWTURB )
GL_SubdivideSurface( out ); // cut up polygon for warps
}
// now we have enough data to trying determine samplecount per lightmap pixel
if( test_lightsize != -1 && prev_lightofs != -1 && next_lightofs != -1 )
{
float samples = (float)(next_lightofs - prev_lightofs) / (float)test_lightsize;
if( samples != (int)samples )
{
test_lightsize = (test_lightsize + 3) & ~3; // align datasize and try again
samples = (float)(next_lightofs - prev_lightofs) / (float)test_lightsize;
}
if( samples == 1 || samples == 3 )
{
world.lightmap_samples = (int)samples;
MsgDev( D_REPORT, "lighting: %s\n", (world.lightmap_samples == 1) ? "monochrome" : "colored" );
world.lightmap_samples = Q_max( world.lightmap_samples, 1 ); // avoid division by zero
}
else MsgDev( D_WARN, "lighting invalid samplecount: %g, defaulting to %i\n", samples, world.lightmap_samples );
}
}
/*
@ -2595,10 +2693,10 @@ static void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *load
Mod_LoadEdges( &header->lumps[LUMP_EDGES] );
Mod_LoadSurfEdges( &header->lumps[LUMP_SURFEDGES] );
Mod_LoadTextures( &header->lumps[LUMP_TEXTURES] );
Mod_LoadLighting( &header->lumps[LUMP_LIGHTING], extrahdr );
Mod_LoadVisibility( &header->lumps[LUMP_VISIBILITY] );
Mod_LoadTexInfo( &header->lumps[LUMP_TEXINFO], extrahdr );
Mod_LoadSurfaces( &header->lumps[LUMP_FACES] );
Mod_LoadLighting( &header->lumps[LUMP_LIGHTING], &header->lumps[LUMP_FACES], extrahdr );
Mod_LoadMarkSurfaces( &header->lumps[LUMP_MARKSURFACES] );
Mod_LoadLeafs( &header->lumps[LUMP_LEAFS] );
Mod_LoadNodes( &header->lumps[LUMP_NODES] );