diff --git a/common/com_model.h b/common/com_model.h index 486f78cc..d705dab8 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -83,6 +83,7 @@ typedef struct glpoly_s struct glpoly_s *chain; int numverts; int flags; // for SURF_UNDERWATER +// struct glpoly_s *fb_chain; // next fb poly in chain float verts[4][VERTEXSIZE]; // variable sized (xyz s1t1 s2t2) } glpoly_t; diff --git a/debug.bat b/debug.bat index 8de78396..7f0c2d2e 100644 --- a/debug.bat +++ b/debug.bat @@ -23,9 +23,6 @@ if errorlevel 1 set BUILD_ERROR=1 %MSDEV% launch/launch.dsp %CONFIG%"launch - Win32 Debug" %build_target% if errorlevel 1 set BUILD_ERROR=1 -%MSDEV% vid_gl/vid_gl.dsp %CONFIG%"vid_gl - Win32 Debug" %build_target% -if errorlevel 1 set BUILD_ERROR=1 - if "%BUILD_ERROR%"=="" goto build_ok echo ********************* diff --git a/dlls/monsters.cpp b/dlls/monsters.cpp index e9e94432..1a39c039 100644 --- a/dlls/monsters.cpp +++ b/dlls/monsters.cpp @@ -2090,7 +2090,7 @@ void CBaseMonster :: StartMonster ( void ) // Try to move the monster to make sure it's not stuck in a brush. if (!WALK_MOVE ( ENT(pev), 0, 0, WALKMOVE_NORMAL ) ) { - ALERT(at_error, "Monster %s stuck in wall--level design error", STRING(pev->classname)); + ALERT(at_error, "Monster %s stuck in wall--level design error\n", STRING(pev->classname)); pev->effects = EF_BRIGHTFIELD; } } diff --git a/dlls/triggers.cpp b/dlls/triggers.cpp index bd36a082..258dfe51 100644 --- a/dlls/triggers.cpp +++ b/dlls/triggers.cpp @@ -1407,7 +1407,7 @@ void CChangeLevel :: Spawn( void ) ALERT( at_console, "a trigger_changelevel doesn't have a map" ); if ( FStrEq( m_szLandmarkName, "" ) ) - ALERT( at_console, "trigger_changelevel to %s doesn't have a landmark", m_szMapName ); + ALERT( at_console, "trigger_changelevel to %s doesn't have a landmark\n", m_szMapName ); if (!FStringNull ( pev->targetname ) ) { diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index 1fd6939d..1e68534d 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -1280,7 +1280,6 @@ void CL_FreeEntity( cl_entity_t *pEdict ) void CL_ClearWorld( void ) { cl_entity_t *ent; - int i; ent = EDICT_NUM( 0 ); ent->index = NUM_FOR_EDICT( ent ); @@ -1289,10 +1288,6 @@ void CL_ClearWorld( void ) ent->curstate.movetype = MOVETYPE_PUSH; ent->model = cl.worldmodel; clgame.numEntities = 1; - - // clear the lightstyles - for( i = 0; i < MAX_LIGHTSTYLES; i++ ) - cl.lightstyles[i].value = 1.0f; } void CL_InitEdicts( void ) @@ -2930,13 +2925,19 @@ void Tri_DrawTriangles( int fTrans ) { if( fTrans ) { - CL_DrawBeams( true ); - CL_DrawParticles(); + if( !RI.refdef.onlyClientDraw ) + { + CL_DrawBeams( true ); + CL_DrawParticles(); + } clgame.dllFuncs.pfnDrawTransparentTriangles (); } else { - CL_DrawBeams( false ); + if( !RI.refdef.onlyClientDraw ) + { + CL_DrawBeams( false ); + } clgame.dllFuncs.pfnDrawNormalTriangles (); } } diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 018b487e..991d5d2f 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -25,6 +25,7 @@ convar_t *cl_nodelta; convar_t *cl_crosshair; convar_t *cl_cmdbackup; convar_t *cl_draw_particles; +convar_t *cl_lightstyle_lerping; convar_t *cl_idealpitchscale; convar_t *cl_solid_players; convar_t *cl_draw_beams; @@ -1451,6 +1452,7 @@ void CL_InitLocal( void ) cl_cmdrate = Cvar_Get( "cl_cmdrate", "30", CVAR_ARCHIVE, "Max number of command packets sent to server per second" ); cl_draw_particles = Cvar_Get( "cl_draw_particles", "1", CVAR_ARCHIVE, "Disable any particle effects" ); cl_draw_beams = Cvar_Get( "cl_draw_beams", "1", CVAR_ARCHIVE, "Disable view beams" ); + cl_lightstyle_lerping = Cvar_Get( "cl_lightstyle_lerping", "0", CVAR_ARCHIVE, "enables animated light lerping (perfomance option)" ); Cvar_Get( "hud_scale", "0", CVAR_ARCHIVE|CVAR_LATCH, "scale hud at current resolution" ); Cvar_Get( "skin", "", CVAR_USERINFO, "player skin" ); // XDM 3.3 want this cvar diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 0f8b2585..f7744c26 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -2099,7 +2099,7 @@ LIGHT STYLE MANAGEMENT ============================================================== */ -static int lastofs; +#define STYLE_LERPING_THRESHOLD 3.0f // because we wan't interpolate fast sequences (e.g. on\off) /* ================ @@ -2109,50 +2109,41 @@ CL_ClearLightStyles void CL_ClearLightStyles( void ) { Mem_Set( cl.lightstyles, 0, sizeof( cl.lightstyles )); - lastofs = -1; -} - -/* -================ -CL_RunLightStyles - -light animations -'m' is normal light, 'a' is no light, 'z' is double bright -================ -*/ -void CL_RunLightStyles( void ) -{ - int i, ofs; - lightstyle_t *ls; - - if( cls.state != ca_active ) return; - - ofs = (cl.time * 10); - if( ofs == lastofs ) return; - lastofs = ofs; - - for( i = 0, ls = cl.lightstyles; i < MAX_LIGHTSTYLES; i++, ls++ ) - { - if( ls->length == 0 ) ls->value = 0.0f; // disable light - else if( ls->length == 1 ) ls->value = ls->map[0]; - else ls->value = ls->map[ofs%ls->length]; - } } void CL_SetLightstyle( int style, const char *s ) { - int j, k; + int i, k; + lightstyle_t *ls; + float val1, val2; ASSERT( s ); ASSERT( style >= 0 && style < MAX_LIGHTSTYLES ); - com.strncpy( cl.lightstyles[style].pattern, s, sizeof( cl.lightstyles[0].pattern )); + ls = &cl.lightstyles[style]; - j = com.strlen( s ); - cl.lightstyles[style].length = j; + com.strncpy( ls->pattern, s, sizeof( ls->pattern )); - for( k = 0; k < j; k++ ) - cl.lightstyles[style].map[k] = (float)(s[k]-'a') / (float)('m'-'a'); + ls->length = com.strlen( s ); + + for( i = 0; i < ls->length; i++ ) + ls->map[i] = (float)(s[i] - 'a'); + + ls->interp = true; + + // check for allow interpolate + // NOTE: fast flickering styles looks ugly when interpolation is running + for( k = 0; k < ls->length; k++ ) + { + val1 = ls->map[(k+0) % ls->length]; + val2 = ls->map[(k+1) % ls->length]; + + if( fabs( val1 - val2 ) > STYLE_LERPING_THRESHOLD ) + { + ls->interp = false; + break; + } + } } /* @@ -2268,8 +2259,9 @@ update client flashlight */ void CL_UpadteFlashlight( cl_entity_t *pEnt ) { - vec3_t vecSrc, vecEnd, vecPos; + vec3_t vecSrc, vecEnd; vec3_t forward, view_ofs; + float distLight; pmtrace_t trace; dlight_t *dl; @@ -2312,19 +2304,16 @@ void CL_UpadteFlashlight( cl_entity_t *pEnt ) VectorMA( vecSrc, 512.0f, forward, vecEnd ); trace = PM_PlayerTrace( clgame.pmove, vecSrc, vecEnd, PM_TRACELINE_PHYSENTSONLY, 2, -1, NULL ); - - if( trace.fraction != 1.0f ) - VectorMA( trace.endpos, -16.0f, trace.plane.normal, vecPos ); - else VectorCopy( trace.endpos, vecPos ); + distLight = (1.0f - trace.fraction); // update flashlight endpos dl = CL_AllocDlight( pEnt->index ); - VectorCopy( vecPos, dl->origin ); + VectorCopy( trace.endpos, dl->origin ); dl->die = cl.time + 0.001f; // die on next frame - dl->color.r = 255; - dl->color.g = 255; - dl->color.b = 255; - dl->radius = 96; + dl->color.r = 255 * distLight; + dl->color.g = 255 * distLight; + dl->color.b = 255 * distLight; + dl->radius = 64; } /* diff --git a/engine/client/client.h b/engine/client/client.h index d6ae52ee..7fb5131d 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -484,6 +484,7 @@ extern convar_t *cl_testlights; extern convar_t *cl_solid_players; extern convar_t *cl_idealpitchscale; extern convar_t *cl_allow_levelshots; +extern convar_t *cl_lightstyle_lerping; extern convar_t *cl_draw_particles; extern convar_t *cl_levelshot_name; extern convar_t *cl_draw_beams; diff --git a/engine/client/gl_local.h b/engine/client/gl_local.h index 0232093a..0e5a9bde 100644 --- a/engine/client/gl_local.h +++ b/engine/client/gl_local.h @@ -15,7 +15,7 @@ extern byte *r_temppool; #define MAX_TEXTURES 1024 -#define MAX_LIGHTMAPS 64 +#define MAX_LIGHTMAPS 128 #define SUBDIVIDE_SIZE 64 // refparams @@ -147,6 +147,7 @@ typedef struct matrix4x4 projectionMatrix; matrix4x4 worldviewProjectionMatrix; // worldviewMatrix * projectionMatrix + int lightstylevalue[MAX_LIGHTSTYLES]; mplane_t clipPlane; } ref_instance_t; @@ -164,7 +165,10 @@ typedef struct int lightmapTextures[MAX_LIGHTMAPS]; int skytexturenum; // this not a gl_texturenum! - + + // OpenGL matrix states + qboolean modelviewIdentity; + int visframecount; // PVS frame int dlightframecount; // dynamic light frame int framecount; @@ -184,6 +188,7 @@ extern ref_params_t r_lastRefdef; extern ref_instance_t RI; extern ref_globals_t tr; +extern float gldepthmin, gldepthmax; extern mleaf_t *r_viewleaf, *r_oldviewleaf; extern mleaf_t *r_viewleaf2, *r_oldviewleaf2; extern dlight_t cl_dlights[MAX_DLIGHTS]; @@ -238,12 +243,17 @@ void R_StoreEfrags( efrag_t **ppefrag ); // gl_rlight.c // void R_PushDlights( void ); +void R_AnimateLight( void ); +void R_MarkLights( dlight_t *light, int bit, mnode_t *node ); // // gl_rmain.c // void R_ClearScene( void ); +void R_LoadIdentity( void ); void R_DrawCubemapView( const vec3_t origin, const vec3_t angles, int size ); +void R_TranslateForEntity( cl_entity_t *e ); +void R_RotateForEntity( cl_entity_t *e ); // // gl_rmath.c @@ -256,6 +266,8 @@ void V_AdjustFov( float *fov_x, float *fov_y, float width, float height, qboolea // void R_MarkLeaves( void ); void R_DrawWorld( void ); +void R_DrawWaterSurfaces( void ); +void R_DrawBrushModel( cl_entity_t *e ); void GL_SubdivideSurface( msurface_t *fa ); void GL_BuildPolygonFromSurface( msurface_t *fa ); void GL_BuildLightmaps( void ); @@ -274,7 +286,7 @@ void R_ClearSkyBox( void ); void R_DrawSkyBox( void ); void EmitSkyLayers( msurface_t *fa ); void EmitSkyPolys( msurface_t *fa ); -void EmitWaterPolys( msurface_t *fa ); +void EmitWaterPolys( glpoly_t *polys ); void R_DrawSkyChain( msurface_t *s ); // @@ -363,6 +375,7 @@ typedef struct GLfloat max_texture_lodbias; int color_bits; + int alpha_bits; int depth_bits; int stencil_bits; @@ -440,7 +453,6 @@ extern convar_t *gl_skymip; extern convar_t *gl_nobind; extern convar_t *gl_finish; extern convar_t *gl_clear; -extern convar_t *gl_texsort; extern convar_t *r_width; extern convar_t *r_height; @@ -448,6 +460,7 @@ extern convar_t *r_speeds; extern convar_t *r_fullbright; extern convar_t *r_norefresh; extern convar_t *r_lighting_modulate; +extern convar_t *r_drawentities; extern convar_t *r_adjust_fov; extern convar_t *r_novis; extern convar_t *r_nocull; diff --git a/engine/client/gl_rlight.c b/engine/client/gl_rlight.c index 30c98ab0..7464382d 100644 --- a/engine/client/gl_rlight.c +++ b/engine/client/gl_rlight.c @@ -14,6 +14,63 @@ DYNAMIC LIGHTS ============================================================================= */ +/* +================== +R_AnimateLight + +================== +*/ +void R_AnimateLight( void ) +{ + int i, k, flight, clight; + float l, lerpfrac, backlerp; + lightstyle_t *ls; + + // light animations + // 'm' is normal light, 'a' is no light, 'z' is double bright + flight = (int)floor( cl.time * 10 ); + clight = (int)ceil( cl.time * 10 ); + lerpfrac = ( cl.time * 10 ) - flight; + backlerp = 1.0f - lerpfrac; + + for( i = 0, ls = cl.lightstyles; i < MAX_LIGHTSTYLES; i++, ls++ ) + { + if( r_fullbright->integer || !cl.worldmodel->lightdata ) + { + RI.lightstylevalue[i] = 256 * 256; + continue; + } + + if( !ls->length ) + { + // was 256, changed to 264 for consistency + RI.lightstylevalue[i] = 256 * r_lighting_modulate->value; + continue; + } + else if( ls->length == 1 ) + { + // single length style so don't bother interpolating + RI.lightstylevalue[i] = ls->map[0] * 22 * r_lighting_modulate->value; + continue; + } + else if( !ls->interp || !cl_lightstyle_lerping->integer ) + { + RI.lightstylevalue[i] = ls->map[flight%ls->length] * 22 * r_lighting_modulate->value; + continue; + } + + // interpolate animating light + // frame just gone + k = ls->map[flight % ls->length]; + l = (float)( k * 22 ) * backlerp; + + // upcoming frame + k = ls->map[clight % ls->length]; + l += (float)( k * 22 ) * lerpfrac; + + RI.lightstylevalue[i] = (int)l * r_lighting_modulate->value; + } +} /* ============= @@ -22,7 +79,6 @@ R_MarkLights */ void R_MarkLights( dlight_t *light, int bit, mnode_t *node ) { - mplane_t *splitplane; float dist; msurface_t *surf; int i; @@ -30,9 +86,8 @@ void R_MarkLights( dlight_t *light, int bit, mnode_t *node ) if( node->contents < 0 ) return; - splitplane = node->plane; - dist = DotProduct( light->origin, splitplane->normal ) - splitplane->dist; - + dist = PlaneDiff( light->origin, node->plane ); + if( dist > light->radius ) { R_MarkLights( light, bit, node->children[0] ); diff --git a/engine/client/gl_rmain.c b/engine/client/gl_rmain.c index 01c983b5..3fd05938 100644 --- a/engine/client/gl_rmain.c +++ b/engine/client/gl_rmain.c @@ -18,9 +18,7 @@ mleaf_t *r_viewleaf, *r_oldviewleaf; mleaf_t *r_viewleaf2, *r_oldviewleaf2; uint r_numEntities; -cl_entity_t *r_solid_entities[MAX_VISIBLE_PACKET]; // opaque edicts -cl_entity_t *r_alpha_entities[MAX_VISIBLE_PACKET]; // edicts with rendermode kRenderTransAlpha -cl_entity_t *r_trans_entities[MAX_VISIBLE_PACKET]; // edicts with rendermode kRenderTransTexture, Additive etc +cl_entity_t *r_entities[MAX_VISIBLE_PACKET]; qboolean R_CullBox( const vec3_t mins, const vec3_t maxs ) { @@ -92,7 +90,8 @@ R_ClearScene */ void R_ClearScene( void ) { - r_numEntities = 1; + Mem_Set( r_entities, 0, sizeof( r_entities )); + r_numEntities = 0; } /* @@ -102,7 +101,14 @@ R_AddEntity */ qboolean R_AddEntity( struct cl_entity_s *pRefEntity, int entityType ) { + if( r_numEntities >= MAX_VISIBLE_PACKET ) + return false; + + pRefEntity->curstate.entityType = entityType; + + r_entities[r_numEntities] = pRefEntity; r_numEntities++; + return true; } @@ -235,6 +241,77 @@ static void R_SetupModelviewMatrix( const ref_params_t *fd, matrix4x4 m ) Matrix4x4_ConcatTranslate( m, -fd->vieworg[0], -fd->vieworg[1], -fd->vieworg[2] ); } +/* +============= +R_LoadIdentity +============= +*/ +void R_LoadIdentity( void ) +{ + if( tr.modelviewIdentity ) return; + + Matrix4x4_LoadIdentity( RI.objectMatrix ); + Matrix4x4_Copy( RI.modelviewMatrix, RI.worldviewMatrix ); + GL_LoadMatrix( RI.modelviewMatrix ); + tr.modelviewIdentity = true; +} + +/* +============= +R_RotateForEntity +============= +*/ +void R_RotateForEntity( cl_entity_t *e ) +{ + float *org, *ang; + float scale = 1.0f; + + if( e == clgame.entities ) + { + R_LoadIdentity(); + return; + } + + org = e->origin; + ang = e->angles; + + if( e->model->type != mod_brush && e->curstate.scale > 0.0f ) + scale = e->curstate.scale; + + Matrix4x4_CreateFromEntity( RI.objectMatrix, org[0], org[1], org[2], ang[0], ang[1], ang[2], scale ); + Matrix4x4_ConcatTransforms( RI.modelviewMatrix, RI.worldviewMatrix, RI.objectMatrix ); + + GL_LoadMatrix( RI.modelviewMatrix ); + tr.modelviewIdentity = false; +} + +/* +============= +R_TranslateForEntity +============= +*/ +void R_TranslateForEntity( cl_entity_t *e ) +{ + float scale = 1.0f; + + if( e == clgame.entities ) + { + R_LoadIdentity(); + return; + } + + if( e->model->type != mod_brush && e->curstate.scale > 0.0f ) + scale = e->curstate.scale; + + Matrix4x4_LoadIdentity( RI.objectMatrix ); + Matrix4x4_SetOrigin( RI.objectMatrix, e->origin[0], e->origin[1], e->origin[2] ); + Matrix4x4_ConcatScale( RI.objectMatrix, scale ); + Matrix4x4_ConcatTransforms( RI.modelviewMatrix, RI.worldviewMatrix, RI.objectMatrix ); + + GL_LoadMatrix( RI.modelviewMatrix ); + tr.modelviewIdentity = false; +} + /* =============== R_SetupFrame @@ -246,7 +323,7 @@ static void R_SetupFrame( void ) VectorCopy( RI.refdef.vieworg, RI.vieworg ); AngleVectors( RI.refdef.viewangles, RI.vforward, RI.vright, RI.vup ); - CL_RunLightStyles(); + R_AnimateLight(); tr.framecount++; @@ -296,6 +373,14 @@ R_SetupGL */ static void R_SetupGL( void ) { + if( RI.refdef.waterlevel >= 3 ) + { + float f; + f = com.sin( cl.time * 0.4f * ( M_PI * 2.7f )); + RI.refdef.fov_x += f; + RI.refdef.fov_y -= f; + } + R_SetupModelviewMatrix( &RI.refdef, RI.worldviewMatrix ); R_SetupProjectionMatrix( &RI.refdef, RI.projectionMatrix ); if( RI.params & RP_MIRRORVIEW ) RI.projectionMatrix[0][0] = -RI.projectionMatrix[0][0]; @@ -346,6 +431,41 @@ static void R_EndGL( void ) pglDisable( GL_CLIP_PLANE0 ); } +/* +============= +R_DrawEntitiesOnList +============= +*/ +void R_DrawEntitiesOnList( void ) +{ + int i; + + if( !r_drawentities->integer ) + return; + + // first draw entities with rendermode 'normal' + for( i = 0; i < r_numEntities; i++ ) + { + RI.currententity = r_entities[i]; + ASSERT( RI.currententity != NULL ); + + if( RI.currententity->curstate.rendermode != kRenderNormal ) + continue; + + if( !RI.currententity->model ) + continue; + + switch( RI.currententity->model->type ) + { + case mod_brush: + R_DrawBrushModel( RI.currententity ); + break; + default: + break; + } + } +} + /* ================ R_RenderScene @@ -371,10 +491,12 @@ void R_RenderScene( const ref_params_t *fd ) R_DrawWorld(); CL_ExtraUpdate (); // don't let sound get messed up if going slow + Tri_DrawTriangles( false ); -// R_DrawEntitiesOnList(); + R_DrawEntitiesOnList(); - CL_DrawParticles (); + R_DrawWaterSurfaces(); + Tri_DrawTriangles( true ); R_EndGL(); } diff --git a/engine/client/gl_rsurf.c b/engine/client/gl_rsurf.c index 2a7bd791..a9cff4fe 100644 --- a/engine/client/gl_rsurf.c +++ b/engine/client/gl_rsurf.c @@ -7,28 +7,41 @@ #include "client.h" #include "gl_local.h" #include "cm_local.h" +#include "matrix_lib.h" -#define BLOCK_WIDTH 256 -#define BLOCK_HEIGHT 256 +#define BLOCK_WIDTH 128 +#define BLOCK_HEIGHT 128 typedef struct { - glpoly_t *lightmap_polys[MAX_LIGHTMAPS]; qboolean lightmap_modified[MAX_LIGHTMAPS]; wrect_t lightmap_rectchange[MAX_LIGHTMAPS]; int allocated[MAX_LIGHTMAPS][BLOCK_WIDTH]; byte lightmaps[MAX_LIGHTMAPS*BLOCK_WIDTH*BLOCK_HEIGHT*4]; } lightmap_state_t; +typedef struct gl_light_s +{ + int local[2]; + int minlight; // rad - minlight + int rad; +} gl_light_t; + static vec3_t modelorg; // relative to viewpoint static vec3_t modelmins; static vec3_t modelmaxs; static byte visbytes[MAX_MAP_LEAFS/8]; -static vec3_t r_blockLights[BLOCK_WIDTH*BLOCK_HEIGHT]; +static uint r_blockLights[BLOCK_WIDTH*BLOCK_HEIGHT*3]; +static glpoly_t *lightmap_polys[MAX_LIGHTMAPS]; +static glpoly_t *fullbright_polys[MAX_TEXTURES]; +static qboolean draw_fullbrights = false; static lightmap_state_t r_lmState; static msurface_t *skychain = NULL; static msurface_t *waterchain = NULL; +static gl_light_t r_dlights[MAX_DLIGHTS]; +static int r_numdlights; + static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride ); static void LM_UploadBlock( int lightmapnum ); @@ -124,6 +137,7 @@ static void SubdividePolygon_r( msurface_t *warpface, int numverts, float *verts // add a point in the center to help keep warp valid poly = Mem_Alloc( loadmodel->mempool, sizeof( glpoly_t ) + ((numverts-4)+2) * VERTEXSIZE * sizeof( float )); poly->next = warpface->polys; + poly->flags = warpface->flags; warpface->polys = poly; poly->numverts = numverts + 2; VectorClear( total ); @@ -362,18 +376,16 @@ void R_BlendLightmaps( void ) if( r_fullbright->integer ) return; - if( !gl_texsort->integer ) - return; if( !r_lightmap->integer ) { GL_TexEnv( GL_MODULATE ); - GL_SetState( GLSTATE_SRCBLEND_ZERO|GLSTATE_DSTBLEND_ONE_MINUS_SRC_COLOR ); + GL_SetState( GLSTATE_SRCBLEND_ZERO|GLSTATE_DSTBLEND_SRC_COLOR ); } for( i = 0; i < MAX_LIGHTMAPS; i++ ) { - p = r_lmState.lightmap_polys[i]; + p = lightmap_polys[i]; if( !p ) continue; GL_Bind( GL_TEXTURE0, tr.lightmapTextures[i] ); @@ -382,23 +394,15 @@ void R_BlendLightmaps( void ) for( ; p; p = p->chain ) { - if( p->flags & SURF_UNDERWATER ) - { - DrawGLWaterPoly( p, true ); - } - else - { - pglBegin( GL_POLYGON ); + pglBegin( GL_POLYGON ); - v = p->verts[0]; - for( j = 0; j < p->numverts; j++, v += VERTEXSIZE ) - { - pglTexCoord2f( v[5], v[6] ); - pglVertex3fv( v ); - } - - pglEnd(); + v = p->verts[0]; + for( j = 0; j < p->numverts; j++, v += VERTEXSIZE ) + { + pglTexCoord2f( v[5], v[6] ); + pglVertex3fv( v ); } + pglEnd(); } } @@ -406,6 +410,129 @@ void R_BlendLightmaps( void ) GL_SetState( GLSTATE_DEPTHWRITE ); } +/* +================ +R_RenderFullbrights +================ +*/ +void R_RenderFullbrights( void ) +{ + glpoly_t *p; + int i; +#if 0 + if( !draw_fullbrights ) + return; + + GL_SetState( GLSTATE_SRCBLEND_ONE|GLSTATE_DSTBLEND_ONE ); + GL_TexEnv( GL_MODULATE ); + + for( i = 1; i < MAX_TEXTURES; i++ ) + { + if( !fullbright_polys[i] ) + continue; + GL_Bind( GL_TEXTURE0, i ); + + for( p = fullbright_polys[i]; p; p = p->fb_chain ) + { + if( p->flags & SURF_DRAWTURB ) + EmitWaterPolys( p ); + else DrawGLPoly( p ); + } + fullbright_polys[i] = NULL; + } + + GL_SetState( GLSTATE_DEPTHWRITE ); + draw_fullbrights = false; +#endif +} + +/* +=============== +R_BuildDlights +=============== +*/ +void R_BuildDlights( msurface_t *surf ) +{ + float dist; + vec3_t impact; + int lnum, smax, tmax; + int tdmin, sdmin, distmin; + int irad, iminlight, local[2]; + vec3_t origin_l; + matrix4x4 imatrix; + gl_light_t *light; + mtexinfo_t *tex; + dlight_t *dl; + + r_numdlights = 0; + + smax = ( surf->extents[0] >> 4 ) + 1; + tmax = ( surf->extents[1] >> 4 ) + 1; + tex = surf->texinfo; + + for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ ) + { + if(!( surf->dlightbits & ( 1<origin, origin_l ); + } + else VectorCopy( dl->origin, origin_l ); + + dist = PlaneDiff( origin_l, surf->plane ); + irad = ( dl->radius - fabs( dist )) * 256; + iminlight = dl->minlight * 256; + if( irad < iminlight ) continue; + + iminlight = irad - iminlight; + + VectorMA( origin_l, -dist, surf->plane->normal, impact ); + + local[0] = DotProduct( impact, tex->vecs[0] ) + tex->vecs[0][3] - surf->texturemins[0]; + local[1] = DotProduct( impact, tex->vecs[1] ) + tex->vecs[1][3] - surf->texturemins[1]; + + // check if this dlight will touch the surface + if( local[1] > 0 ) + { + tdmin = local[1] - (tmax << 4); + if( tdmin < 0 ) tdmin = 0; + } + else + { + tdmin = -local[1]; + } + + if( local[0] > 0 ) + { + sdmin = local[0] - (smax << 4); + if( sdmin < 0 ) sdmin = 0; + } + else + { + sdmin = -local[0]; + } + + distmin = (sdmin > tdmin) ? (sdmin << 8) + (tdmin << 7) : (tdmin << 8) + (sdmin << 7); + + if( distmin < iminlight ) + { + // save dlight info + light = &r_dlights[r_numdlights]; + light->minlight = iminlight; + light->local[0] = local[0]; + light->local[1] = local[1]; + light->rad = irad; + r_numdlights++; + } + } +} + /* ================ R_RenderDynamicLightmaps @@ -414,58 +541,68 @@ R_RenderDynamicLightmaps void R_RenderDynamicLightmaps( msurface_t *fa ) { byte *base; - int maps; wrect_t *rect; - int smax, tmax; - float scale; + uint scale; + qboolean lightstyle_modified = false; + int maps, smax, tmax; if( fa->flags & ( SURF_DRAWSKY|SURF_DRAWTURB )) return; - fa->polys->chain = r_lmState.lightmap_polys[fa->lightmaptexturenum]; - r_lmState.lightmap_polys[fa->lightmaptexturenum] = fa->polys; + fa->polys->chain = lightmap_polys[fa->lightmaptexturenum]; + lightmap_polys[fa->lightmaptexturenum] = fa->polys; + + if( !r_dynamic->integer ) + return; // check for lightmap modification for( maps = 0; maps < MAXLIGHTMAPS && fa->styles[maps] != 255; maps++ ) { - scale = cl.lightstyles[fa->styles[maps]].value * r_lighting_modulate->value; + scale = RI.lightstylevalue[fa->styles[maps]]; + if( scale != fa->cached_light[maps] ) - goto dynamic; // lightstyle or r_lighting_modulate changed - } - - if( fa->dlightframe == tr.framecount || fa->cached_dlight ) - { -dynamic: - if( r_dynamic->integer ) { - r_lmState.lightmap_modified[fa->lightmaptexturenum] = true; - rect = &r_lmState.lightmap_rectchange[fa->lightmaptexturenum]; - - if( fa->light_t < rect->right ) - { - if( rect->bottom ) - rect->bottom += rect->right - fa->light_t; - rect->right = fa->light_t; - } - - if( fa->light_s < rect->left ) - { - if( rect->top ) - rect->top += rect->left - fa->light_s; - rect->left = fa->light_s; - } - - smax = ( fa->extents[0] >> 4 ) + 1; - tmax = ( fa->extents[1] >> 4 ) + 1; - if(( rect->top + rect->left ) < ( fa->light_s + smax )) - rect->top = ( fa->light_s - rect->left ) + smax; - if(( rect->bottom + rect->right ) < ( fa->light_t + tmax )) - rect->bottom = ( fa->light_t - rect->right ) + tmax; - base = r_lmState.lightmaps + fa->lightmaptexturenum * BLOCK_WIDTH * BLOCK_HEIGHT * 4; - base += fa->light_t * BLOCK_WIDTH * 4 + fa->light_s * 4; - R_BuildLightMap( fa, base, BLOCK_WIDTH * 4 ); + lightstyle_modified = true; + break; } } + + if( fa->dlightframe == tr.framecount ) + R_BuildDlights( fa ); + else r_numdlights = 0; + + if( !r_numdlights && !fa->cached_dlight && !lightstyle_modified ) + return; + + r_lmState.lightmap_modified[fa->lightmaptexturenum] = true; + rect = &r_lmState.lightmap_rectchange[fa->lightmaptexturenum]; + + if( fa->light_t < rect->right ) + { + if( rect->bottom ) + rect->bottom += rect->right - fa->light_t; + rect->right = fa->light_t; + } + + if( fa->light_s < rect->left ) + { + if( rect->top ) + rect->top += rect->left - fa->light_s; + rect->left = fa->light_s; + } + + smax = ( fa->extents[0] >> 4 ) + 1; + tmax = ( fa->extents[1] >> 4 ) + 1; + + if(( rect->top + rect->left ) < ( fa->light_s + smax )) + rect->top = ( fa->light_s - rect->left ) + smax; + + if(( rect->bottom + rect->right ) < ( fa->light_t + tmax )) + rect->bottom = ( fa->light_t - rect->right ) + tmax; + + base = r_lmState.lightmaps + fa->lightmaptexturenum * BLOCK_WIDTH * BLOCK_HEIGHT * 4; + base += fa->light_t * BLOCK_WIDTH * 4 + fa->light_s * 4; + R_BuildLightMap( fa, base, BLOCK_WIDTH * 4 ); } /* @@ -488,17 +625,22 @@ void R_RenderBrushPoly( msurface_t *fa ) t = R_TextureAnimation( fa->texinfo->texture ); GL_Bind( GL_TEXTURE0, t->gl_texturenum ); - +#if 0 + if( t->fb_texturenum ) + { + fa->polys->fb_chain = fullbright_polys[t->fb_texturenum]; + fullbright_polys[t->fb_texturenum] = fa->polys; + draw_fullbrights = true; + } +#endif if( fa->flags & SURF_DRAWTURB ) { // warp texture, no lightmaps - EmitWaterPolys( fa ); + EmitWaterPolys( fa->polys ); return; } - if( fa->flags & SURF_UNDERWATER ) - DrawGLWaterPoly( fa->polys, false ); - else DrawGLPoly( fa->polys ); + DrawGLPoly( fa->polys ); // add the poly to the proper lightmap chain R_RenderDynamicLightmaps( fa ); @@ -511,227 +653,53 @@ R_AddDynamicLights */ void R_AddDynamicLights( msurface_t *surf ) { - int lnum, sd, td, s, t; - float dist, rad, minlight; - vec3_t impact, local; - int smax, tmax; - float brightness; - mtexinfo_t *tex; - dlight_t *dl; + color24 color; + int local[2]; + int i, sd, td, s, t; + int irad, idist, iminlight; + int smax, tmax, tmp; + gl_light_t *light; + uint *bl; smax = (surf->extents[0] >> 4) + 1; tmax = (surf->extents[1] >> 4) + 1; - tex = surf->texinfo; - for( lnum = 0; lnum < MAX_DLIGHTS; lnum++ ) + for( i = 0, light = r_dlights; i < r_numdlights; i++, light++ ) { - if(!( surf->dlightbits & ( 1<minlight; + irad = light->rad; - rad = dl->radius; - dist = DotProduct( dl->origin, surf->plane->normal ) - surf->plane->dist; - rad -= fabs( dist ); - minlight = dl->minlight; - if( rad < minlight ) continue; + local[1] = light->local[1]; + bl = r_blockLights; - minlight = rad - minlight; - - VectorMA( dl->origin, -dist, surf->plane->normal, impact ); - local[0] = DotProduct( impact, tex->vecs[0] ) + tex->vecs[0][3]; - local[1] = DotProduct( impact, tex->vecs[1] ) + tex->vecs[1][3]; - - local[0] -= surf->texturemins[0]; - local[1] -= surf->texturemins[1]; - for( t = 0; t < tmax; t++ ) { - td = local[1] - t * 16; - if( td < 0 ) td = -td; + td = (local[1] < 0) ? -local[1] : local[1]; + local[1] -= LM_SAMPLE_SIZE; + local[0] = light->local[0]; for( s = 0; s < smax; s++ ) { - sd = local[0] - s * 16; - if( sd < 0 ) sd = -sd; - if( sd > td ) dist = sd + (td >> 1); - else dist = td + (sd >> 1); - brightness = (rad - dist); + sd = (local[0] < 0) ? -local[0] : local[0]; + local[0] -= LM_SAMPLE_SIZE; + idist = (sd > td) ? (sd << 8) + (td << 7) : (td << 8) + (sd << 7); - if( dl->dark ) - brightness = -brightness; - - if( dist < minlight ) + if( idist < iminlight ) { - r_blockLights[t * smax + s][0] += dl->color.r * brightness; - r_blockLights[t * smax + s][1] += dl->color.g * brightness; - r_blockLights[t * smax + s][2] += dl->color.b * brightness; + if( cl_dlights[i].dark ) + tmp = -(irad - idist) >> 7; + else tmp = (irad - idist) >> 7; + bl[0] += tmp * color.r; + bl[1] += tmp * color.g; + bl[2] += tmp * color.b; } + bl += 3; } } } } -/* -================ -R_DrawSequentialPoly - -Systems that have fast state and texture changes can -just do everything as it passes with no need to sort -================ -*/ -void R_DrawSequentialPoly( msurface_t *s ) -{ - glpoly_t *p; - float *v; - texture_t *t; - vec3_t nv; - int i; - - // normal lightmaped poly - if(!( s->flags & ( SURF_DRAWSKY|SURF_DRAWTURB|SURF_UNDERWATER ))) - { - R_RenderDynamicLightmaps( s ); - r_stats.c_brush_polys++; - - if( GL_Support( GL_ARB_MULTITEXTURE )) - { - p = s->polys; - - t = R_TextureAnimation( s->texinfo->texture ); - - GL_Bind( GL_TEXTURE0, t->gl_texturenum ); - GL_TexEnv( GL_REPLACE ); - GL_SetState( GLSTATE_DEPTHWRITE ); - - GL_Bind( GL_TEXTURE1, tr.lightmapTextures[s->lightmaptexturenum] ); - i = s->lightmaptexturenum; - - if( r_lmState.lightmap_modified[i] ) - LM_UploadBlock( i ); - - GL_TexEnv( GL_MODULATE ); - - pglBegin( GL_POLYGON ); - v = p->verts[0]; - - for( i = 0; i < p->numverts; i++, v += VERTEXSIZE ) - { - GL_MultiTexCoord2f( GL_TEXTURE0, v[3], v[4] ); - GL_MultiTexCoord2f( GL_TEXTURE1, v[5], v[6] ); - pglVertex3fv( v ); - } - - pglEnd(); - return; - } - else - { - p = s->polys; - - t = R_TextureAnimation( s->texinfo->texture ); - GL_Bind( GL_TEXTURE0, t->gl_texturenum ); - GL_TexEnv( GL_REPLACE ); - GL_SetState( GLSTATE_DEPTHWRITE ); - - pglBegin( GL_POLYGON ); - v = p->verts[0]; - - for( i = 0; i < p->numverts; i++, v += VERTEXSIZE ) - { - pglTexCoord2f( v[3], v[4] ); - pglVertex3fv( v ); - } - - pglEnd(); - - GL_Bind( GL_TEXTURE0, tr.lightmapTextures[s->lightmaptexturenum] ); - GL_TexEnv( GL_MODULATE ); - GL_SetState( GLSTATE_SRCBLEND_ZERO|GLSTATE_DSTBLEND_ONE_MINUS_SRC_COLOR ); - - pglBegin( GL_POLYGON ); - v = p->verts[0]; - for( i = 0; i < p->numverts; i++, v += VERTEXSIZE ) - { - pglTexCoord2f( v[5], v[6] ); - pglVertex3fv( v ); - } - - pglEnd(); - GL_TexEnv( GL_REPLACE ); - GL_SetState( GLSTATE_DEPTHWRITE ); - } - - return; - } - - // subdivided water surface warp - if( s->flags & SURF_DRAWTURB ) - { - GL_CleanUpTextureUnits( 1 ); - GL_Bind( GL_TEXTURE0, s->texinfo->texture->gl_texturenum ); - EmitWaterPolys( s ); - return; - } - - // subdivided sky warp - if( s->flags & SURF_DRAWSKY ) - { - GL_CleanUpTextureUnits( 1 ); - EmitSkyLayers( s ); - return; - } - - // underwater warped with lightmap - R_RenderDynamicLightmaps( s ); - r_stats.c_brush_polys++; - - if( GL_Support( GL_ARB_MULTITEXTURE )) - { - p = s->polys; - - t = R_TextureAnimation( s->texinfo->texture ); - GL_Bind( GL_TEXTURE0, t->gl_texturenum ); - GL_TexEnv( GL_REPLACE ); - - GL_Bind( GL_TEXTURE1, tr.lightmapTextures[s->lightmaptexturenum] ); - i = s->lightmaptexturenum; - - if( r_lmState.lightmap_modified[i] ) - LM_UploadBlock( i ); - GL_TexEnv( GL_BLEND ); - - pglBegin( GL_TRIANGLE_FAN ); - v = p->verts[0]; - - for( i = 0; i < p->numverts; i++, v += VERTEXSIZE ) - { - GL_MultiTexCoord2f( GL_TEXTURE0, v[3], v[4] ); - GL_MultiTexCoord2f( GL_TEXTURE1, v[5], v[6] ); - - nv[0] = v[0] + 8 * com.sin( v[1] * 0.05f + cl.time ) * com.sin( v[2] * 0.05f + cl.time ); - nv[1] = v[1] + 8 * com.sin( v[0] * 0.05f + cl.time ) * com.sin( v[2] * 0.05f + cl.time ); - nv[2] = v[2]; - pglVertex3fv( nv ); - } - - pglEnd (); - - } - else - { - p = s->polys; - - t = R_TextureAnimation( s->texinfo->texture ); - GL_Bind( GL_TEXTURE0, t->gl_texturenum ); - DrawGLWaterPoly( p, false ); - - GL_Bind( GL_TEXTURE0, tr.lightmapTextures[s->lightmaptexturenum] ); - pglEnable( GL_BLEND ); - DrawGLWaterPoly( p, true ); - pglDisable( GL_BLEND ); - } -} - /* ================ R_DrawTextureChains @@ -743,18 +711,6 @@ void R_DrawTextureChains( void ) msurface_t *s; texture_t *t; - if( !gl_texsort->integer ) - { - GL_CleanUpTextureUnits( 1 ); - - if( skychain ) - { - R_DrawSkyChain( skychain ); - skychain = NULL; - } - return; - } - for( i = 0; i < cl.worldmodel->numtextures; i++ ) { t = cl.worldmodel->textures[i]; @@ -769,15 +725,155 @@ void R_DrawTextureChains( void ) } else { - if(( s->flags & SURF_DRAWTURB ) && r_wateralpha->value != 1.0f ) - continue; // draw translucent water later - for( ;s != NULL; s = s->texturechain ) + for( ; s != NULL; s = s->texturechain ) R_RenderBrushPoly( s ); } t->texturechain = NULL; } } +/* +================ +R_DrawWaterSurfaces +================ +*/ +void R_DrawWaterSurfaces( void ) +{ + int i; + msurface_t *s; + texture_t *t; + + // non-transparent water is already drawed + if( r_wateralpha->value >= 1.0f ) + return; + + // go back to the world matrix + pglMatrixMode( GL_MODELVIEW ); + GL_LoadMatrix( RI.worldviewMatrix ); + + GL_SetState( GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE_MINUS_SRC_ALPHA ); + pglColor4f( 1.0f, 1.0f, 1.0f, r_wateralpha->value ); + GL_TexEnv( GL_MODULATE ); + + for( i = 0; i < cl.worldmodel->numtextures; i++ ) + { + t = cl.worldmodel->textures[i]; + if( !t ) continue; + + s = t->texturechain; + if( !s ) continue; + + if(!( s->flags & SURF_DRAWTURB )) + continue; + + // set modulate mode explicitly + GL_Bind( GL_TEXTURE0, t->gl_texturenum ); + + for( ; s; s = s->texturechain ) + EmitWaterPolys( s->polys ); + + t->texturechain = NULL; + } + + GL_SetState( GLSTATE_DEPTHWRITE ); + pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); + GL_TexEnv( GL_REPLACE ); +} + +/* +================= +R_DrawBrushModel +================= +*/ +void R_DrawBrushModel( cl_entity_t *e ) +{ + int i, k, sidebit; + vec3_t mins, maxs; + msurface_t *psurf; + float dot; + dlight_t *l; + model_t *clmodel; + qboolean rotated; + + clmodel = e->model; + + if( !VectorIsNull( e->angles )) + { + for( i = 0; i < 3; i++ ) + { + mins[i] = e->origin[i] - clmodel->radius; + maxs[i] = e->origin[i] + clmodel->radius; + } + rotated = true; + } + else + { + VectorAdd( e->origin, clmodel->mins, mins ); + VectorAdd( e->origin, clmodel->maxs, maxs ); + rotated = false; + } + + if( R_CullBox( mins, maxs )) + return; + + pglColor3f( 1.0f, 1.0f, 1.0f ); + Mem_Set( lightmap_polys, 0, sizeof( lightmap_polys )); + + VectorSubtract( RI.refdef.vieworg, e->origin, modelorg ); + if( rotated ) R_RotateForEntity( e ); + else R_TranslateForEntity( e ); + + VectorSubtract( RI.refdef.vieworg, e->origin, modelorg ); + + if( rotated ) + { + vec3_t temp; + VectorCopy( modelorg, temp ); + Matrix4x4_VectorITransform( RI.objectMatrix, temp, modelorg ); + } + + psurf = &clmodel->surfaces[clmodel->firstmodelsurface]; + + // calculate dynamic lighting for bmodel if it's not an + // instanced model + if( clmodel->firstmodelsurface != 0 ) + { + vec3_t origin_l, oldorigin; + matrix4x4 imatrix; + + for( k = 0, l = cl_dlights; k < MAX_DLIGHTS; k++, l++ ) + { + if( l->die < cl.time || !l->radius ) + continue; + + VectorCopy( l->origin, oldorigin ); // save oldorigin + Matrix4x4_Invert_Simple( imatrix, RI.objectMatrix ); + Matrix4x4_VectorTransform( imatrix, l->origin, origin_l ); + VectorCopy( origin_l, l->origin ); // move light in bmodel space + R_MarkLights( l, 1<nodes + clmodel->hulls[0].firstclipnode ); + VectorCopy( oldorigin, l->origin ); // restore lightorigin + } + } + + for( i = 0; i < clmodel->nummodelsurfaces; i++, psurf++ ) + { + // find which side of the node we are on + dot = PlaneDiff( modelorg, psurf->plane ); + + if( dot >= 0 ) sidebit = 0; + else sidebit = SURF_PLANEBACK; + + // draw the polygon + if(( psurf->flags & SURF_PLANEBACK ) != sidebit ) + continue; // wrong side + + R_RenderBrushPoly( psurf ); + } + + R_BlendLightmaps (); + R_LoadIdentity(); // restore worldmatrix +} + /* ============================================================= @@ -791,8 +887,10 @@ void R_DrawTextureChains( void ) R_RecursiveWorldNode ================ */ -void R_RecursiveWorldNode( mnode_t *node ) +void R_RecursiveWorldNode( mnode_t *node, uint clipflags ) { + const mplane_t *clipplane; + int i, clipped; msurface_t *surf, **mark; mleaf_t *pleaf; int c, side, sidebit; @@ -804,9 +902,19 @@ void R_RecursiveWorldNode( mnode_t *node ) if( node->visframe != tr.visframecount ) return; - if( R_CullBox( node->minmaxs, node->minmaxs + 3 )) - return; - + if( clipflags ) + { + for( i = 0, clipplane = RI.frustum; i < 6; i++, clipplane++ ) + { + if(!( clipflags & ( 1<minmaxs, node->minmaxs + 3, clipplane ); + if( clipped == 2 ) return; + if( clipped == 1 ) clipflags &= ~(1<contents < 0 ) { @@ -827,6 +935,8 @@ void R_RecursiveWorldNode( mnode_t *node ) // deal with model fragments in this leaf if( pleaf->efrags ) R_StoreEfrags( &pleaf->efrags ); + + r_stats.c_world_leafs++; return; } @@ -847,7 +957,7 @@ void R_RecursiveWorldNode( mnode_t *node ) } // recurse down the children, front side first - R_RecursiveWorldNode( node->children[side] ); + R_RecursiveWorldNode( node->children[side], clipflags ); // draw stuff for( c = node->numsurfaces, surf = cl.worldmodel->surfaces + node->firstsurface; c; c--, surf++ ) @@ -858,27 +968,12 @@ void R_RecursiveWorldNode( mnode_t *node ) if(( surf->flags & SURF_PLANEBACK ) != sidebit ) continue; // wrong side - // if sorting by texture, just store it out - if( gl_texsort->integer ) - { - surf->texturechain = surf->texinfo->texture->texturechain; - surf->texinfo->texture->texturechain = surf; - } - else if( surf->flags & SURF_DRAWSKY ) - { - surf->texturechain = skychain; - skychain = surf; - } - else if( surf->flags & SURF_DRAWTURB ) - { - surf->texturechain = waterchain; - waterchain = surf; - } - else R_DrawSequentialPoly( surf ); + surf->texturechain = surf->texinfo->texture->texturechain; + surf->texinfo->texture->texturechain = surf; } // recurse down the back side - R_RecursiveWorldNode( node->children[!side] ); + R_RecursiveWorldNode( node->children[!side], clipflags ); } /* @@ -891,17 +986,22 @@ void R_DrawWorld( void ) RI.currententity = clgame.entities; RI.currentmodel = RI.currententity->model; + if( RI.refdef.onlyClientDraw ) + return; + VectorCopy( RI.refdef.vieworg, modelorg ); - Mem_Set( r_lmState.lightmap_polys, 0, sizeof( r_lmState.lightmap_polys )); + Mem_Set( lightmap_polys, 0, sizeof( lightmap_polys )); + Mem_Set( fullbright_polys, 0, sizeof( fullbright_polys )); ClearBounds( RI.visMins, RI.visMaxs ); R_ClearSkyBox (); - R_RecursiveWorldNode( cl.worldmodel->nodes ); + R_RecursiveWorldNode( cl.worldmodel->nodes, RI.clipFlags ); R_DrawTextureChains(); R_BlendLightmaps(); + R_RenderFullbrights(); R_DrawSkyBox (); } @@ -919,7 +1019,8 @@ void R_MarkLeaves( void ) mnode_t *node; int i; - if( !RI.drawWorld ) return; + if( !RI.drawWorld || RI.refdef.onlyClientDraw ) + return; if( r_viewleaf == r_oldviewleaf && r_viewleaf2 == r_oldviewleaf2 && !r_novis->integer && r_viewleaf != NULL ) return; @@ -1038,10 +1139,11 @@ static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride ) { int smax, tmax, t, s, i; int size, map, blocksize; - float *bl, max, scale; + uint scale; + uint *bl; color24 *lm; - surf->cached_dlight = ( surf->dlightframe == tr.framecount ); + surf->cached_dlight = (r_numdlights > 0) ? true : false; smax = (surf->extents[0] >> 4) + 1; tmax = (surf->extents[1] >> 4) + 1; @@ -1049,69 +1151,38 @@ static void R_BuildLightMap( msurface_t *surf, byte *dest, int stride ) blocksize = size * 3; lm = surf->samples; - // set to full bright if no light data - if( !lm || r_fullbright->integer || !cl.worldmodel->lightdata ) - { - // set to full bright if no light data - Mem_Set( r_blockLights, 0xFF, sizeof( float ) * blocksize ); - } - else - { - Mem_Set( r_blockLights, 0, sizeof( float ) * blocksize ); + Mem_Set( r_blockLights, 0, sizeof( uint ) * blocksize ); - // add all the lightmaps - for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ ) - { - scale = cl.lightstyles[surf->styles[map]].value * r_lighting_modulate->value; - surf->cached_light[map] = scale; + // add all the lightmaps + for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255 && lm; map++ ) + { + scale = RI.lightstylevalue[surf->styles[map]]; + surf->cached_light[map] = scale; - for( i = 0, bl = r_blockLights[0]; i < size; i++, bl += 3, lm++ ) - { - bl[0] += lm->r * scale; - bl[1] += lm->g * scale; - bl[2] += lm->b * scale; - } + for( i = 0, bl = r_blockLights; i < size; i++, bl += 3, lm++ ) + { + bl[0] += lm->r * scale; + bl[1] += lm->g * scale; + bl[2] += lm->b * scale; } } // add all the dynamic lights - if( surf->cached_dlight ) + if( r_numdlights ) R_AddDynamicLights( surf ); // put into texture format stride -= (smax << 2); - bl = r_blockLights[0]; + bl = r_blockLights; for( t = 0; t < tmax; t++, dest += stride ) { for( s = 0; s < smax; s++ ) { - // catch negative lights - if( bl[0] < 0.0f ) bl[0] = 0.0f; - if( bl[1] < 0.0f ) bl[1] = 0.0f; - if( bl[2] < 0.0f ) bl[2] = 0.0f; - - // Determine the brightest of the three color components - max = VectorMax( bl ); - - // rescale all the color components if the intensity of the - // greatest channel exceeds 255 - if( max > 255.0f ) - { - max = 255.0f / max; - - dest[0] = 255 - ( bl[0] * max ); - dest[1] = 255 - ( bl[1] * max ); - dest[2] = 255 - ( bl[2] * max ); - dest[3] = 255; - } - else - { - dest[0] = 255 - bl[0]; - dest[1] = 255 - bl[1]; - dest[2] = 255 - bl[2]; - dest[3] = 255; - } + dest[0] = min((bl[0] >> 7), 255 ); + dest[1] = min((bl[1] >> 7), 255 ); + dest[2] = min((bl[2] >> 7), 255 ); + dest[3] = 255; bl += 3; dest += 4; @@ -1162,6 +1233,7 @@ void GL_CreateSurfaceLightmap( msurface_t *surf ) surf->lightmaptexturenum = LM_AllocBlock( smax, tmax, &surf->light_s, &surf->light_t ); base = r_lmState.lightmaps + surf->lightmaptexturenum * BLOCK_WIDTH * BLOCK_HEIGHT * 4; base += (surf->light_t * BLOCK_WIDTH + surf->light_s) * 4; + r_numdlights = 0; R_BuildLightMap( surf, base, BLOCK_WIDTH * 4 ); } @@ -1194,6 +1266,9 @@ void GL_BuildLightmaps( void ) skychain = waterchain = NULL; + // setup all the lightstyles + R_AnimateLight(); + LM_InitBlock(); for( i = 1; i < MAX_MODELS; i++ ) @@ -1238,7 +1313,7 @@ void GL_BuildLightmaps( void ) r_lightmap.size = r_lightmap.width * r_lightmap.height * 4; r_lightmap.flags = IMAGE_HAS_COLOR; // FIXME: detecting grayscale lightmaps for quake1 r_lightmap.buffer = (byte *)&r_lmState.lightmaps[r_lightmap.size*i]; - tr.lightmapTextures[i] = GL_LoadTextureInternal( lmName, &r_lightmap, TF_LIGHTMAP, false ); + tr.lightmapTextures[i] = GL_LoadTextureInternal( lmName, &r_lightmap, TF_FONT|TF_LIGHTMAP, false ); GL_SetTextureType( tr.lightmapTextures[i], TEX_LIGHTMAP ); } } \ No newline at end of file diff --git a/engine/client/gl_vidnt.c b/engine/client/gl_vidnt.c index e6b50d32..6dfffa27 100644 --- a/engine/client/gl_vidnt.c +++ b/engine/client/gl_vidnt.c @@ -19,6 +19,7 @@ convar_t *gl_allow_software; convar_t *gl_extensions; convar_t *gl_colorbits; +convar_t *gl_alphabits; convar_t *gl_depthbits; convar_t *gl_stencilbits; convar_t *gl_texturebits; @@ -36,7 +37,6 @@ convar_t *gl_skymip; convar_t *gl_nobind; convar_t *gl_finish; convar_t *gl_clear; -convar_t *gl_texsort; convar_t *r_width; convar_t *r_height; @@ -44,6 +44,7 @@ convar_t *r_speeds; convar_t *r_fullbright; convar_t *r_norefresh; convar_t *r_lighting_modulate; +convar_t *r_drawentities; convar_t *r_adjust_fov; convar_t *r_novis; convar_t *r_nocull; @@ -635,13 +636,13 @@ qboolean GL_DeleteContext( void ) GL_ChoosePFD ================= */ -static int GL_ChoosePFD( int colorBits, int depthBits, int stencilBits ) +static int GL_ChoosePFD( int colorBits, int alphaBits, int depthBits, int stencilBits ) { PIXELFORMATDESCRIPTOR PFDs[MAX_PFDS], *current, *selected; uint flags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; int i, numPFDs, pixelFormat = 0; - MsgDev( D_NOTE, "GL_ChoosePFD( color %i, depth %i, stencil %i )\n", colorBits, depthBits, stencilBits ); + MsgDev( D_NOTE, "GL_ChoosePFD( color %i, alpha %i, depth %i, stencil %i )\n", colorBits, alphaBits, depthBits, stencilBits ); // Count PFDs if( glw_state.minidriver ) @@ -682,6 +683,10 @@ static int GL_ChoosePFD( int colorBits, int depthBits, int stencilBits ) if( current->cColorBits < colorBits ) continue; + // check alpha bits + if( current->cAlphaBits < alphaBits ) + continue; + // check depth bits if( current->cDepthBits < depthBits ) continue; @@ -708,6 +713,16 @@ static int GL_ChoosePFD( int colorBits, int depthBits, int stencilBits ) } } + if( alphaBits != selected->cAlphaBits ) + { + if( alphaBits == current->cAlphaBits || current->cAlphaBits > selected->cAlphaBits ) + { + selected = current; + pixelFormat = i; + continue; + } + } + if( depthBits != selected->cDepthBits ) { if( depthBits == current->cDepthBits || current->cDepthBits > selected->cDepthBits ) @@ -765,7 +780,8 @@ GL_SetPixelformat qboolean GL_SetPixelformat( void ) { PIXELFORMATDESCRIPTOR PFD; - int colorBits, depthBits, stencilBits; + int colorBits, alphaBits; + int depthBits, stencilBits; int pixelFormat; size_t gamma_size; byte *savedGamma; @@ -789,17 +805,18 @@ qboolean GL_SetPixelformat( void ) // set color/depth/stencil colorBits = (gl_colorbits->integer) ? gl_colorbits->integer : 32; depthBits = (gl_depthbits->integer) ? gl_depthbits->integer : 24; + alphaBits = (gl_alphabits->integer) ? gl_alphabits->integer : 8; stencilBits = (gl_stencilbits->integer) ? gl_stencilbits->integer : 0; // choose a pixel format - pixelFormat = GL_ChoosePFD( colorBits, depthBits, stencilBits ); + pixelFormat = GL_ChoosePFD( colorBits, alphaBits, depthBits, stencilBits ); if( !pixelFormat ) { // try again with default color/depth/stencil - if( colorBits > 16 || depthBits > 16 || stencilBits > 0 ) - pixelFormat = GL_ChoosePFD( 16, 16, 0 ); - else pixelFormat = GL_ChoosePFD( 32, 24, 0 ); + if( colorBits > 16 || depthBits > 16 || alphaBits > 0 || stencilBits > 0 ) + pixelFormat = GL_ChoosePFD( 16, 0, 16, 0 ); + else pixelFormat = GL_ChoosePFD( 32, 0, 24, 0 ); if( !pixelFormat ) { @@ -833,6 +850,7 @@ qboolean GL_SetPixelformat( void ) } glConfig.color_bits = PFD.cColorBits; + glConfig.alpha_bits = PFD.cAlphaBits; glConfig.depth_bits = PFD.cDepthBits; glConfig.stencil_bits = PFD.cStencilBits; @@ -846,7 +864,7 @@ qboolean GL_SetPixelformat( void ) else glState.stencilEnabled = false; // print out PFD specifics - MsgDev( D_NOTE, "GL PFD: color( %d-bits ) Z( %d-bit )\n", PFD.cColorBits, PFD.cDepthBits ); + MsgDev( D_NOTE, "GL PFD: color( %d-bits ) alpha( %d-bits ) Z( %d-bit )\n", PFD.cColorBits, PFD.cAlphaBits, PFD.cDepthBits ); // init gamma ramp Mem_Set( glState.stateRamp, 0, sizeof( glState.stateRamp )); @@ -1322,6 +1340,8 @@ void R_RenderInfo_f( void ) Msg( "SKYMIP: %i\n", gl_skymip->integer ); Msg( "TEXTUREMODE: %s\n", gl_texturemode->string ); Msg( "VERTICAL SYNC: %s\n", gl_swapInterval->integer ? "enabled" : "disabled" ); + Msg( "Color %d bits, Alpha %d bits, Depth %d bits, Stencil %d bits\n", glConfig.color_bits, + glConfig.alpha_bits, glConfig.depth_bits, glConfig.stencil_bits ); } //======================================================================= @@ -1337,7 +1357,7 @@ void GL_InitCommands( void ) r_speeds = Cvar_Get( "r_speeds", "0", CVAR_ARCHIVE, "shows renderer speeds" ); r_fullbright = Cvar_Get( "r_fullbright", "0", CVAR_CHEAT, "disable lightmaps, get fullbright for entities" ); r_norefresh = Cvar_Get( "r_norefresh", "0", 0, "disable 3D rendering (use with caution)" ); - r_lighting_modulate = Cvar_Get( "r_lighting_modulate", "1", CVAR_ARCHIVE, "lightstyles modulate scale" ); + r_lighting_modulate = Cvar_Get( "r_lighting_modulate", "0.6", CVAR_ARCHIVE, "lightstyles modulate scale" ); r_adjust_fov = Cvar_Get( "r_adjust_fov", "1", CVAR_ARCHIVE, "making FOV adjustment for wide-screens" ); r_novis = Cvar_Get( "r_novis", "0", 0, "ignore vis information (perfomance test)" ); r_nocull = Cvar_Get( "r_nocull", "0", 0, "ignore frustrum culling (perfomance test)" ); @@ -1347,12 +1367,14 @@ void GL_InitCommands( void ) r_lightmap = Cvar_Get( "r_lightmap", "0", CVAR_CHEAT, "lightmap debugging tool" ); r_shadows = Cvar_Get( "r_shadows", "0", CVAR_ARCHIVE, "enable model shadows" ); r_fastsky = Cvar_Get( "r_fastsky", "0", CVAR_ARCHIVE, "enable algorhytm fo fast sky rendering (for old machines)" ); + r_drawentities = Cvar_Get( "r_drawentities", "1", CVAR_CHEAT|CVAR_ARCHIVE, "render entities" ); gl_picmip = Cvar_Get( "gl_picmip", "0", CVAR_RENDERINFO|CVAR_LATCH_VIDEO, "reduces resolution of textures by powers of 2" ); gl_skymip = Cvar_Get( "gl_skymip", "0", CVAR_RENDERINFO|CVAR_LATCH_VIDEO, "reduces resolution of skybox textures by powers of 2" ); gl_ignorehwgamma = Cvar_Get( "gl_ignorehwgamma", "0", CVAR_ARCHIVE|CVAR_LATCH_VIDEO, "ignore hardware gamma (e.g. not support)" ); gl_allow_software = Cvar_Get( "gl_allow_software", "0", CVAR_ARCHIVE, "allow OpenGL software emulation" ); gl_colorbits = Cvar_Get( "gl_colorbits", "0", CVAR_ARCHIVE | CVAR_LATCH_VIDEO, "pixelformat color bits (0 - auto)" ); + gl_alphabits = Cvar_Get( "gl_alphabits", "0", CVAR_ARCHIVE | CVAR_LATCH_VIDEO, "pixelformat alpha bits (0 - auto)" ); gl_depthbits = Cvar_Get( "gl_depthbits", "0", CVAR_ARCHIVE | CVAR_LATCH_VIDEO, "pixelformat depth bits (0 - auto)" ); gl_texturemode = Cvar_Get( "gl_texturemode", "GL_LINEAR_MIPMAP_LINEAR", CVAR_ARCHIVE, "texture filter" ); gl_texturebits = Cvar_Get( "gl_texturebits", "0", CVAR_ARCHIVE|CVAR_LATCH_VIDEO, "set texture upload format (0 - auto)" ); @@ -1368,7 +1390,6 @@ void GL_InitCommands( void ) gl_showtextures = Cvar_Get( "r_showtextures", "0", CVAR_CHEAT, "show all uploaded textures (type values from 1 to 9)" ); gl_finish = Cvar_Get( "gl_finish", "0", CVAR_ARCHIVE, "use glFinish instead of glFlush" ); gl_clear = Cvar_Get( "gl_clear", "0", CVAR_ARCHIVE, "clearing screen after each frame" ); - gl_texsort = Cvar_Get( "gl_texsort", "1", CVAR_ARCHIVE, "enable or disable sorting by texture" ); // make sure r_swapinterval is checked after vid_restart gl_swapInterval->modified = true; diff --git a/engine/client/gl_warp.c b/engine/client/gl_warp.c index 33b07d73..3e75fda3 100644 --- a/engine/client/gl_warp.c +++ b/engine/client/gl_warp.c @@ -164,19 +164,28 @@ EmitWaterPolys Does a water warp on the pre-fragmented glpoly_t chain ============= */ -void EmitWaterPolys( msurface_t *fa ) +void EmitWaterPolys( glpoly_t *polys ) { glpoly_t *p; - float *v; - int i; + float *v, nv, waveHeight; float s, t, os, ot; + int i; - for( p = fa->polys; p; p = p->next ) + if( RI.currententity == clgame.entities ) + waveHeight = RI.refdef.movevars->waveHeight * 2.0f; + else waveHeight = RI.currententity->curstate.scale * 32.0f; + + for( p = polys; p; p = p->next ) { pglBegin( GL_POLYGON ); for( i = 0, v = p->verts[0]; i < p->numverts; i++, v += VERTEXSIZE ) { + if( waveHeight ) + nv = v[2] + waveHeight + ( waveHeight * com.sin(v[0] * 0.02 + cl.time) + * com.sin(v[1] * 0.02 + cl.time) * com.sin(v[2] * 0.02 + cl.time)); + else nv = v[2]; + os = v[3]; ot = v[4]; @@ -187,9 +196,8 @@ void EmitWaterPolys( msurface_t *fa ) t *= ( 1.0f / SUBDIVIDE_SIZE ); pglTexCoord2f( s, t ); - pglVertex3fv( v ); + pglVertex3f( v[0], v[1], nv ); } - pglEnd(); } } @@ -242,7 +250,6 @@ void R_DrawSkyChain( msurface_t *s ) { msurface_t *fa; - // used when gl_texsort is on GL_Bind( GL_TEXTURE0, tr.solidskyTexture ); speedscale = cl.time * 8; diff --git a/engine/common/com_export.h b/engine/common/com_export.h index ffa28516..49f12384 100644 --- a/engine/common/com_export.h +++ b/engine/common/com_export.h @@ -20,7 +20,6 @@ extern stdlib_api_t com; #define TF_FONT (TF_UNCOMPRESSED|TF_NOPICMIP|TF_NOMIPMAP|TF_CLAMP) #define TF_IMAGE (TF_UNCOMPRESSED|TF_NOPICMIP|TF_NOMIPMAP) #define TF_DECAL (TF_CLAMP|TF_UNCOMPRESSED) -#define TF_LIGHTMAP TF_FONT typedef enum { @@ -38,6 +37,7 @@ typedef enum TF_HAS_LUMA = BIT(11), // sets by GL_UploadTexture TF_MAKELUMA = BIT(12), // create luma from quake texture TF_NORMALMAP = BIT(13), // is a normalmap + TF_LIGHTMAP = BIT(14), // is a lightmap } texFlags_t; typedef struct diff --git a/engine/common/model.c b/engine/common/model.c index 91e731f4..fa767d4e 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -495,12 +495,12 @@ static void Mod_LoadTextures( const dlump_t *l ) int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6); if( world.version == HLBSP_VERSION ) size += sizeof( short ) + 768; - tx->fb_texturenum = GL_LoadTexture( texname, (byte *)mt, size, TF_MAKELUMA ); + tx->fb_texturenum = GL_LoadTexture( texname, (byte *)mt, size, TF_MAKELUMA|TF_NOMIPMAP ); } else { // okay, loading it from wad - tx->fb_texturenum = GL_LoadTexture( texname, NULL, 0, TF_MAKELUMA ); + tx->fb_texturenum = GL_LoadTexture( texname, NULL, 0, TF_MAKELUMA|TF_NOMIPMAP ); } } diff --git a/engine/common/world.h b/engine/common/world.h index 1addb965..7d2b9fa0 100644 --- a/engine/common/world.h +++ b/engine/common/world.h @@ -56,10 +56,11 @@ typedef struct area_s typedef struct { - char pattern[CS_SIZE]; + char pattern[MAX_STRING]; float map[MAX_STRING]; int length; float value; + qboolean interp; // allow to interpolate this lightstyle } lightstyle_t; extern const char *et_name[]; diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 108d5eb1..ce072600 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -4342,6 +4342,7 @@ void SV_LoadFromFile( script_t *entities ) token_t token; int inhibited, spawned, died; int current_skill = Cvar_VariableInteger( "skill" ); // lock skill level + qboolean inhibits_ents = (world.version == Q1BSP_VERSION) ? true : false; qboolean deathmatch = Cvar_VariableInteger( "deathmatch" ); qboolean create_world = true; edict_t *ent; @@ -4366,12 +4367,41 @@ void SV_LoadFromFile( script_t *entities ) if( !SV_ParseEdict( entities, ent )) continue; + // remove things from different skill levels or deathmatch + if( inhibits_ents && deathmatch ) + { + if( ent->v.spawnflags & (1<<11)) + { + SV_FreeEdict( ent ); + inhibited++; + continue; + } + } + else if( inhibits_ents && current_skill == 0 && ent->v.spawnflags & (1<<8)) + { + SV_FreeEdict( ent ); + inhibited++; + continue; + } + else if( inhibits_ents && current_skill == 1 && ent->v.spawnflags & (1<<9)) + { + SV_FreeEdict( ent ); + inhibited++; + continue; + } + else if( inhibits_ents && current_skill >= 2 && ent->v.spawnflags & (1<<10)) + { + SV_FreeEdict( ent ); + inhibited++; + continue; + } + if( svgame.dllFuncs.pfnSpawn( ent ) == -1 ) died++; else spawned++; } - MsgDev( D_INFO, "%i entities inhibited\n", inhibited ); + MsgDev( D_INFO, "\n%i entities inhibited\n", inhibited ); } /* diff --git a/engine/server/sv_world.c b/engine/server/sv_world.c index 854b9cb3..a9887c0f 100644 --- a/engine/server/sv_world.c +++ b/engine/server/sv_world.c @@ -345,7 +345,7 @@ void SV_ClearWorld( void ) // clear lightstyles for( i = 0; i < MAX_LIGHTSTYLES; i++ ) - sv.lightstyles[i].value = 1.0f; + sv.lightstyles[i].value = 256.0f; sv_lastofs = -1; Mem_Set( sv_areanodes, 0, sizeof( sv_areanodes )); @@ -1352,7 +1352,6 @@ trace_t SV_MoveToss( edict_t *tossent, edict_t *ignore ) */ static vec3_t sv_pointColor; -static float sv_modulate; /* ================= @@ -1431,7 +1430,7 @@ static qboolean SV_RecursiveLightPoint( model_t *model, mnode_t *node, const vec for( map = 0; map < MAXLIGHTMAPS && surf->styles[map] != 255; map++ ) { - scale = sv.lightstyles[surf->styles[map]].value * sv_modulate; + scale = sv.lightstyles[surf->styles[map]].value; sv_pointColor[0] += lm->r * scale; sv_pointColor[1] += lm->g * scale; @@ -1459,9 +1458,9 @@ void SV_RunLightStyles( void ) for( i = 0, ls = sv.lightstyles; i < MAX_LIGHTSTYLES; i++, ls++ ) { - if( ls->length == 0 ) ls->value = 0.0f; // disable this light - else if( ls->length == 1 ) ls->value = ls->map[0]; - else ls->value = ls->map[ofs%ls->length]; + if( ls->length == 0 ) ls->value = 256.0f * sv_lighting_modulate->value; // disable this light + else if( ls->length == 1 ) ls->value = ls->map[0] * 22.0f * sv_lighting_modulate->value; + else ls->value = ls->map[ofs%ls->length] * 22.0f * sv_lighting_modulate->value; } } @@ -1485,7 +1484,7 @@ void SV_SetLightStyle( int style, const char* s ) sv.lightstyles[style].length = j; for( k = 0; k < j; k++ ) - sv.lightstyles[style].map[k] = (float)( s[k]-'a' ) / (float)( 'm'-'a' ); + sv.lightstyles[style].map[k] = (float)(s[k] - 'a'); if( sv.state != ss_active ) return; @@ -1527,7 +1526,6 @@ int SV_LightForEntity( edict_t *pEdict ) else end[2] = start[2] - 8192; VectorSet( sv_pointColor, 1.0f, 1.0f, 1.0f ); - sv_modulate = sv_lighting_modulate->value * (1.0f / 255); SV_RecursiveLightPoint( sv.worldmodel, sv.worldmodel->nodes, start, end ); return VectorAvg( sv_pointColor ); diff --git a/engine/warpsin.h b/engine/warpsin.h index bcadd68a..e140acf9 100644 --- a/engine/warpsin.h +++ b/engine/warpsin.h @@ -1,47 +1,53 @@ -/*** -* -* Copyright (c) 1996-2002, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ +/* +Copyright (C) 1997-2001 Id Software, Inc. - 0, 0.19633, 0.392541, 0.588517, 0.784137, 0.979285, 1.17384, 1.3677, - 1.56072, 1.75281, 1.94384, 2.1337, 2.32228, 2.50945, 2.69512, 2.87916, - 3.06147, 3.24193, 3.42044, 3.59689, 3.77117, 3.94319, 4.11282, 4.27998, - 4.44456, 4.60647, 4.76559, 4.92185, 5.07515, 5.22538, 5.37247, 5.51632, - 5.65685, 5.79398, 5.92761, 6.05767, 6.18408, 6.30677, 6.42566, 6.54068, - 6.65176, 6.75883, 6.86183, 6.9607, 7.05537, 7.14579, 7.23191, 7.31368, - 7.39104, 7.46394, 7.53235, 7.59623, 7.65552, 7.71021, 7.76025, 7.80562, - 7.84628, 7.88222, 7.91341, 7.93984, 7.96148, 7.97832, 7.99036, 7.99759, - 8, 7.99759, 7.99036, 7.97832, 7.96148, 7.93984, 7.91341, 7.88222, - 7.84628, 7.80562, 7.76025, 7.71021, 7.65552, 7.59623, 7.53235, 7.46394, - 7.39104, 7.31368, 7.23191, 7.14579, 7.05537, 6.9607, 6.86183, 6.75883, - 6.65176, 6.54068, 6.42566, 6.30677, 6.18408, 6.05767, 5.92761, 5.79398, - 5.65685, 5.51632, 5.37247, 5.22538, 5.07515, 4.92185, 4.76559, 4.60647, - 4.44456, 4.27998, 4.11282, 3.94319, 3.77117, 3.59689, 3.42044, 3.24193, - 3.06147, 2.87916, 2.69512, 2.50945, 2.32228, 2.1337, 1.94384, 1.75281, - 1.56072, 1.3677, 1.17384, 0.979285, 0.784137, 0.588517, 0.392541, 0.19633, - 9.79717e-16, -0.19633, -0.392541, -0.588517, -0.784137, -0.979285, -1.17384, -1.3677, - -1.56072, -1.75281, -1.94384, -2.1337, -2.32228, -2.50945, -2.69512, -2.87916, - -3.06147, -3.24193, -3.42044, -3.59689, -3.77117, -3.94319, -4.11282, -4.27998, - -4.44456, -4.60647, -4.76559, -4.92185, -5.07515, -5.22538, -5.37247, -5.51632, - -5.65685, -5.79398, -5.92761, -6.05767, -6.18408, -6.30677, -6.42566, -6.54068, - -6.65176, -6.75883, -6.86183, -6.9607, -7.05537, -7.14579, -7.23191, -7.31368, - -7.39104, -7.46394, -7.53235, -7.59623, -7.65552, -7.71021, -7.76025, -7.80562, - -7.84628, -7.88222, -7.91341, -7.93984, -7.96148, -7.97832, -7.99036, -7.99759, - -8, -7.99759, -7.99036, -7.97832, -7.96148, -7.93984, -7.91341, -7.88222, - -7.84628, -7.80562, -7.76025, -7.71021, -7.65552, -7.59623, -7.53235, -7.46394, - -7.39104, -7.31368, -7.23191, -7.14579, -7.05537, -6.9607, -6.86183, -6.75883, - -6.65176, -6.54068, -6.42566, -6.30677, -6.18408, -6.05767, -5.92761, -5.79398, - -5.65685, -5.51632, -5.37247, -5.22538, -5.07515, -4.92185, -4.76559, -4.60647, - -4.44456, -4.27998, -4.11282, -3.94319, -3.77117, -3.59689, -3.42044, -3.24193, - -3.06147, -2.87916, -2.69512, -2.50945, -2.32228, -2.1337, -1.94384, -1.75281, - -1.56072, -1.3677, -1.17384, -0.979285, -0.784137, -0.588517, -0.392541, -0.19633, +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + + +0.000000, 0.098165, 0.196270, 0.294259, 0.392069, 0.489643, 0.586920, 0.683850, +0.780360, 0.876405, 0.971920, 1.066850, 1.161140, 1.254725, 1.347560, 1.439580, +1.530735, 1.620965, 1.710220, 1.798445, 1.885585, 1.971595, 2.056410, 2.139990, +2.222280, 2.303235, 2.382795, 2.460925, 2.537575, 2.612690, 2.686235, 2.758160, +2.828425, 2.896990, 2.963805, 3.028835, 3.092040, 3.153385, 3.212830, 3.270340, +3.325880, 3.379415, 3.430915, 3.480350, 3.527685, 3.572895, 3.615955, 3.656840, +3.695520, 3.731970, 3.766175, 3.798115, 3.827760, 3.855105, 3.880125, 3.902810, +3.923140, 3.941110, 3.956705, 3.969920, 3.980740, 3.989160, 3.995180, 3.998795, +4.000000, 3.998795, 3.995180, 3.989160, 3.980740, 3.969920, 3.956705, 3.941110, +3.923140, 3.902810, 3.880125, 3.855105, 3.827760, 3.798115, 3.766175, 3.731970, +3.695520, 3.656840, 3.615955, 3.572895, 3.527685, 3.480350, 3.430915, 3.379415, +3.325880, 3.270340, 3.212830, 3.153385, 3.092040, 3.028835, 2.963805, 2.896990, +2.828425, 2.758160, 2.686235, 2.612690, 2.537575, 2.460925, 2.382795, 2.303235, +2.222280, 2.139990, 2.056410, 1.971595, 1.885585, 1.798445, 1.710220, 1.620965, +1.530735, 1.439580, 1.347560, 1.254725, 1.161140, 1.066850, 0.971920, 0.876405, +0.780360, 0.683850, 0.586920, 0.489643, 0.392069, 0.294259, 0.196270, 0.098165, +0.000000, -0.098165, -0.196270, -0.294259, -0.392069, -0.489643, -0.586920, -0.683850, +-0.780360, -0.876405, -0.971920, -1.066850, -1.161140, -1.254725, -1.347560, -1.439580, +-1.530735, -1.620965, -1.710220, -1.798445, -1.885585, -1.971595, -2.056410, -2.139990, +-2.222280, -2.303235, -2.382795, -2.460925, -2.537575, -2.612690, -2.686235, -2.758160, +-2.828425, -2.896990, -2.963805, -3.028835, -3.092040, -3.153385, -3.212830, -3.270340, +-3.325880, -3.379415, -3.430915, -3.480350, -3.527685, -3.572895, -3.615955, -3.656840, +-3.695520, -3.731970, -3.766175, -3.798115, -3.827760, -3.855105, -3.880125, -3.902810, +-3.923140, -3.941110, -3.956705, -3.969920, -3.980740, -3.989160, -3.995180, -3.998795, +-4.000000, -3.998795, -3.995180, -3.989160, -3.980740, -3.969920, -3.956705, -3.941110, +-3.923140, -3.902810, -3.880125, -3.855105, -3.827760, -3.798115, -3.766175, -3.731970, +-3.695520, -3.656840, -3.615955, -3.572895, -3.527685, -3.480350, -3.430915, -3.379415, +-3.325880, -3.270340, -3.212830, -3.153385, -3.092040, -3.028835, -2.963805, -2.896990, +-2.828425, -2.758160, -2.686235, -2.612690, -2.537575, -2.460925, -2.382795, -2.303235, +-2.222280, -2.139990, -2.056410, -1.971595, -1.885585, -1.798445, -1.710220, -1.620965, +-1.530735, -1.439580, -1.347560, -1.254725, -1.161140, -1.066850, -0.971920, -0.876405, +-0.780360, -0.683850, -0.586920, -0.489643, -0.392069, -0.294259, -0.196270, -0.098165, diff --git a/launch/imagelib/img_utils.c b/launch/imagelib/img_utils.c index cfd9fc0a..f1cda80b 100644 --- a/launch/imagelib/img_utils.c +++ b/launch/imagelib/img_utils.c @@ -646,7 +646,9 @@ NOTE: must call Image_GetPaletteXXX before used qboolean Image_Copy8bitRGBA( const byte *in, byte *out, int pixels ) { int *iout = (int *)out; + byte *fin = (byte *)in; rgba_t *col; + int i; if( !image.d_currentpal ) { @@ -659,6 +661,18 @@ qboolean Image_Copy8bitRGBA( const byte *in, byte *out, int pixels ) return false; } + // this is a base image with luma - clear luma pixels + if( image.flags & IMAGE_HAS_LUMA ) + { + for( i = 0; i < image.width * image.height; i++ ) + { + if( image.flags & IMAGE_HAS_LUMA_Q1 ) + fin[i] = fin[i] < 224 ? fin[i] : 0; + else if( image.flags & IMAGE_HAS_LUMA_Q2 ) + fin[i] = (fin[i] >= 208 && fin[i] <= 240 ) ? 0 : fin[i]; + } + } + while( pixels >= 8 ) { iout[0] = image.d_currentpal[in[0]]; @@ -1270,9 +1284,9 @@ byte *Image_CreateLumaInternal( const byte *fin, int width, int height, int type for( i = 0; i < width * height; i++ ) { if( flags & IMAGE_HAS_LUMA_Q1 ) - *out++ = fin[i] > 224 ? fin[i] : 0; + *out++ = fin[i] >= 224 ? fin[i] : 0; else if( flags & IMAGE_HAS_LUMA_Q2 ) - *out++ = (fin[i] > 208 && fin[i] < 240) ? fin[i] : 0; + *out++ = (fin[i] >= 208 && fin[i] <= 240) ? fin[i] : 0; } break; default: diff --git a/release.bat b/release.bat index f680f7a3..e2799411 100644 --- a/release.bat +++ b/release.bat @@ -23,9 +23,6 @@ if errorlevel 1 set BUILD_ERROR=1 %MSDEV% launch/launch.dsp %CONFIG%"launch - Win32 Release" %build_target% if errorlevel 1 set BUILD_ERROR=1 -%MSDEV% vid_gl/vid_gl.dsp %CONFIG%"vid_gl - Win32 Release" %build_target% -if errorlevel 1 set BUILD_ERROR=1 - if "%BUILD_ERROR%"=="" goto build_ok echo *********************