03 Dec 2017
This commit is contained in:
parent
ed59113f71
commit
a79b5f8d28
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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] );
|
||||
|
|
Reference in New Issue