diff options
author | Andrey Nazarov <skuller@skuller.net> | 2008-08-16 10:19:42 +0000 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2008-08-16 10:19:42 +0000 |
commit | 1526e22e4ff29153e9c127081e8ea8d9e2f33b8c (patch) | |
tree | b361766433d4a7b4a111865afd52803e2bbf7754 /source/gl_world.c | |
parent | e826e5f176f21cd18b3bbc22887a266835ada57c (diff) |
Split some monolithic include files into smaller ones.
Use single BSP models cache for refresh and collision subsystems.
Refresh libraries may not longer be dynamically loaded.
Made gi.TagMalloc use separate tag namespace to avoid
conflicts with engine reserverd tags.
Fixed listing order of MVD channels in chooser menu.
A lot of misc changes... MSVC build is definitely broken now.
Diffstat (limited to 'source/gl_world.c')
-rw-r--r-- | source/gl_world.c | 440 |
1 files changed, 192 insertions, 248 deletions
diff --git a/source/gl_world.c b/source/gl_world.c index a585dc4..7a38d69 100644 --- a/source/gl_world.c +++ b/source/gl_world.c @@ -22,159 +22,63 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. vec3_t modelViewOrigin; // viewer origin in model space -static vec3_t lightcolor; - -static qboolean GL_LightPoint_r( bspNode_t *node, vec3_t start, vec3_t end ) { - vec_t startFrac, endFrac, midFrac; - vec3_t _start, mid; - int side; - qboolean ret; - bspSurface_t *surf; - bspTexinfo_t *texinfo; - int i, pitch; - int s, t; +qboolean GL_LightPoint( vec3_t origin, vec3_t color ) { + bsp_t *bsp = gl_static.world.cache; + mface_t *surf; + int s, t; byte *b1, *b2, *b3, *b4; int fracu, fracv; int w1, w2, w3, w4; - int color[3]; - - VectorCopy( start, _start ); - while( node->plane ) { - // calculate distancies - startFrac = PlaneDiffFast( _start, node->plane ); - endFrac = PlaneDiffFast( end, node->plane ); - side = ( startFrac < 0 ); - - if( ( endFrac < 0 ) == side ) { - // both points are one the same side - node = node->children[side]; - continue; - } - - // find crossing point - midFrac = startFrac / ( startFrac - endFrac ); - LerpVector( _start, end, midFrac, mid ); - - // check near side - ret = GL_LightPoint_r( node->children[side], _start, mid ); - if( ret ) { - return ret; - } - - for( i = 0, surf = node->firstFace; i < node->numFaces; i++, surf++ ) { - texinfo = surf->texinfo; - if( texinfo->flags & (SURF_WARP|SURF_SKY) ) { - continue; - } - if( !surf->lightmap ) { - continue; - } - s = DotProduct( texinfo->axis[0], mid ) + texinfo->offset[0]; - t = DotProduct( texinfo->axis[1], mid ) + texinfo->offset[1]; + byte temp[3]; + int pitch; + vec3_t point; - s -= surf->texturemins[0]; - t -= surf->texturemins[1]; - if( s < 0 || t < 0 ) { - continue; - } - if( s > surf->extents[0] || t > surf->extents[1] ) { - continue; - } - - fracu = s & 15; - fracv = t & 15; - - s >>= 4; - t >>= 4; - - pitch = ( surf->extents[0] >> 4 ) + 1; - b1 = &surf->lightmap[3 * ( ( t + 0 ) * pitch + ( s + 0 ) )]; - b2 = &surf->lightmap[3 * ( ( t + 0 ) * pitch + ( s + 1 ) )]; - b3 = &surf->lightmap[3 * ( ( t + 1 ) * pitch + ( s + 1 ) )]; - b4 = &surf->lightmap[3 * ( ( t + 1 ) * pitch + ( s + 0 ) )]; - - w1 = ( 16 - fracu ) * ( 16 - fracv ); - w2 = fracu * ( 16 - fracv ); - w3 = fracu * fracv; - w4 = ( 16 - fracu ) * fracv; - - color[0] = ( w1 * b1[0] + w2 * b2[0] + w3 * b3[0] + w4 * b4[0] ) >> 8; - color[1] = ( w1 * b1[1] + w2 * b2[1] + w3 * b3[1] + w4 * b4[1] ) >> 8; - color[2] = ( w1 * b1[2] + w2 * b2[2] + w3 * b3[2] + w4 * b4[2] ) >> 8; - - VectorMA( lightcolor, 1.0f / 255, color, lightcolor ); - - return qtrue; - } - - // check far side - VectorCopy( mid, _start ); - node = node->children[side^1]; + if( !bsp || !bsp->lightmap ) { + return qfalse; } - return qfalse; -} - -void GL_LightPoint( vec3_t origin, vec3_t dest ) { - extern cvar_t *gl_modulate_hack; - vec3_t point; -#if USE_DYNAMIC - dlight_t *light; - vec3_t dir; - vec_t dist, f; -#endif - int i; - - if( !r_world.name[0] || gl_fullbright->integer ) { - VectorSet( dest, 1, 1, 1 ); - return; - } - point[0] = origin[0]; point[1] = origin[1]; point[2] = origin[2] - 8192; - - VectorClear( lightcolor ); - if( !r_world.lightmap || !GL_LightPoint_r( r_world.nodes, origin, point ) ) { - VectorSet( lightcolor, 1, 1, 1 ); + + surf = BSP_LightPoint( bsp->nodes, origin, point, &s, &t ); + if( !surf ) { + return qfalse; } - if( gl_modulate_hack && gl_modulate_hack->integer ) { - VectorScale( lightcolor, gl_modulate->value, lightcolor ); - } + fracu = s & 15; + fracv = t & 15; -#if USE_DYNAMIC - for( i = 0, light = glr.fd.dlights; i < glr.fd.num_dlights; i++, light++ ) { - VectorSubtract( light->origin, origin, dir ); - dist = VectorLength( dir ); - if( dist > light->intensity ) { - continue; - } - f = 1.0f - dist / light->intensity; - VectorMA( lightcolor, f, light->color, lightcolor ); - } -#endif + s >>= 4; + t >>= 4; - /* apply modulate twice to mimic original ref_gl behavior */ - VectorScale( lightcolor, gl_modulate->value, lightcolor ); + pitch = ( surf->extents[0] >> 4 ) + 1; + b1 = &surf->lightmap[3 * ( ( t + 0 ) * pitch + ( s + 0 ) )]; + b2 = &surf->lightmap[3 * ( ( t + 0 ) * pitch + ( s + 1 ) )]; + b3 = &surf->lightmap[3 * ( ( t + 1 ) * pitch + ( s + 1 ) )]; + b4 = &surf->lightmap[3 * ( ( t + 1 ) * pitch + ( s + 0 ) )]; + + w1 = ( 16 - fracu ) * ( 16 - fracv ); + w2 = fracu * ( 16 - fracv ); + w3 = fracu * fracv; + w4 = ( 16 - fracu ) * fracv; - for( i = 0; i < 3; i++ ) { - if( lightcolor[i] > 1 ) { - lightcolor[i] = 1; - } else if( lightcolor[i] < 0 ) { - lightcolor[i] = 0; - } - } + temp[0] = ( w1 * b1[0] + w2 * b2[0] + w3 * b3[0] + w4 * b4[0] ) >> 8; + temp[1] = ( w1 * b1[1] + w2 * b2[1] + w3 * b3[1] + w4 * b4[1] ) >> 8; + temp[2] = ( w1 * b1[2] + w2 * b2[2] + w3 * b3[2] + w4 * b4[2] ) >> 8; + + GL_AdjustColor( temp, temp, 2 ); - VectorCopy( lightcolor, dest ); + VectorScale( temp, 1.0f / 255, color ); + return qtrue; } #if USE_DYNAMIC -static void GL_MarkLights_r( bspNode_t *node, dlight_t *light ) { +static void GL_MarkLights_r( mnode_t *node, dlight_t *light ) { vec_t dot; int count; - bspSurface_t *face; + mface_t *face; int lightbit = 1 << light->index; while( node->plane ) { @@ -215,19 +119,16 @@ void GL_MarkLights( void ) { for( i = 0, light = glr.fd.dlights; i < glr.fd.num_dlights; i++, light++ ) { light->index = i; VectorCopy( light->origin, light->transformed ); - GL_MarkLights_r( r_world.nodes, light ); + GL_MarkLights_r( gl_static.world.cache->nodes, light ); } } -static void GL_TransformLights( bspSubmodel_t *model ) { +static void GL_TransformLights( mmodel_t *model ) { int i; dlight_t *light; vec3_t temp; if( !model->headnode ) { - // this happens on some maps - // could lead to a crash of the original ref_gl - //Com_WPrintf( "GL_TransformLights: NULL headnode\n" ); return; } @@ -239,22 +140,68 @@ static void GL_TransformLights( bspSubmodel_t *model ) { light->transformed[2] = DotProduct( temp, glr.entaxis[2] ); GL_MarkLights_r( model->headnode, light ); - } } + +void GL_AddLights( vec3_t origin, vec3_t color ) { + dlight_t *light; + vec3_t dir; + vec_t dist, f; + int i; + + for( i = 0, light = glr.fd.dlights; i < glr.fd.num_dlights; i++, light++ ) { + VectorSubtract( light->origin, origin, dir ); + dist = VectorLength( dir ); + if( dist > light->intensity ) { + continue; + } + f = 1.0f - dist / light->intensity; + VectorMA( color, f, light->color, color ); + } +} +#endif + +void R_LightPoint( vec3_t origin, vec3_t color ) { + int i; + + if( gl_fullbright->integer ) { + VectorSet( color, 1, 1, 1 ); + return; + } + + // get lighting from world + if( !GL_LightPoint( origin, color ) ) { + VectorSet( color, 1, 1, 1 ); + } + +#if USE_DYNAMIC + if( gl_dynamic->integer ) { + // add dynamic lights + GL_AddLights( origin, color ); + } #endif + // apply modulate twice to mimic original ref_gl behavior + VectorScale( color, gl_modulate->value, color ); + + for( i = 0; i < 3; i++ ) { + clamp( color[i], 0, 1 ); + } +} + void GL_MarkLeaves( void ) { - byte fatvis[MAX_MAP_LEAFS/8]; - bspLeaf_t *leaf, *lastleaf; - bspNode_t *node, *lastnode; - byte *vis1, *vis2; - uint32_t *dst, *src1, *src2; + static int lastNodesVisible; + byte vis1[MAX_MAP_VIS]; + byte vis2[MAX_MAP_VIS]; + mleaf_t *leaf; + mnode_t *node; + uint32_t *src1, *src2; int cluster1, cluster2, longs; vec3_t tmp; - static int lastNodesVisible; + int i; + bsp_t *bsp = gl_static.world.cache; - leaf = Bsp_FindLeaf( glr.fd.vieworg ); + leaf = BSP_PointLeaf( bsp->nodes, glr.fd.vieworg ); cluster1 = cluster2 = leaf->cluster; VectorCopy( glr.fd.vieworg, tmp ); if( !leaf->contents ) { @@ -262,7 +209,7 @@ void GL_MarkLeaves( void ) { } else { tmp[2] += 16; } - leaf = Bsp_FindLeaf( tmp ); + leaf = BSP_PointLeaf( bsp->nodes, tmp ); if( !( leaf->contents & CONTENTS_SOLID ) ) { cluster2 = leaf->cluster; } @@ -275,55 +222,43 @@ void GL_MarkLeaves( void ) { goto finish; } - vis1 = vis2 = Bsp_ClusterPVS( cluster1 ); - if( cluster1 != cluster2 ) { - vis2 = Bsp_ClusterPVS( cluster2 ); - if( !vis1 ) { - vis1 = vis2; - } else if( !vis2 ) { - vis2 = vis1; - } - } glr.visframe++; - lastNodesVisible = 0; glr.viewcluster1 = cluster1; glr.viewcluster2 = cluster2; - if( !vis1 || gl_novis->integer ) { - /* mark everything visible */ - lastleaf = r_world.leafs + r_world.numLeafs; - for( leaf = r_world.leafs; leaf != lastleaf; leaf++ ) { - leaf->visframe = glr.visframe; + if( !bsp->vis || gl_novis->integer || cluster1 == -1 ) { + // mark everything visible + for( i = 0; i < bsp->numnodes; i++ ) { + bsp->nodes[i].visframe = glr.visframe; } - lastnode = r_world.nodes + r_world.numNodes; - for( node = r_world.nodes; node != lastnode; node++ ) { - node->visframe = glr.visframe; + for( i = 0; i < bsp->numleafs; i++ ) { + bsp->leafs[i].visframe = glr.visframe; } - lastNodesVisible = r_world.numNodes; + lastNodesVisible = bsp->numnodes; goto finish; } - if( vis1 != vis2 ) { - longs = ( r_world.numClusters + 31 ) >> 5; + BSP_ClusterVis( bsp, vis1, cluster1, DVIS_PVS ); + if( cluster1 != cluster2 ) { + BSP_ClusterVis( bsp, vis2, cluster2, DVIS_PVS ); + longs = ( bsp->visrowsize + 31 ) >> 5; src1 = ( uint32_t * )vis1; src2 = ( uint32_t * )vis2; - dst = ( uint32_t * )fatvis; while( longs-- ) { - *dst++ = *src1++ | *src2++; + *src1++ |= *src2++; } - vis1 = fatvis; } - - lastleaf = r_world.leafs + r_world.numLeafs; - for( leaf = r_world.leafs; leaf != lastleaf; leaf++ ) { + + lastNodesVisible = 0; + for( i = 0, leaf = bsp->leafs; i < bsp->numleafs; i++, leaf++ ) { cluster1 = leaf->cluster; if( cluster1 == -1 ) { continue; } if( Q_IsBitSet( vis1, cluster1 ) ) { - node = ( bspNode_t * )leaf; + node = ( mnode_t * )leaf; - /* mark parent nodes visible */ + // mark parent nodes visible do { if( node->visframe == glr.visframe ) { break; @@ -340,40 +275,16 @@ finish: } -#define NODE_CLIPPED 0 -#define NODE_UNCLIPPED 15 - -static inline qboolean GL_ClipNodeToFrustum( bspNode_t *node, int *clipflags ) { - int flags = *clipflags; - int i, bits, mask; - - for( i = 0, mask = 1; i < 4; i++, mask <<= 1 ) { - if( flags & mask ) { - continue; - } - bits = BoxOnPlaneSide( node->mins, node->maxs, - &glr.frustumPlanes[i] ); - if( bits == BOX_BEHIND ) { - return qfalse; - } - if( bits == BOX_INFRONT ) { - flags |= mask; - } - } - - *clipflags = flags; - - return qtrue; -} #define BACKFACE_EPSILON 0.001f -#define SIDE_FRONT 0 -#define SIDE_BACK 1 +#define BSP_CullFace( face, dot ) \ + ( ( (dot) < -BACKFACE_EPSILON && !( (face)->drawflags & DSURF_PLANEBACK ) ) || \ + ( (dot) > BACKFACE_EPSILON && ( (face)->drawflags & DSURF_PLANEBACK ) ) ) -void GL_DrawBspModel( bspSubmodel_t *model ) { - bspSurface_t *face; +void GL_DrawBspModel( mmodel_t *model ) { + mface_t *face; int count; vec3_t bounds[2]; vec_t dot; @@ -429,13 +340,11 @@ void GL_DrawBspModel( bspSubmodel_t *model ) { /* draw visible faces */ /* FIXME: go by headnode instead? */ - face = model->firstFace; - count = model->numFaces; + face = model->firstface; + count = model->numfaces; while( count-- ) { dot = PlaneDiffFast( modelViewOrigin, face->plane ); - if( ( dot < -BACKFACE_EPSILON && face->side == SIDE_FRONT ) || - ( dot > BACKFACE_EPSILON && face->side == SIDE_BACK ) ) - { + if( BSP_CullFace( face, dot ) ) { c.facesCulled++; } else { /* FIXME: trans surfaces are not supported on inline models */ @@ -449,61 +358,95 @@ void GL_DrawBspModel( bspSubmodel_t *model ) { qglPopMatrix(); } -static void GL_WorldNode_r( bspNode_t *node, int clipflags ) { - bspLeaf_t *leaf; - bspSurface_t **leafFace, *face; - int count, side, area; +#define NODE_CLIPPED 0 +#define NODE_UNCLIPPED 15 + +static inline qboolean GL_ClipNode( mnode_t *node, int *clipflags ) { + int flags = *clipflags; + int i, bits, mask; + + if( flags == NODE_UNCLIPPED ) { + return qtrue; + } + for( i = 0, mask = 1; i < 4; i++, mask <<= 1 ) { + if( flags & mask ) { + continue; + } + bits = BoxOnPlaneSide( node->mins, node->maxs, + &glr.frustumPlanes[i] ); + if( bits == BOX_BEHIND ) { + return qfalse; + } + if( bits == BOX_INFRONT ) { + flags |= mask; + } + } + + *clipflags = flags; + + return qtrue; +} + +static inline void GL_DrawLeaf( mleaf_t *leaf ) { + mface_t **face, **last; + + if( leaf->contents == CONTENTS_SOLID ) { + return; // solid leaf + } + if( glr.fd.areabits && !Q_IsBitSet( glr.fd.areabits, leaf->area ) ) { + return; // door blocks sight + } + last = leaf->firstleafface + leaf->numleaffaces; + for( face = leaf->firstleafface; face < last; face++ ) { + (*face)->drawframe = glr.drawframe; + } +} + +static inline void GL_DrawNode( mnode_t *node, vec_t dot ) { + mface_t *face, *last = node->firstface + node->numfaces; + + for( face = node->firstface; face < last; face++ ) { + if( face->drawframe != glr.drawframe ) { + continue; + } + if( BSP_CullFace( face, dot ) ) { + c.facesCulled++; + } else { + GL_AddFace( face ); + } + } + + c.nodesDrawn++; +} + +static void GL_WorldNode_r( mnode_t *node, int clipflags ) { + int side; vec_t dot; - + while( node->visframe == glr.visframe ) { - if( gl_cull_nodes->integer && clipflags != NODE_UNCLIPPED && - GL_ClipNodeToFrustum( node, &clipflags ) == qfalse ) - { + if( !GL_ClipNode( node, &clipflags ) ) { c.nodesCulled++; break; } if( !node->plane ) { - /* found a leaf */ - leaf = ( bspLeaf_t * )node; - if( leaf->contents == CONTENTS_SOLID ) { - break; - } - area = leaf->area; - if( !glr.fd.areabits || Q_IsBitSet( glr.fd.areabits, area ) ) { - leafFace = leaf->firstLeafFace; - count = leaf->numLeafFaces; - while( count-- ) { - face = *leafFace++; - face->drawframe = glr.drawframe; - } - } + GL_DrawLeaf( ( mleaf_t * )node ); break; } dot = PlaneDiffFast( modelViewOrigin, node->plane ); - side = ( dot < 0 ); + if( dot < 0 ) { + side = 1; + } else { + side = 0; + } GL_WorldNode_r( node->children[side], clipflags ); - face = node->firstFace; - count = node->numFaces; - while( count-- ) { - if( face->drawframe == glr.drawframe ) { - if( face->side == side ) { - GL_AddFace( face ); - } else { - c.facesCulled++; - } - } - face++; - } - - c.nodesDrawn++; + GL_DrawNode( node, dot ); node = node->children[ side ^ 1 ]; } - } void GL_DrawWorld( void ) { @@ -519,7 +462,8 @@ void GL_DrawWorld( void ) { VectorCopy( glr.fd.vieworg, modelViewOrigin ); - GL_WorldNode_r( r_world.nodes, NODE_CLIPPED ); + GL_WorldNode_r( gl_static.world.cache->nodes, + gl_cull_nodes->integer ? NODE_CLIPPED : NODE_UNCLIPPED ); GL_DrawSolidFaces(); |