Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

tr_scene.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 
00023 #include "tr_local.h"
00024 
00025 int         r_firstSceneDrawSurf;
00026 
00027 int         r_numdlights;
00028 int         r_firstSceneDlight;
00029 
00030 int         r_numentities;
00031 int         r_firstSceneEntity;
00032 
00033 int         r_numpolys;
00034 int         r_firstScenePoly;
00035 
00036 int         r_numpolyverts;
00037 
00038 
00039 /*
00040 ====================
00041 R_ToggleSmpFrame
00042 
00043 ====================
00044 */
00045 void R_ToggleSmpFrame( void ) {
00046     if ( r_smp->integer ) {
00047         // use the other buffers next frame, because another CPU
00048         // may still be rendering into the current ones
00049         tr.smpFrame ^= 1;
00050     } else {
00051         tr.smpFrame = 0;
00052     }
00053 
00054     backEndData[tr.smpFrame]->commands.used = 0;
00055 
00056     r_firstSceneDrawSurf = 0;
00057 
00058     r_numdlights = 0;
00059     r_firstSceneDlight = 0;
00060 
00061     r_numentities = 0;
00062     r_firstSceneEntity = 0;
00063 
00064     r_numpolys = 0;
00065     r_firstScenePoly = 0;
00066 
00067     r_numpolyverts = 0;
00068 }
00069 
00070 
00071 /*
00072 ====================
00073 RE_ClearScene
00074 
00075 ====================
00076 */
00077 void RE_ClearScene( void ) {
00078     r_firstSceneDlight = r_numdlights;
00079     r_firstSceneEntity = r_numentities;
00080     r_firstScenePoly = r_numpolys;
00081 }
00082 
00083 /*
00084 ===========================================================================
00085 
00086 DISCRETE POLYS
00087 
00088 ===========================================================================
00089 */
00090 
00091 /*
00092 =====================
00093 R_AddPolygonSurfaces
00094 
00095 Adds all the scene's polys into this view's drawsurf list
00096 =====================
00097 */
00098 void R_AddPolygonSurfaces( void ) {
00099     int         i;
00100     shader_t    *sh;
00101     srfPoly_t   *poly;
00102 
00103     tr.currentEntityNum = ENTITYNUM_WORLD;
00104     tr.shiftedEntityNum = tr.currentEntityNum << QSORT_ENTITYNUM_SHIFT;
00105 
00106     for ( i = 0, poly = tr.refdef.polys; i < tr.refdef.numPolys ; i++, poly++ ) {
00107         sh = R_GetShaderByHandle( poly->hShader );
00108         R_AddDrawSurf( ( void * )poly, sh, poly->fogIndex, qfalse );
00109     }
00110 }
00111 
00112 /*
00113 =====================
00114 RE_AddPolyToScene
00115 
00116 =====================
00117 */
00118 void RE_AddPolyToScene( qhandle_t hShader, int numVerts, const polyVert_t *verts, int numPolys ) {
00119     srfPoly_t   *poly;
00120     int         i, j;
00121     int         fogIndex;
00122     fog_t       *fog;
00123     vec3_t      bounds[2];
00124 
00125     if ( !tr.registered ) {
00126         return;
00127     }
00128 
00129     if ( !hShader ) {
00130         ri.Printf( PRINT_WARNING, "WARNING: RE_AddPolyToScene: NULL poly shader\n");
00131         return;
00132     }
00133 
00134     for ( j = 0; j < numPolys; j++ ) {
00135         if ( r_numpolyverts + numVerts > max_polyverts || r_numpolys >= max_polys ) {
00136       /*
00137       NOTE TTimo this was initially a PRINT_WARNING
00138       but it happens a lot with high fighting scenes and particles
00139       since we don't plan on changing the const and making for room for those effects
00140       simply cut this message to developer only
00141       */
00142             ri.Printf( PRINT_DEVELOPER, "WARNING: RE_AddPolyToScene: r_max_polys or r_max_polyverts reached\n");
00143             return;
00144         }
00145 
00146         poly = &backEndData[tr.smpFrame]->polys[r_numpolys];
00147         poly->surfaceType = SF_POLY;
00148         poly->hShader = hShader;
00149         poly->numVerts = numVerts;
00150         poly->verts = &backEndData[tr.smpFrame]->polyVerts[r_numpolyverts];
00151         
00152         Com_Memcpy( poly->verts, &verts[numVerts*j], numVerts * sizeof( *verts ) );
00153 
00154         if ( glConfig.hardwareType == GLHW_RAGEPRO ) {
00155             poly->verts->modulate[0] = 255;
00156             poly->verts->modulate[1] = 255;
00157             poly->verts->modulate[2] = 255;
00158             poly->verts->modulate[3] = 255;
00159         }
00160         // done.
00161         r_numpolys++;
00162         r_numpolyverts += numVerts;
00163 
00164         // if no world is loaded
00165         if ( tr.world == NULL ) {
00166             fogIndex = 0;
00167         }
00168         // see if it is in a fog volume
00169         else if ( tr.world->numfogs == 1 ) {
00170             fogIndex = 0;
00171         } else {
00172             // find which fog volume the poly is in
00173             VectorCopy( poly->verts[0].xyz, bounds[0] );
00174             VectorCopy( poly->verts[0].xyz, bounds[1] );
00175             for ( i = 1 ; i < poly->numVerts ; i++ ) {
00176                 AddPointToBounds( poly->verts[i].xyz, bounds[0], bounds[1] );
00177             }
00178             for ( fogIndex = 1 ; fogIndex < tr.world->numfogs ; fogIndex++ ) {
00179                 fog = &tr.world->fogs[fogIndex]; 
00180                 if ( bounds[1][0] >= fog->bounds[0][0]
00181                     && bounds[1][1] >= fog->bounds[0][1]
00182                     && bounds[1][2] >= fog->bounds[0][2]
00183                     && bounds[0][0] <= fog->bounds[1][0]
00184                     && bounds[0][1] <= fog->bounds[1][1]
00185                     && bounds[0][2] <= fog->bounds[1][2] ) {
00186                     break;
00187                 }
00188             }
00189             if ( fogIndex == tr.world->numfogs ) {
00190                 fogIndex = 0;
00191             }
00192         }
00193         poly->fogIndex = fogIndex;
00194     }
00195 }
00196 
00197 
00198 //=================================================================================
00199 
00200 
00201 /*
00202 =====================
00203 RE_AddRefEntityToScene
00204 
00205 =====================
00206 */
00207 void RE_AddRefEntityToScene( const refEntity_t *ent ) {
00208     if ( !tr.registered ) {
00209         return;
00210     }
00211   // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=402
00212     if ( r_numentities >= ENTITYNUM_WORLD ) {
00213         return;
00214     }
00215     if ( ent->reType < 0 || ent->reType >= RT_MAX_REF_ENTITY_TYPE ) {
00216         ri.Error( ERR_DROP, "RE_AddRefEntityToScene: bad reType %i", ent->reType );
00217     }
00218 
00219     backEndData[tr.smpFrame]->entities[r_numentities].e = *ent;
00220     backEndData[tr.smpFrame]->entities[r_numentities].lightingCalculated = qfalse;
00221 
00222     r_numentities++;
00223 }
00224 
00225 
00226 /*
00227 =====================
00228 RE_AddDynamicLightToScene
00229 
00230 =====================
00231 */
00232 void RE_AddDynamicLightToScene( const vec3_t org, float intensity, float r, float g, float b, int additive ) {
00233     dlight_t    *dl;
00234 
00235     if ( !tr.registered ) {
00236         return;
00237     }
00238     if ( r_numdlights >= MAX_DLIGHTS ) {
00239         return;
00240     }
00241     if ( intensity <= 0 ) {
00242         return;
00243     }
00244     // these cards don't have the correct blend mode
00245     if ( glConfig.hardwareType == GLHW_RIVA128 || glConfig.hardwareType == GLHW_PERMEDIA2 ) {
00246         return;
00247     }
00248     dl = &backEndData[tr.smpFrame]->dlights[r_numdlights++];
00249     VectorCopy (org, dl->origin);
00250     dl->radius = intensity;
00251     dl->color[0] = r;
00252     dl->color[1] = g;
00253     dl->color[2] = b;
00254     dl->additive = additive;
00255 }
00256 
00257 /*
00258 =====================
00259 RE_AddLightToScene
00260 
00261 =====================
00262 */
00263 void RE_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b ) {
00264     RE_AddDynamicLightToScene( org, intensity, r, g, b, qfalse );
00265 }
00266 
00267 /*
00268 =====================
00269 RE_AddAdditiveLightToScene
00270 
00271 =====================
00272 */
00273 void RE_AddAdditiveLightToScene( const vec3_t org, float intensity, float r, float g, float b ) {
00274     RE_AddDynamicLightToScene( org, intensity, r, g, b, qtrue );
00275 }
00276 
00277 /*
00278 @@@@@@@@@@@@@@@@@@@@@
00279 RE_RenderScene
00280 
00281 Draw a 3D view into a part of the window, then return
00282 to 2D drawing.
00283 
00284 Rendering a scene may require multiple views to be rendered
00285 to handle mirrors,
00286 @@@@@@@@@@@@@@@@@@@@@
00287 */
00288 void RE_RenderScene( const refdef_t *fd ) {
00289     viewParms_t     parms;
00290     int             startTime;
00291 
00292     if ( !tr.registered ) {
00293         return;
00294     }
00295     GLimp_LogComment( "====== RE_RenderScene =====\n" );
00296 
00297     if ( r_norefresh->integer ) {
00298         return;
00299     }
00300 
00301     startTime = ri.Milliseconds();
00302 
00303     if (!tr.world && !( fd->rdflags & RDF_NOWORLDMODEL ) ) {
00304         ri.Error (ERR_DROP, "R_RenderScene: NULL worldmodel");
00305     }
00306 
00307     Com_Memcpy( tr.refdef.text, fd->text, sizeof( tr.refdef.text ) );
00308 
00309     tr.refdef.x = fd->x;
00310     tr.refdef.y = fd->y;
00311     tr.refdef.width = fd->width;
00312     tr.refdef.height = fd->height;
00313     tr.refdef.fov_x = fd->fov_x;
00314     tr.refdef.fov_y = fd->fov_y;
00315 
00316     VectorCopy( fd->vieworg, tr.refdef.vieworg );
00317     VectorCopy( fd->viewaxis[0], tr.refdef.viewaxis[0] );
00318     VectorCopy( fd->viewaxis[1], tr.refdef.viewaxis[1] );
00319     VectorCopy( fd->viewaxis[2], tr.refdef.viewaxis[2] );
00320 
00321     tr.refdef.time = fd->time;
00322     tr.refdef.rdflags = fd->rdflags;
00323 
00324     // copy the areamask data over and note if it has changed, which
00325     // will force a reset of the visible leafs even if the view hasn't moved
00326     tr.refdef.areamaskModified = qfalse;
00327     if ( ! (tr.refdef.rdflags & RDF_NOWORLDMODEL) ) {
00328         int     areaDiff;
00329         int     i;
00330 
00331         // compare the area bits
00332         areaDiff = 0;
00333         for (i = 0 ; i < MAX_MAP_AREA_BYTES/4 ; i++) {
00334             areaDiff |= ((int *)tr.refdef.areamask)[i] ^ ((int *)fd->areamask)[i];
00335             ((int *)tr.refdef.areamask)[i] = ((int *)fd->areamask)[i];
00336         }
00337 
00338         if ( areaDiff ) {
00339             // a door just opened or something
00340             tr.refdef.areamaskModified = qtrue;
00341         }
00342     }
00343 
00344 
00345     // derived info
00346 
00347     tr.refdef.floatTime = tr.refdef.time * 0.001f;
00348 
00349     tr.refdef.numDrawSurfs = r_firstSceneDrawSurf;
00350     tr.refdef.drawSurfs = backEndData[tr.smpFrame]->drawSurfs;
00351 
00352     tr.refdef.num_entities = r_numentities - r_firstSceneEntity;
00353     tr.refdef.entities = &backEndData[tr.smpFrame]->entities[r_firstSceneEntity];
00354 
00355     tr.refdef.num_dlights = r_numdlights - r_firstSceneDlight;
00356     tr.refdef.dlights = &backEndData[tr.smpFrame]->dlights[r_firstSceneDlight];
00357 
00358     tr.refdef.numPolys = r_numpolys - r_firstScenePoly;
00359     tr.refdef.polys = &backEndData[tr.smpFrame]->polys[r_firstScenePoly];
00360 
00361     // turn off dynamic lighting globally by clearing all the
00362     // dlights if it needs to be disabled or if vertex lighting is enabled
00363     if ( r_dynamiclight->integer == 0 ||
00364          r_vertexLight->integer == 1 ||
00365          glConfig.hardwareType == GLHW_PERMEDIA2 ) {
00366         tr.refdef.num_dlights = 0;
00367     }
00368 
00369     // a single frame may have multiple scenes draw inside it --
00370     // a 3D game view, 3D status bar renderings, 3D menus, etc.
00371     // They need to be distinguished by the light flare code, because
00372     // the visibility state for a given surface may be different in
00373     // each scene / view.
00374     tr.frameSceneNum++;
00375     tr.sceneCount++;
00376 
00377     // setup view parms for the initial view
00378     //
00379     // set up viewport
00380     // The refdef takes 0-at-the-top y coordinates, so
00381     // convert to GL's 0-at-the-bottom space
00382     //
00383     Com_Memset( &parms, 0, sizeof( parms ) );
00384     parms.viewportX = tr.refdef.x;
00385     parms.viewportY = glConfig.vidHeight - ( tr.refdef.y + tr.refdef.height );
00386     parms.viewportWidth = tr.refdef.width;
00387     parms.viewportHeight = tr.refdef.height;
00388     parms.isPortal = qfalse;
00389 
00390     parms.fovX = tr.refdef.fov_x;
00391     parms.fovY = tr.refdef.fov_y;
00392 
00393     VectorCopy( fd->vieworg, parms.or.origin );
00394     VectorCopy( fd->viewaxis[0], parms.or.axis[0] );
00395     VectorCopy( fd->viewaxis[1], parms.or.axis[1] );
00396     VectorCopy( fd->viewaxis[2], parms.or.axis[2] );
00397 
00398     VectorCopy( fd->vieworg, parms.pvsOrigin );
00399 
00400     R_RenderView( &parms );
00401 
00402     // the next scene rendered in this frame will tack on after this one
00403     r_firstSceneDrawSurf = tr.refdef.numDrawSurfs;
00404     r_firstSceneEntity = r_numentities;
00405     r_firstSceneDlight = r_numdlights;
00406     r_firstScenePoly = r_numpolys;
00407 
00408     tr.frontEndMsec += ri.Milliseconds() - startTime;
00409 }

Generated on Thu Aug 25 12:37:53 2005 for Quake III Arena by  doxygen 1.3.9.1