02 Apr 2014

This commit is contained in:
g-cont 2014-04-02 00:00:00 +04:00 committed by Alibek Omarov
parent e11dac742d
commit a3d2270329
26 changed files with 467 additions and 225 deletions

View File

@ -92,6 +92,20 @@ typedef struct
int flags; // sky or slime, no lightmap or 256 subdivision
} mtexinfo_t;
// 73 bytes per VBO vertex
// FIXME: align to 32 bytes
typedef struct glvert_s
{
vec3_t vertex; // position
vec3_t normal; // normal
vec2_t stcoord; // ST texture coords
vec2_t lmcoord; // ST lightmap coords
vec2_t sccoord; // ST scissor coords (decals only) - for normalmap coords migration
vec3_t tangent; // tangent
vec3_t binormal; // binormal
byte color[4]; // colors per vertex
} glvert_t;
typedef struct glpoly_s
{
struct glpoly_s *next;
@ -197,15 +211,11 @@ typedef struct msurfmesh_s
{
unsigned short numVerts;
unsigned short numElems; // ~ 20 000 vertex per one surface. Should be enough
unsigned int startVert; // user-variable. may be used for construct world single-VBO
unsigned int startElem; // user-variable. may be used for construct world single-VBO
vec3_t *vertices; // vertexes array
vec2_t *stcoords; // s\t coords array
vec2_t *lmcoords; // l\m coords array (unused for studio models)
vec3_t *normals; // normals array (identical for bsp polys, unique for studio models)
vec3_t *tangent; // tangent array (identical for bsp polys, unique for studio models)
vec3_t *binormal; // binormal array (identical for bsp polys, unique for studio models)
byte *colors; // colors array for vertex lighting (filling 0xFF by default)
unsigned short *indices; // indices
glvert_t *verts; // vertexes array
unsigned short *elems; // indices
struct msurface_s *surf; // pointer to parent surface. Just for consistency
struct msurfmesh_s *next; // temporary chain of subdivided surfaces

View File

@ -118,6 +118,8 @@ typedef enum
TF_TEXTURE_RECTANGLE= (1<<22), // this is GL_TEXTURE_RECTANGLE
TF_ALPHA_BORDER = (1<<23), // clamp to (0,0,0,255) (probably no difference)
TF_IMAGE_PROGRAM = (1<<24), // enable image program support like in Doom3
TF_ALPHACONTRAST = (1<<25), // special texture flags for internal usage
TF_FLOAT = (1<<26), // float textures
} texFlags_t;
typedef struct beam_s BEAM;
@ -246,6 +248,8 @@ typedef struct render_interface_s
qboolean (*R_SpeedsMessage)( char *out, size_t size );
// replace with built-in R_DrawCubemapView for make skyshots or envshots
qboolean (*R_DrawCubemapView)( const float *origin, const float *angles, int size );
// alloc or destroy studiomodel custom data
void (*Mod_ProcessUserData)( model_t *mod, qboolean create );
} render_interface_t;
#endif//RENDER_API_H

View File

@ -323,7 +323,7 @@ void CL_LevelShot_f( void )
cls.scrshot_request = scrshot_inactive;
// check for exist
Q_sprintf( cls.shotname, "levelshots/%s.bmp", clgame.mapname );
Q_sprintf( cls.shotname, "levelshots/%s_%s.bmp", clgame.mapname, glState.wideScreen ? "16x9" : "4x3" );
// make sure what entity patch is never than bsp
ft1 = FS_FileTime( cl.worldmodel->name, false );

View File

@ -369,7 +369,6 @@ Set new weapon animation
void CL_WeaponAnim( int iAnim, int body )
{
cl_entity_t *view = &clgame.viewent;
static int viewmodel = -1;
view->curstate.modelindex = cl.frame.local.client.viewmodel;

View File

@ -3846,6 +3846,7 @@ void CL_UnloadProgs( void )
CL_FreeViewBeams();
CL_FreeParticles();
CL_ClearAllRemaps();
Mod_ClearUserData();
VGui_Shutdown();
// NOTE: HLFX 0.5 has strange bug: hanging on exit if no map was loaded

View File

@ -1572,7 +1572,7 @@ void CL_Escape_f( void )
if( UI_CreditsActive( )) return;
if( cls.state == ca_cinematic )
SCR_StopCinematic();
SCR_NextMovie(); // jump to next movie
else UI_SetActiveMenu( true );
}
@ -1787,9 +1787,9 @@ void CL_Init( void )
cls.initialized = true;
cl.maxclients = 1; // allow to drawing player in menu
cls.demonum = -1;
}
/*
===============
CL_Shutdown

View File

@ -611,7 +611,7 @@ void CL_ParseServerData( sizebuf_t *msg )
CL_InitEdicts (); // re-arrange edicts
// get splash name
Cvar_Set( "cl_levelshot_name", va( "levelshots/%s", clgame.mapname ));
Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, glState.wideScreen ? "16x9" : "4x3" ));
Cvar_SetFloat( "scr_loading", 0.0f ); // reset progress bar
if(( cl_allow_levelshots->integer && !cls.changelevel ) || cl.background )

View File

@ -800,6 +800,7 @@ void SCR_InitCinematic( void );
void SCR_FreeCinematic( void );
qboolean SCR_PlayCinematic( const char *name );
qboolean SCR_DrawCinematic( void );
qboolean SCR_NextMovie( void );
void SCR_RunCinematic( void );
void SCR_StopCinematic( void );
void CL_PlayVideo_f( void );

View File

@ -451,6 +451,9 @@ void VID_ImageAdjustGamma( byte *in, uint width, uint height )
byte r_gammaTable[256]; // adjust screenshot gamma
byte *p = in;
if( !gl_compensate_gamma_screenshots->integer )
return;
// rebuild the gamma table
for( i = 0; i < 256; i++ )
{
@ -499,8 +502,16 @@ qboolean VID_ScreenShot( const char *filename, int shot_type )
break;
case VID_LEVELSHOT:
flags |= IMAGE_RESAMPLE;
height = 384;
width = 512;
if( glState.wideScreen )
{
height = 480;
width = 800;
}
else
{
height = 480;
width = 640;
}
break;
case VID_MINISHOT:
flags |= IMAGE_RESAMPLE;

View File

@ -2186,7 +2186,8 @@ void CL_ReadLineFile_f( void )
if( !CL_BeamPoints( p1, p2, modelIndex, 99999, 2, 0, 255, 0, 0, 0, 255.0f, 0.0f, 0.0f ))
{
if( !modelIndex ) MsgDev( D_ERROR, "CL_ReadLineFile: no beam sprite!\n" );
if( Mod_GetType( modelIndex ) != mod_sprite )
MsgDev( D_ERROR, "CL_ReadLineFile: failed to load sprites/laserbeam.spr!\n" );
else MsgDev( D_ERROR, "CL_ReadLineFile: not enough free beams!\n" );
break;
}

View File

@ -536,11 +536,7 @@ msurfmesh_t *R_DecalCreateMesh( decalinfo_t *decalinfo, decal_t *pdecal, msurfac
// allocate mesh
numElems = (numVerts - 2) * 3;
// mesh + ( vertex, normal, (st + lmst) ) * numVerts + elem * numElems;
bufSize = sizeof( msurfmesh_t ) + numVerts * ( sizeof( vec3_t ) + sizeof( vec3_t ) + sizeof( vec4_t )) + numElems * sizeof( word );
bufSize += numVerts * ( sizeof( vec3_t ) + sizeof( vec3_t )); // tangent and binormal
bufSize += numVerts * sizeof( rgba_t ); // color array
bufSize = sizeof( msurfmesh_t ) + numVerts * sizeof( glvert_t ) + numElems * sizeof( word );
buffer = Mem_Alloc( cls.mempool, bufSize );
mesh = (msurfmesh_t *)buffer;
@ -549,22 +545,9 @@ msurfmesh_t *R_DecalCreateMesh( decalinfo_t *decalinfo, decal_t *pdecal, msurfac
mesh->numElems = numElems;
// setup pointers
mesh->vertices = (vec3_t *)buffer;
buffer += numVerts * sizeof( vec3_t );
mesh->stcoords = (vec2_t *)buffer;
buffer += numVerts * sizeof( vec2_t );
mesh->lmcoords = (vec2_t *)buffer;
buffer += numVerts * sizeof( vec2_t );
mesh->normals = (vec3_t *)buffer;
buffer += numVerts * sizeof( vec3_t );
mesh->tangent = (vec3_t *)buffer;
buffer += numVerts * sizeof( vec3_t );
mesh->binormal = (vec3_t *)buffer;
buffer += numVerts * sizeof( vec3_t );
mesh->colors = (byte *)buffer;
buffer += numVerts * sizeof( rgba_t );
mesh->indices = (word *)buffer;
mesh->verts = (glvert_t *)buffer;
buffer += numVerts * sizeof( glvert_t );
mesh->elems = (word *)buffer;
buffer += numElems * sizeof( word );
mesh->surf = surf; // NOTE: meshchains can be linked with one surface
@ -572,26 +555,29 @@ msurfmesh_t *R_DecalCreateMesh( decalinfo_t *decalinfo, decal_t *pdecal, msurfac
// create indices
for( i = 0; i < mesh->numVerts - 2; i++ )
{
mesh->indices[i*3+0] = 0;
mesh->indices[i*3+1] = i + 1;
mesh->indices[i*3+2] = i + 2;
mesh->elems[i*3+0] = 0;
mesh->elems[i*3+1] = i + 1;
mesh->elems[i*3+2] = i + 2;
}
// clear colors (it can be used for vertex lighting)
Q_memset( mesh->colors, 0xFF, numVerts * sizeof( rgba_t ));
// fill the mesh
for( i = 0; i < numVerts; i++, v += VERTEXSIZE )
{
VectorCopy( v, mesh->vertices[i] );
VectorCopy( decalinfo->m_Basis[0], mesh->tangent[i] );
VectorCopy( decalinfo->m_Basis[1], mesh->binormal[i] );
VectorCopy( decalinfo->m_Basis[2], mesh->normals[i] );
glvert_t *out = &mesh->verts[i];
VectorCopy( v, out->vertex );
VectorCopy( decalinfo->m_Basis[0], out->tangent );
VectorCopy( decalinfo->m_Basis[1], out->binormal );
VectorCopy( decalinfo->m_Basis[2], out->normal );
mesh->stcoords[i][0] = v[3];
mesh->stcoords[i][1] = v[4];
mesh->lmcoords[i][0] = v[5];
mesh->lmcoords[i][1] = v[6];
out->stcoord[0] = v[3];
out->stcoord[1] = v[4];
out->lmcoord[0] = v[5];
out->lmcoord[1] = v[6];
out->sccoord[0] = (( DotProduct( v , surf->texinfo->vecs[0] ) + surf->texinfo->vecs[0][3] ) / surf->texinfo->texture->width );
out->sccoord[1] = (( DotProduct( v , surf->texinfo->vecs[1] ) + surf->texinfo->vecs[1][3] ) / surf->texinfo->texture->height );
// clear colors (it can be used for vertex lighting)
Q_memset( out->color, 0xFF, sizeof( out->color ));
}
pdecal->mesh = mesh;
@ -929,11 +915,13 @@ float *R_DecalSetupVerts( decal_t *pDecal, msurface_t *surf, int texture, int *o
// if we have mesh so skip clipping and just copy vertexes out (perf)
for( i = 0, v = g_DecalClipVerts[0]; i < count; i++, v += VERTEXSIZE )
{
VectorCopy( pDecal->mesh->vertices[i], v );
v[3] = pDecal->mesh->stcoords[i][0];
v[4] = pDecal->mesh->stcoords[i][1];
v[5] = pDecal->mesh->lmcoords[i][0];
v[6] = pDecal->mesh->lmcoords[i][1];
glvert_t *p = &pDecal->mesh->verts[i];
VectorCopy( p->vertex, v );
v[3] = p->stcoord[0];
v[4] = p->stcoord[1];
v[5] = p->lmcoord[0];
v[6] = p->lmcoord[1];
}
// restore pointer

View File

@ -505,6 +505,40 @@ typedef float GLmatrix[16];
#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B
#define GL_TEXTURE_RED_TYPE_ARB 0x8C10
#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11
#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12
#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13
#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14
#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15
#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16
#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17
#define GL_RGBA32F_ARB 0x8814
#define GL_RGB32F_ARB 0x8815
#define GL_ALPHA32F_ARB 0x8816
#define GL_INTENSITY32F_ARB 0x8817
#define GL_LUMINANCE32F_ARB 0x8818
#define GL_LUMINANCE_ALPHA32F_ARB 0x8819
#define GL_RGBA16F_ARB 0x881A
#define GL_RGB16F_ARB 0x881B
#define GL_ALPHA16F_ARB 0x881C
#define GL_INTENSITY16F_ARB 0x881D
#define GL_LUMINANCE16F_ARB 0x881E
#define GL_LUMINANCE_ALPHA16F_ARB 0x881F
#define GL_RGBA_FLOAT32_ATI 0x8814
#define GL_RGB_FLOAT32_ATI 0x8815
#define GL_ALPHA_FLOAT32_ATI 0x8816
#define GL_INTENSITY_FLOAT32_ATI 0x8817
#define GL_LUMINANCE_FLOAT32_ATI 0x8818
#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819
#define GL_RGBA_FLOAT16_ATI 0x881A
#define GL_RGB_FLOAT16_ATI 0x881B
#define GL_ALPHA_FLOAT16_ATI 0x881C
#define GL_INTENSITY_FLOAT16_ATI 0x881D
#define GL_LUMINANCE_FLOAT16_ATI 0x881E
#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F
//GL_ARB_vertex_buffer_object
#define GL_ARRAY_BUFFER_ARB 0x8892
#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893

View File

@ -199,7 +199,7 @@ void GL_TexFilter( gltexture_t *tex, qboolean update )
}
// set texture anisotropy if available
if( GL_Support( GL_ANISOTROPY_EXT ))
if( GL_Support( GL_ANISOTROPY_EXT ) && !( tex->flags & TF_ALPHACONTRAST ))
pglTexParameterf( tex->target, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_anisotropy->value );
// set texture LOD bias if available
@ -441,6 +441,30 @@ void R_TextureList_f( void )
case GL_DEPTH_COMPONENT:
Msg( "DEPTH " );
break;
case GL_LUMINANCE16F_ARB:
Msg( "L16F " );
break;
case GL_LUMINANCE32F_ARB:
Msg( "L32F " );
break;
case GL_LUMINANCE_ALPHA16F_ARB:
Msg( "LA16F " );
break;
case GL_LUMINANCE_ALPHA32F_ARB:
Msg( "LA32F " );
break;
case GL_RGB16F_ARB:
Msg( "RGB16F" );
break;
case GL_RGB32F_ARB:
Msg( "RGB32F" );
break;
case GL_RGBA16F_ARB:
Msg( "RGBA16F" );
break;
case GL_RGBA32F_ARB:
Msg( "RGBA32F" );
break;
default:
Msg( "????? " );
break;
@ -638,6 +662,43 @@ static GLenum GL_TextureFormat( gltexture_t *tex, int *samples )
format = GL_DEPTH_COMPONENT;
tex->flags &= ~TF_INTENSITY;
}
else if( tex->flags & TF_FLOAT && GL_Support( GL_ARB_TEXTURE_FLOAT_EXT ))
{
int bits = glw_state.desktopBitsPixel;
switch( *samples )
{
case 1:
switch( bits )
{
case 16: format = GL_LUMINANCE16F_ARB; break;
default: format = GL_LUMINANCE32F_ARB; break;
}
break;
case 2:
switch( bits )
{
case 16: format = GL_LUMINANCE_ALPHA16F_ARB; break;
default: format = GL_LUMINANCE_ALPHA32F_ARB; break;
}
break;
case 3:
switch( bits )
{
case 16: format = GL_RGB16F_ARB; break;
default: format = GL_RGB32F_ARB; break;
}
break;
case 4:
default:
switch( bits )
{
case 16: format = GL_RGBA16F_ARB; break;
default: format = GL_RGBA32F_ARB; break;
}
break;
}
}
else if( compress )
{
switch( *samples )
@ -895,7 +956,7 @@ void GL_GenerateMipmaps( byte *buffer, rgbdata_t *pic, gltexture_t *tex, GLenum
if( tex->flags & TF_NOMIPMAP )
return;
if( GL_Support( GL_SGIS_MIPMAPS_EXT ) && !( tex->flags & TF_NORMALMAP ))
if( GL_Support( GL_SGIS_MIPMAPS_EXT ) && !( tex->flags & ( TF_NORMALMAP|TF_ALPHACONTRAST )))
{
pglHint( GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST );
pglTexParameteri( glTarget, GL_GENERATE_MIPMAP_SGIS, GL_TRUE );
@ -914,7 +975,8 @@ void GL_GenerateMipmaps( byte *buffer, rgbdata_t *pic, gltexture_t *tex, GLenum
while( w > 1 || h > 1 )
{
// build the mipmap
GL_BuildMipMap( buffer, w, h, ( tex->flags & TF_NORMALMAP ));
if( tex->flags & TF_ALPHACONTRAST ) Q_memset( buffer, pic->width >> mipLevel, w * h * 4 );
else GL_BuildMipMap( buffer, w, h, ( tex->flags & TF_NORMALMAP ));
w = (w+1)>>1;
h = (h+1)>>1;
@ -1144,11 +1206,11 @@ static void GL_UploadTexture( rgbdata_t *pic, gltexture_t *tex, qboolean subImag
}
else
{
if( GL_Support( GL_SGIS_MIPMAPS_EXT ) && !( tex->flags & TF_NORMALMAP ))
if( GL_Support( GL_SGIS_MIPMAPS_EXT ) && !( tex->flags & ( TF_NORMALMAP|TF_ALPHACONTRAST )))
GL_GenerateMipmaps( data, pic, tex, glTarget, inFormat, i, subImage );
if( subImage ) pglTexSubImage2D( tex->target, 0, 0, 0, tex->width, tex->height, inFormat, dataType, data );
else pglTexImage2D( tex->target, 0, outFormat, tex->width, tex->height, 0, inFormat, dataType, data );
if( !GL_Support( GL_SGIS_MIPMAPS_EXT ) || ( tex->flags & TF_NORMALMAP ))
if( !GL_Support( GL_SGIS_MIPMAPS_EXT ) || ( tex->flags & ( TF_NORMALMAP|TF_ALPHACONTRAST )))
GL_GenerateMipmaps( data, pic, tex, glTarget, inFormat, i, subImage );
}
@ -2198,6 +2260,44 @@ static rgbdata_t *R_ClearPixels( rgbdata_t *in, qboolean clearAlpha )
return in;
}
/*
================
R_MovePixels
move alpha-channel into color or back
================
*/
static rgbdata_t *R_MovePixels( rgbdata_t *in, qboolean alphaToColor )
{
byte *pic;
int i;
// make sure what we processing RGBA images
in = R_ForceImageToRGBA( in );
pic = in->buffer;
if( alphaToColor )
{
for( i = 0; ( i < in->width * in->height ) && ( in->flags & IMAGE_HAS_ALPHA ); i++ )
{
pic[(i<<2)+0] = pic[(i<<2)+1] = pic[(i<<2)+2] = pic[(i<<2)+3]; // move from alpha to color
pic[(i<<2)+3] = 0xFF; // clear alpha channel
}
}
else
{
// clear color or greyscale image otherwise
for( i = 0; i < in->width * in->height; i++ )
{
// convert to grayscale
pic[(i<<2)+3] = (pic[(i<<2)+0] * 0.32f) + (pic[(i<<2)+0] * 0.59f) + (pic[(i<<2)+0] * 0.09f);
pic[(i<<2)+0] = pic[(i<<2)+1] = pic[(i<<2)+2] = 0x00; // clear RGB channels
}
}
return in;
}
/*
==============================================================================
@ -3326,6 +3426,64 @@ static rgbdata_t *R_ParseClearPixels( char **script, int *samples, texFlags_t *f
return R_ClearPixels( pic, clearAlpha );
}
/*
=================
R_ParseMovePixels
=================
*/
static rgbdata_t *R_ParseMovePixels( char **script, int *samples, texFlags_t *flags )
{
char token[256];
qboolean alphaToColor;
rgbdata_t *pic;
*script = COM_ParseFile( *script, token );
if( Q_stricmp( token, "(" ))
{
MsgDev( D_WARN, "expected '(', found '%s' instead for 'movePixels'\n", token );
return NULL;
}
if(( *script = COM_ParseFile( *script, token )) == NULL )
{
MsgDev( D_WARN, "missing parameters for 'movePixels'\n" );
return NULL;
}
pic = R_LoadImage( script, token, NULL, 0, samples, flags );
if( !pic ) return NULL;
*script = COM_ParseFile( *script, token );
if( !Q_stricmp( token, "AlphaToColor" ))
{
*script = COM_ParseFile( *script, token );
alphaToColor = true;
}
else if( !Q_stricmp( token, "ColorToAlpha" ))
{
*script = COM_ParseFile( *script, token );
alphaToColor = false;
}
else if( !Q_stricmp( token, ")" ))
{
alphaToColor = true; // move alpha to color as default
}
else *script = COM_ParseFile( *script, token ); // skip unknown token
if( Q_stricmp( token, ")" ))
{
MsgDev( D_WARN, "expected ')', found '%s' instead for 'movePixels'\n", token );
FS_FreeImage( pic );
return NULL;
}
*samples = alphaToColor ? 3 : 1;
if( alphaToColor ) *flags &= ~TF_HAS_ALPHA;
*flags &= ~TF_INTENSITY;
return R_MovePixels( pic, alphaToColor );
}
/*
=================
R_LoadImage
@ -3365,6 +3523,8 @@ static rgbdata_t *R_LoadImage( char **script, const char *name, const byte *buf,
return R_ParseDepthmap( script, buf, size, samples, flags );
else if( !Q_stricmp( name, "clearPixels" ))
return R_ParseClearPixels( script, samples, flags );
else if( !Q_stricmp( name, "movePixels" ))
return R_ParseMovePixels( script, samples, flags );
else if( !Q_stricmp( name, "Studio" ))
return R_ParseStudioSkin( script, buf, size, samples, flags );
else if( !Q_stricmp( name, "Sprite" ))
@ -3648,6 +3808,34 @@ static rgbdata_t *R_InitBlankBumpTexture( texFlags_t *flags )
return &r_image;
}
/*
==================
R_InitBlankDeluxeTexture
==================
*/
static rgbdata_t *R_InitBlankDeluxeTexture( texFlags_t *flags )
{
int i;
// default normalmap texture
for( i = 0; i < 256; i++ )
{
data2D[i*4+0] = 127;
data2D[i*4+1] = 127;
data2D[i*4+2] = 0; // light from ceiling
}
*flags = TF_NORMALMAP|TF_UNCOMPRESSED;
r_image.buffer = data2D;
r_image.width = r_image.height = 16;
r_image.size = r_image.width * r_image.height * 4;
r_image.flags = IMAGE_HAS_COLOR;
r_image.type = PF_RGBA_32;
return &r_image;
}
/*
==================
R_InitAttenuationTexture
@ -3959,6 +4147,29 @@ static rgbdata_t *R_InitWhiteCubemap( texFlags_t *flags )
return &r_image;
}
/*
==================
R_InitAlphaContrast
==================
*/
static rgbdata_t *R_InitAlphaContrast( texFlags_t *flags )
{
int size = 64;
byte *data = data2D;
*flags = (TF_NOPICMIP|TF_UNCOMPRESSED|TF_ALPHACONTRAST|TF_INTENSITY);
r_image.width = r_image.height = 64;
r_image.size = r_image.width * r_image.height * 4;
Q_memset( data, size, r_image.size );
r_image.buffer = data2D;
r_image.type = PF_RGBA_32;
return &r_image;
}
/*
==================
R_InitBuiltinTextures
@ -3993,11 +4204,13 @@ static void R_InitBuiltinTextures( void )
{ "*attnno", &tr.attenuationStubTexture, R_InitAttenuationTextureNoAtten, TEX_SYSTEM },
{ "*normalize", &tr.normalizeTexture, R_InitNormalizeCubemap, TEX_CUBEMAP },
{ "*blankbump", &tr.blankbumpTexture, R_InitBlankBumpTexture, TEX_SYSTEM },
{ "*blankdeluxe", &tr.blankdeluxeTexture, R_InitBlankDeluxeTexture, TEX_SYSTEM },
{ "*lightCube", &tr.dlightCubeTexture, R_InitDlightCubemap, TEX_CUBEMAP },
{ "*grayCube", &tr.grayCubeTexture, R_InitGrayCubemap, TEX_CUBEMAP },
{ "*whiteCube", &tr.whiteCubeTexture, R_InitWhiteCubemap, TEX_CUBEMAP },
{ "*atten3D", &tr.attenuationTexture3D, R_InitAttenTexture3D, TEX_SYSTEM },
{ "*sky", &tr.skyTexture, R_InitSkyTexture, TEX_SYSTEM },
{ "*alphaContrast", &tr.acontTexture, R_InitAlphaContrast, TEX_SYSTEM },
{ NULL, NULL, NULL }
};
size_t i, num_builtin_textures = sizeof( textures ) / sizeof( textures[0] ) - 1;

View File

@ -160,6 +160,7 @@ typedef struct
int whiteTexture;
int grayTexture;
int blackTexture;
int acontTexture;
int defaultTexture; // use for bad textures
int particleTexture; // particle texture
int particleTexture2; // unsmoothed particle texture
@ -174,6 +175,7 @@ typedef struct
int attenuationTexture3D;// 3D attenuation
int attenuationStubTexture;
int blankbumpTexture;
int blankdeluxeTexture;
int normalizeTexture;
int dlightCubeTexture; // dynamic cubemap
int grayCubeTexture;
@ -518,6 +520,7 @@ enum
GL_CUSTOM_VERTEX_ARRAY_EXT,
GL_TEXTURE_ENV_ADD_EXT,
GL_CLAMP_TEXBORDER_EXT,
GL_ARB_TEXTURE_FLOAT_EXT,
GL_DEPTH_TEXTURE,
GL_SHADOW_EXT,
GL_EXTCOUNT, // must be last
@ -621,6 +624,7 @@ extern convar_t *gl_texture_lodbias;
extern convar_t *gl_showtextures;
extern convar_t *gl_compress_textures;
extern convar_t *gl_luminance_textures;
extern convar_t *gl_compensate_gamma_screenshots;
extern convar_t *gl_keeptjunctions;
extern convar_t *gl_detailscale;
extern convar_t *gl_overview; // draw map in overview mode

View File

@ -408,6 +408,9 @@ void R_ClearStaticEntities( void )
{
int i;
if( host.type == HOST_DEDICATED )
return;
// clear out efrags in case the level hasn't been reloaded
for( i = 0; i < cl.worldmodel->numleafs; i++ )
cl.worldmodel->leafs[i+1].efrags = NULL;

View File

@ -1503,7 +1503,7 @@ void R_StudioDynamicLight( cl_entity_t *ent, alight_t *lightinfo )
VectorSubtract( dl->origin, origin, direction );
dist = VectorLength( direction );
if( !dist || dist > dl->radius + ent->model->radius )
if( !dist || dist > dl->radius + studio_radius )
continue;
radius2 = dl->radius * dl->radius; // squared radius
@ -1589,7 +1589,7 @@ void R_StudioEntityLight( alight_t *lightinfo )
VectorSubtract( el->origin, origin, direction );
dist = VectorLength( direction );
if( !dist || dist > el->radius + ent->model->radius )
if( !dist || dist > el->radius + studio_radius )
continue;
radius2 = el->radius * el->radius; // squared radius
@ -2020,6 +2020,7 @@ static void R_StudioDrawPoints( void )
else if( g_nFaceFlags & STUDIO_NF_TRANSPARENT )
{
GL_SetRenderMode( kRenderTransAlpha );
pglAlphaFunc( GL_GREATER, 0.0f );
alpha = 1.0f;
}
else if( g_nFaceFlags & STUDIO_NF_ADDITIVE )
@ -2570,6 +2571,8 @@ static void R_StudioSetupRenderer( int rendermode )
if( glState.drawTrans && g_iRenderMode != kRenderTransAdd )
pglDepthMask( GL_TRUE );
pglAlphaFunc( GL_GREATER, 0.0f );
if( g_iBackFaceCull )
GL_FrontFace( true );
}

View File

@ -34,6 +34,7 @@ convar_t *gl_ignorehwgamma;
convar_t *gl_texture_anisotropy;
convar_t *gl_compress_textures;
convar_t *gl_luminance_textures;
convar_t *gl_compensate_gamma_screenshots;
convar_t *gl_keeptjunctions;
convar_t *gl_texture_lodbias;
convar_t *gl_showtextures;
@ -1517,6 +1518,7 @@ void GL_InitCommands( void )
gl_texture_lodbias = Cvar_Get( "gl_texture_lodbias", "0.0", CVAR_ARCHIVE, "LOD bias for mipmapped textures" );
gl_compress_textures = Cvar_Get( "gl_compress_textures", "0", CVAR_GLCONFIG, "compress textures to safe video memory" );
gl_luminance_textures = Cvar_Get( "gl_luminance_textures", "0", CVAR_GLCONFIG, "force all textures to luminance" );
gl_compensate_gamma_screenshots = Cvar_Get( "gl_compensate_gamma_screenshots", "0", CVAR_ARCHIVE, "allow to apply gamma value for screenshots and snapshots" );
gl_keeptjunctions = Cvar_Get( "gl_keeptjunctions", "1", CVAR_ARCHIVE, "disable to reduce vertexes count but removing tjuncs causes blinking pixels" );
gl_allow_static = Cvar_Get( "gl_allow_static", "0", CVAR_ARCHIVE, "force to drawing non-moveable brushes as part of world (save FPS)" );
gl_allow_mirrors = Cvar_Get( "gl_allow_mirrors", "1", CVAR_ARCHIVE, "allow to draw mirror surfaces" );
@ -1669,6 +1671,8 @@ void GL_InitExtensions( void )
GL_CheckExtension( "GL_ARB_depth_texture", NULL, "gl_depthtexture", GL_DEPTH_TEXTURE );
GL_CheckExtension( "GL_ARB_shadow", NULL, "gl_arb_shadow", GL_SHADOW_EXT );
GL_CheckExtension( "GL_ARB_texture_float", NULL, "gl_arb_texture_float", GL_ARB_TEXTURE_FLOAT_EXT );
// occlusion queries
GL_CheckExtension( "GL_ARB_occlusion_query", occlusionfunc, "gl_occlusion_queries", GL_OCCLUSION_QUERIES_EXT );

View File

@ -16,8 +16,7 @@ GNU General Public License for more details.
#ifndef VOX_H
#define VOX_H
#define CVOXWORDMAX 32
#define CVOXSENTENCEMAX 24
#define CVOXWORDMAX 64
#define CVOXZEROSCANMAX 255 // scan up to this many samples for next zero crossing
#define MAX_SENTENCES 2048
#define SENTENCE_INDEX -99999 // unique sentence index

View File

@ -422,14 +422,14 @@ Con_Printf
*/
void Con_Printf( char *szFmt, ... )
{
char buffer[2048]; // must support > 1k messages
va_list args;
static char buffer[16384]; // must support > 1k messages
va_list args;
if( host.developer <= 0 )
return;
va_start( args, szFmt );
Q_vsnprintf( buffer, 2048, szFmt, args );
Q_vsnprintf( buffer, 16384, szFmt, args );
va_end( args );
Sys_Print( buffer );
@ -443,14 +443,14 @@ Con_DPrintf
*/
void Con_DPrintf( char *szFmt, ... )
{
char buffer[2048]; // must support > 1k messages
va_list args;
static char buffer[16384]; // must support > 1k messages
va_list args;
if( host.developer < D_INFO )
return;
va_start( args, szFmt );
Q_vsnprintf( buffer, 2048, szFmt, args );
Q_vsnprintf( buffer, 16384, szFmt, args );
va_end( args );
Sys_Print( buffer );

View File

@ -553,6 +553,17 @@ qboolean Image_Copy8bitRGBA( const byte *in, byte *out, int pixels )
fin[i] = fin[i] < 224 ? fin[i] : 0;
}
// check for color
for( i = 0; i < 256; i++ )
{
col = (rgba_t *)image.d_currentpal[i];
if( col[0] != col[1] || col[1] != col[2] )
{
image.flags |= IMAGE_HAS_COLOR;
break;
}
}
while( pixels >= 8 )
{
iout[0] = image.d_currentpal[in[0]];
@ -564,10 +575,6 @@ qboolean Image_Copy8bitRGBA( const byte *in, byte *out, int pixels )
iout[6] = image.d_currentpal[in[6]];
iout[7] = image.d_currentpal[in[7]];
col = (rgba_t *)iout;
if( col[0] != col[1] || col[1] != col[2] )
image.flags |= IMAGE_HAS_COLOR;
in += 8;
iout += 8;
pixels -= 8;
@ -595,6 +602,7 @@ qboolean Image_Copy8bitRGBA( const byte *in, byte *out, int pixels )
iout[0] = image.d_currentpal[in[0]];
image.type = PF_RGBA_32; // update image type;
return true;
}

View File

@ -589,6 +589,8 @@ void Key_Event( int key, qboolean down )
{
kb = keys[key].binding;
if( cls.key_dest == key_game && ( key != K_ESCAPE ))
clgame.dllFuncs.pfnKey_Event( down, key, kb );
Key_AddKeyUpCommands( key, kb );
return;
}

View File

@ -101,6 +101,7 @@ extern int bmodel_version; // only actual during loading
void Mod_Init( void );
void Mod_ClearAll( void );
void Mod_Shutdown( void );
void Mod_ClearUserData( void );
void Mod_PrintBSPFileSizes( void );
void Mod_SetupHulls( vec3_t mins[MAX_MAP_HULLS], vec3_t maxs[MAX_MAP_HULLS] );
void Mod_GetBounds( int handle, vec3_t mins, vec3_t maxs );

View File

@ -21,6 +21,7 @@ GNU General Public License for more details.
#include "world.h"
#include "gl_local.h"
#include "features.h"
#include "client.h"
#define MAX_SIDE_VERTS 512 // per one polygon
@ -475,6 +476,24 @@ void Mod_AmbientLevels( const vec3_t p, byte *pvolumes )
*(int *)pvolumes = *(int *)leaf->ambient_sound_level;
}
/*
================
Mod_FreeUserData
================
*/
static void Mod_FreeUserData( model_t *mod )
{
// already freed?
if( !mod || !mod->name[0] )
return;
if( clgame.drawFuncs.Mod_ProcessUserData != NULL )
{
// let the client.dll free custom data
clgame.drawFuncs.Mod_ProcessUserData( mod, false );
}
}
/*
================
Mod_FreeModel
@ -486,6 +505,8 @@ static void Mod_FreeModel( model_t *mod )
if( !mod || !mod->name[0] )
return;
Mod_FreeUserData( mod );
// select the properly unloader
switch( mod->type )
{
@ -536,6 +557,14 @@ void Mod_ClearAll( void )
cm_nummodels = 0;
}
void Mod_ClearUserData( void )
{
int i;
for( i = 0; i < cm_nummodels; i++ )
Mod_FreeUserData( &cm_models[i] );
}
void Mod_Shutdown( void )
{
Mod_ClearAll();
@ -1291,11 +1320,7 @@ static void Mod_BuildPolygon( mextrasurf_t *info, msurface_t *surf, int numVerts
// allocate mesh
numElems = (numVerts - 2) * 3;
// mesh + ( vertex, normal, (st + lmst) ) * numVerts + elem * numElems;
bufSize = sizeof( msurfmesh_t ) + numVerts * ( sizeof( vec3_t ) + sizeof( vec3_t ) + sizeof( vec4_t )) + numElems * sizeof( word );
bufSize += numVerts * ( sizeof( vec3_t ) + sizeof( vec3_t )); // tangent and binormal
bufSize += numVerts * sizeof( rgba_t ); // color array
bufSize = sizeof( msurfmesh_t ) + numVerts * sizeof( glvert_t ) + numElems * sizeof( word );
buffer = Mem_Alloc( loadmodel->mempool, bufSize );
mesh = (msurfmesh_t *)buffer;
@ -1315,22 +1340,9 @@ static void Mod_BuildPolygon( mextrasurf_t *info, msurface_t *surf, int numVerts
VectorNormalize( binormal );
// setup pointers
mesh->vertices = (vec3_t *)buffer;
buffer += numVerts * sizeof( vec3_t );
mesh->stcoords = (vec2_t *)buffer;
buffer += numVerts * sizeof( vec2_t );
mesh->lmcoords = (vec2_t *)buffer;
buffer += numVerts * sizeof( vec2_t );
mesh->normals = (vec3_t *)buffer;
buffer += numVerts * sizeof( vec3_t );
mesh->tangent = (vec3_t *)buffer;
buffer += numVerts * sizeof( vec3_t );
mesh->binormal = (vec3_t *)buffer;
buffer += numVerts * sizeof( vec3_t );
mesh->colors = (byte *)buffer;
buffer += numVerts * sizeof( rgba_t );
mesh->indices = (word *)buffer;
mesh->verts = (glvert_t *)buffer;
buffer += numVerts * sizeof( glvert_t );
mesh->elems = (word *)buffer;
buffer += numElems * sizeof( word );
mesh->next = info->mesh;
@ -1340,21 +1352,20 @@ static void Mod_BuildPolygon( mextrasurf_t *info, msurface_t *surf, int numVerts
// create indices
for( i = 0; i < mesh->numVerts - 2; i++ )
{
mesh->indices[i*3+0] = 0;
mesh->indices[i*3+1] = i + 1;
mesh->indices[i*3+2] = i + 2;
mesh->elems[i*3+0] = 0;
mesh->elems[i*3+1] = i + 1;
mesh->elems[i*3+2] = i + 2;
}
// clear colors (it can be used for vertex lighting)
Q_memset( mesh->colors, 0xFF, numVerts * sizeof( rgba_t ));
for( i = 0; i < numVerts; i++, verts += 3 )
{
glvert_t *out = &mesh->verts[i];
// vertex
VectorCopy( verts, mesh->vertices[i] );
VectorCopy( tangent, mesh->tangent[i] );
VectorCopy( binormal, mesh->binormal[i] );
VectorCopy( normal, mesh->normals[i] );
VectorCopy( verts, out->vertex );
VectorCopy( tangent, out->tangent );
VectorCopy( binormal, out->binormal );
VectorCopy( normal, out->normal );
// texture coordinates
s = DotProduct( verts, texinfo->vecs[0] ) + texinfo->vecs[0][3];
@ -1363,8 +1374,8 @@ static void Mod_BuildPolygon( mextrasurf_t *info, msurface_t *surf, int numVerts
t = DotProduct( verts, texinfo->vecs[1] ) + texinfo->vecs[1][3];
t /= texinfo->texture->height;
mesh->stcoords[i][0] = s;
mesh->stcoords[i][1] = t;
out->stcoord[0] = s;
out->stcoord[1] = t;
// lightmap texture coordinates
s = DotProduct( verts, texinfo->vecs[0] ) + texinfo->vecs[0][3] - surf->texturemins[0];
@ -1377,8 +1388,11 @@ static void Mod_BuildPolygon( mextrasurf_t *info, msurface_t *surf, int numVerts
t += LM_SAMPLE_SIZE >> 1;
t /= BLOCK_SIZE * LM_SAMPLE_SIZE;
mesh->lmcoords[i][0] = s;
mesh->lmcoords[i][1] = t;
out->lmcoord[0] = s;
out->lmcoord[1] = t;
// clear colors (it can be used for vertex lighting)
Q_memset( out->color, 0xFF, sizeof( out->color ));
}
}
@ -1457,11 +1471,7 @@ static void Mod_SubdividePolygon( mextrasurf_t *info, msurface_t *surf, int numV
return;
}
// mesh + ( vertex, normal, (st + lmst) ) * ( numVerts + 2 );
bufSize = sizeof( msurfmesh_t ) + (( numVerts + 2 ) * (( sizeof( vec3_t ) + sizeof( vec3_t ) + sizeof( vec4_t ))));
bufSize += ( numVerts + 2 ) * ( sizeof( vec3_t ) + sizeof( vec3_t )); // tangent and binormal
bufSize += ( numVerts + 2 ) * sizeof( rgba_t ); // color array
bufSize = sizeof( msurfmesh_t ) + ( numVerts + 2 ) * sizeof( glvert_t ); // temp buffer has no indices
buffer = Mem_Alloc( loadmodel->mempool, bufSize );
mesh = (msurfmesh_t *)buffer;
@ -1483,20 +1493,8 @@ static void Mod_SubdividePolygon( mextrasurf_t *info, msurface_t *surf, int numV
VectorNormalize( binormal );
// setup pointers
mesh->vertices = (vec3_t *)buffer;
buffer += mesh->numVerts * sizeof( vec3_t );
mesh->stcoords = (vec2_t *)buffer;
buffer += mesh->numVerts * sizeof( vec2_t );
mesh->lmcoords = (vec2_t *)buffer;
buffer += mesh->numVerts * sizeof( vec2_t );
mesh->normals = (vec3_t *)buffer;
buffer += mesh->numVerts * sizeof( vec3_t );
mesh->tangent = (vec3_t *)buffer;
buffer += mesh->numVerts * sizeof( vec3_t );
mesh->binormal = (vec3_t *)buffer;
buffer += mesh->numVerts * sizeof( vec3_t );
mesh->colors = (byte *)buffer;
buffer += mesh->numVerts * sizeof( rgba_t );
mesh->verts = (glvert_t *)buffer;
buffer += numVerts * sizeof( glvert_t );
VectorClear( vTotal );
VectorClear( nTotal );
@ -1506,23 +1504,22 @@ static void Mod_SubdividePolygon( mextrasurf_t *info, msurface_t *surf, int numV
totalST[0] = totalST[1] = 0;
totalLM[0] = totalLM[1] = 0;
scale = (1.0f / tessSize );
// clear colors (it can be used for vertex lighting)
Q_memset( mesh->colors, 0xFF, mesh->numVerts * sizeof( rgba_t ));
scale = ( 1.0f / tessSize );
for( i = 0; i < numVerts; i++, verts += 3 )
{
// vertex
VectorCopy( verts, mesh->vertices[i+1] );
VectorCopy( normal, mesh->normals[i+1] );
VectorCopy( tangent, mesh->tangent[i+1] );
VectorCopy( binormal, mesh->binormal[i+1] );
glvert_t *out = &mesh->verts[i+1];
VectorAdd( vTotal, mesh->vertices[i+1], vTotal );
VectorAdd( nTotal, mesh->normals[i+1], nTotal );
VectorAdd( tTotal, mesh->tangent[i+1], tTotal );
VectorAdd( bTotal, mesh->binormal[i+1], bTotal );
// vertex
VectorCopy( verts, out->vertex );
VectorCopy( normal, out->normal );
VectorCopy( tangent, out->tangent );
VectorCopy( binormal, out->binormal );
VectorAdd( vTotal, verts, vTotal );
VectorAdd( nTotal, normal, nTotal );
VectorAdd( tTotal, tangent, tTotal );
VectorAdd( bTotal, binormal, bTotal );
if( lightmap )
{
@ -1540,8 +1537,8 @@ static void Mod_SubdividePolygon( mextrasurf_t *info, msurface_t *surf, int numV
t = DotProduct( verts, texinfo->vecs[1] ) * scale;
}
mesh->stcoords[i+1][0] = s;
mesh->stcoords[i+1][1] = t;
out->stcoord[0] = s;
out->stcoord[1] = t;
totalST[0] += s;
totalST[1] += t;
@ -1564,40 +1561,38 @@ static void Mod_SubdividePolygon( mextrasurf_t *info, msurface_t *surf, int numV
s = t = 0.0f;
}
mesh->lmcoords[i+1][0] = s;
mesh->lmcoords[i+1][1] = t;
out->lmcoord[0] = s;
out->lmcoord[1] = t;
totalLM[0] += s;
totalLM[1] += t;
// clear colors (it can be used for vertex lighting)
Q_memset( out->color, 0xFF, sizeof( out->color ));
}
// vertex
oneDivVerts = ( 1.0f / (float)numVerts );
VectorScale( vTotal, oneDivVerts, mesh->vertices[0] );
VectorScale( nTotal, oneDivVerts, mesh->normals[0] );
VectorScale( tTotal, oneDivVerts, mesh->tangent[0] );
VectorScale( bTotal, oneDivVerts, mesh->binormal[0] );
VectorScale( vTotal, oneDivVerts, mesh->verts[0].vertex );
VectorScale( nTotal, oneDivVerts, mesh->verts[0].normal );
VectorScale( tTotal, oneDivVerts, mesh->verts[0].tangent );
VectorScale( bTotal, oneDivVerts, mesh->verts[0].binormal );
VectorNormalize( mesh->normals[0] );
VectorNormalize( mesh->tangent[0] );
VectorNormalize( mesh->binormal[0] );
VectorNormalize( mesh->verts[0].normal );
VectorNormalize( mesh->verts[0].tangent );
VectorNormalize( mesh->verts[0].binormal );
// texture coordinates
mesh->stcoords[0][0] = totalST[0] * oneDivVerts;
mesh->stcoords[0][1] = totalST[1] * oneDivVerts;
mesh->verts[0].stcoord[0] = totalST[0] * oneDivVerts;
mesh->verts[0].stcoord[1] = totalST[1] * oneDivVerts;
// lightmap texture coordinates
mesh->lmcoords[0][0] = totalLM[0] * oneDivVerts;
mesh->lmcoords[0][1] = totalLM[1] * oneDivVerts;
mesh->verts[0].lmcoord[0] = totalLM[0] * oneDivVerts;
mesh->verts[0].lmcoord[1] = totalLM[1] * oneDivVerts;
// copy first vertex to last
VectorCopy( mesh->vertices[1], mesh->vertices[i+1] );
VectorCopy( mesh->normals[1], mesh->normals[i+1] );
VectorCopy( mesh->tangent[1], mesh->tangent[i+1] );
VectorCopy( mesh->binormal[1], mesh->binormal[i+1] );
Vector2Copy( mesh->stcoords[1], mesh->stcoords[i+1] );
Vector2Copy( mesh->lmcoords[1], mesh->lmcoords[i+1] );
Q_memcpy( &mesh->verts[i+1], &mesh->verts[1], sizeof( glvert_t ));
mesh->next = info->mesh;
mesh->surf = surf; // NOTE: meshchains can be linked with one surface
@ -1614,11 +1609,9 @@ turn the polychain into one subdivided surface
static void Mod_ConvertSurface( mextrasurf_t *info, msurface_t *surf )
{
msurfmesh_t *poly, *next, *mesh;
float *outSTcoords, *outLMcoords;
float *outTangent, *outBinorm;
float *outVerts, *outNorms;
int numElems, numVerts;
word *outIndexes;
glvert_t *outVerts;
word *outElems;
int i, bufSize;
byte *buffer;
@ -1632,15 +1625,11 @@ static void Mod_ConvertSurface( mextrasurf_t *info, msurface_t *surf )
numVerts += poly->numVerts;
}
// mesh + ( vertex, normal, (st + lmst) ) * numVerts + elem * numElems;
bufSize = sizeof( msurfmesh_t ) + numVerts * ( sizeof( vec3_t ) + sizeof( vec3_t ) + sizeof( vec4_t )) + numElems * sizeof( word );
bufSize += numVerts * ( sizeof( vec3_t ) + sizeof( vec3_t )); // tangent and binormal
bufSize += numVerts * sizeof( rgba_t ); // color array
// unsigned short limit
if( numVerts >= 65536 ) Host_Error( "Mod_ConvertSurface: vertex count %i exceeds 65535\n", numVerts );
if( numElems >= 65536 ) Host_Error( "Mod_ConvertSurface: index count %i exceeds 65535\n", numElems );
bufSize = sizeof( msurfmesh_t ) + numVerts * sizeof( glvert_t ) + numElems * sizeof( word );
buffer = Mem_Alloc( loadmodel->mempool, bufSize );
mesh = (msurfmesh_t *)buffer;
@ -1650,73 +1639,34 @@ static void Mod_ConvertSurface( mextrasurf_t *info, msurface_t *surf )
mesh->numElems = numElems;
// setup pointers
mesh->vertices = (vec3_t *)buffer;
buffer += numVerts * sizeof( vec3_t );
mesh->stcoords = (vec2_t *)buffer;
buffer += numVerts * sizeof( vec2_t );
mesh->lmcoords = (vec2_t *)buffer;
buffer += numVerts * sizeof( vec2_t );
mesh->normals = (vec3_t *)buffer;
buffer += numVerts * sizeof( vec3_t );
mesh->tangent = (vec3_t *)buffer;
buffer += numVerts * sizeof( vec3_t );
mesh->binormal = (vec3_t *)buffer;
buffer += numVerts * sizeof( vec3_t );
mesh->colors = (byte *)buffer;
buffer += numVerts * sizeof( rgba_t );
mesh->indices = (word *)buffer;
mesh->verts = (glvert_t *)buffer;
buffer += numVerts * sizeof( glvert_t );
mesh->elems = (word *)buffer;
buffer += numElems * sizeof( word );
// setup moving pointers
outVerts = (float *)mesh->vertices;
outNorms = (float *)mesh->normals;
outTangent = (float *)mesh->tangent;
outBinorm = (float *)mesh->binormal;
outSTcoords = (float *)mesh->stcoords;
outLMcoords = (float *)mesh->lmcoords;
outIndexes = (word *)mesh->indices;
outVerts = (glvert_t *)mesh->verts;
outElems = (word *)mesh->elems;
// store vertex data
numElems = numVerts = 0;
// clear colors (it can be used for vertex lighting)
Q_memset( mesh->colors, 0xFF, numVerts * sizeof( rgba_t ));
for( poly = info->mesh; poly; poly = poly->next )
{
// indexes
outIndexes = mesh->indices + numElems;
numElems += (poly->numVerts - 2) * 3;
outElems = mesh->elems + numElems;
outVerts = mesh->verts + numVerts;
for( i = 0; i < poly->numVerts - 2; i++ )
{
outIndexes[i*3+0] = numVerts;
outIndexes[i*3+1] = numVerts + i + 1;
outIndexes[i*3+2] = numVerts + i + 2;
outElems[i*3+0] = numVerts;
outElems[i*3+1] = numVerts + i + 1;
outElems[i*3+2] = numVerts + i + 2;
}
for( i = 0; i < poly->numVerts; i++ )
{
// vertices
VectorCopy( poly->vertices[i], outVerts );
VectorCopy( poly->normals[i], outNorms );
VectorCopy( poly->tangent[i], outTangent );
VectorCopy( poly->binormal[i], outBinorm );
outSTcoords[0] = poly->stcoords[i][0];
outSTcoords[1] = poly->stcoords[i][1];
outLMcoords[0] = poly->lmcoords[i][0];
outLMcoords[1] = poly->lmcoords[i][1];
outVerts += 3;
outNorms += 3;
outBinorm += 3;
outTangent += 3;
outSTcoords += 2;
outLMcoords += 2;
}
Q_memcpy( outVerts, poly->verts, sizeof( glvert_t ) * poly->numVerts );
numElems += (poly->numVerts - 2) * 3;
numVerts += poly->numVerts;
}
@ -2996,6 +2946,12 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
else MsgDev( D_ERROR, "Mod_ForName: %s couldn't load\n", tempname );
return NULL;
}
else if( clgame.drawFuncs.Mod_ProcessUserData != NULL )
{
// let the client.dll load custom data
clgame.drawFuncs.Mod_ProcessUserData( mod, true );
}
return mod;
}
@ -3028,6 +2984,8 @@ void Mod_LoadWorld( const char *name, uint *checksum, qboolean force )
// now replacement table is invalidate
Q_memset( com_models, 0, sizeof( com_models ));
com_models[1] = cm_models; // make link to world
// update the lightmap blocksize
if( host.features & ENGINE_LARGE_LIGHTMAPS )
world.block_size = BLOCK_SIZE_MAX;
@ -3036,7 +2994,6 @@ void Mod_LoadWorld( const char *name, uint *checksum, qboolean force )
if( !Q_stricmp( cm_models[0].name, name ) && !force )
{
// singleplayer mode: server already loaded map
com_models[1] = cm_models; // make link to world
if( checksum ) *checksum = world.checksum;
// still have the right version
@ -3061,7 +3018,6 @@ void Mod_LoadWorld( const char *name, uint *checksum, qboolean force )
// load the newmap
world.loading = true;
worldmodel = Mod_ForName( name, true );
com_models[1] = cm_models; // make link to world
CRC32_MapFile( &world.checksum, worldmodel->name );
world.loading = false;

Binary file not shown.

Binary file not shown.

BIN
game_launch/hl.exe Normal file

Binary file not shown.