1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423 |
- /*
- Copyright (C) 1997-2001 Id Software, Inc.
- 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.
- */
- // r_main.c
- #include "r_local.h"
- viddef_t vid;
- refimport_t ri;
- unsigned d_8to24table[256];
- entity_t r_worldentity;
- char skyname[MAX_QPATH];
- float skyrotate;
- vec3_t skyaxis;
- image_t *sky_images[6];
- refdef_t r_newrefdef;
- model_t *currentmodel;
- model_t *r_worldmodel;
- byte r_warpbuffer[WARP_WIDTH * WARP_HEIGHT];
- swstate_t sw_state;
- void *colormap;
- vec3_t viewlightvec;
- alight_t r_viewlighting = {128, 192, viewlightvec};
- float r_time1;
- int r_numallocatededges;
- float r_aliasuvscale = 1.0;
- int r_outofsurfaces;
- int r_outofedges;
- qboolean r_dowarp;
- mvertex_t *r_pcurrentvertbase;
- int c_surf;
- int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs;
- qboolean r_surfsonstack;
- int r_clipflags;
- //
- // view origin
- //
- vec3_t vup, base_vup;
- vec3_t vpn, base_vpn;
- vec3_t vright, base_vright;
- vec3_t r_origin;
- //
- // screen size info
- //
- oldrefdef_t r_refdef;
- float xcenter, ycenter;
- float xscale, yscale;
- float xscaleinv, yscaleinv;
- float xscaleshrink, yscaleshrink;
- float aliasxscale, aliasyscale, aliasxcenter, aliasycenter;
- int r_screenwidth;
- float verticalFieldOfView;
- float xOrigin, yOrigin;
- mplane_t screenedge[4];
- //
- // refresh flags
- //
- int r_framecount = 1; // so frame counts initialized to 0 don't match
- int r_visframecount;
- int d_spanpixcount;
- int r_polycount;
- int r_drawnpolycount;
- int r_wholepolycount;
- int *pfrustum_indexes[4];
- int r_frustum_indexes[4*6];
- mleaf_t *r_viewleaf;
- int r_viewcluster, r_oldviewcluster;
- image_t *r_notexture_mip;
- float da_time1, da_time2, dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2;
- float se_time1, se_time2, de_time1, de_time2;
- void R_MarkLeaves (void);
- cvar_t *r_lefthand;
- cvar_t *sw_aliasstats;
- cvar_t *sw_allow_modex;
- cvar_t *sw_clearcolor;
- cvar_t *sw_drawflat;
- cvar_t *sw_draworder;
- cvar_t *sw_maxedges;
- cvar_t *sw_maxsurfs;
- cvar_t *sw_mode;
- cvar_t *sw_reportedgeout;
- cvar_t *sw_reportsurfout;
- cvar_t *sw_stipplealpha;
- cvar_t *sw_surfcacheoverride;
- cvar_t *sw_waterwarp;
- cvar_t *r_drawworld;
- cvar_t *r_drawentities;
- cvar_t *r_dspeeds;
- cvar_t *r_fullbright;
- cvar_t *r_lerpmodels;
- cvar_t *r_novis;
- cvar_t *r_speeds;
- cvar_t *r_lightlevel; //FIXME HACK
- cvar_t *vid_fullscreen;
- cvar_t *vid_gamma;
- //PGM
- cvar_t *sw_lockpvs;
- //PGM
- #define STRINGER(x) "x"
- #if !id386
- // r_vars.c
- // all global and static refresh variables are collected in a contiguous block
- // to avoid cache conflicts.
- //-------------------------------------------------------
- // global refresh variables
- //-------------------------------------------------------
- // FIXME: make into one big structure, like cl or sv
- // FIXME: do separately for refresh engine and driver
- // d_vars.c
- // all global and static refresh variables are collected in a contiguous block
- // to avoid cache conflicts.
- //-------------------------------------------------------
- // global refresh variables
- //-------------------------------------------------------
- // FIXME: make into one big structure, like cl or sv
- // FIXME: do separately for refresh engine and driver
- float d_sdivzstepu, d_tdivzstepu, d_zistepu;
- float d_sdivzstepv, d_tdivzstepv, d_zistepv;
- float d_sdivzorigin, d_tdivzorigin, d_ziorigin;
- fixed16_t sadjust, tadjust, bbextents, bbextentt;
- pixel_t *cacheblock;
- int cachewidth;
- pixel_t *d_viewbuffer;
- short *d_pzbuffer;
- unsigned int d_zrowbytes;
- unsigned int d_zwidth;
- #endif // !id386
- byte r_notexture_buffer[1024];
- /*
- ==================
- R_InitTextures
- ==================
- */
- void R_InitTextures (void)
- {
- int x,y, m;
- byte *dest;
-
- // create a simple checkerboard texture for the default
- r_notexture_mip = (image_t *)&r_notexture_buffer;
-
- r_notexture_mip->width = r_notexture_mip->height = 16;
- r_notexture_mip->pixels[0] = &r_notexture_buffer[sizeof(image_t)];
- r_notexture_mip->pixels[1] = r_notexture_mip->pixels[0] + 16*16;
- r_notexture_mip->pixels[2] = r_notexture_mip->pixels[1] + 8*8;
- r_notexture_mip->pixels[3] = r_notexture_mip->pixels[2] + 4*4;
-
- for (m=0 ; m<4 ; m++)
- {
- dest = r_notexture_mip->pixels[m];
- for (y=0 ; y< (16>>m) ; y++)
- for (x=0 ; x< (16>>m) ; x++)
- {
- if ( (y< (8>>m) ) ^ (x< (8>>m) ) )
- *dest++ = 0;
- else
- *dest++ = 0xff;
- }
- }
- }
- /*
- ================
- R_InitTurb
- ================
- */
- void R_InitTurb (void)
- {
- int i;
-
- for (i=0 ; i<1280 ; i++)
- {
- sintable[i] = AMP + sin(i*3.14159*2/CYCLE)*AMP;
- intsintable[i] = AMP2 + sin(i*3.14159*2/CYCLE)*AMP2; // AMP2, not 20
- blanktable[i] = 0; //PGM
- }
- }
- void R_ImageList_f( void );
- void R_Register (void)
- {
- sw_aliasstats = ri.Cvar_Get ("sw_polymodelstats", "0", 0);
- sw_allow_modex = ri.Cvar_Get( "sw_allow_modex", "1", CVAR_ARCHIVE );
- sw_clearcolor = ri.Cvar_Get ("sw_clearcolor", "2", 0);
- sw_drawflat = ri.Cvar_Get ("sw_drawflat", "0", 0);
- sw_draworder = ri.Cvar_Get ("sw_draworder", "0", 0);
- sw_maxedges = ri.Cvar_Get ("sw_maxedges", STRINGER(MAXSTACKSURFACES), 0);
- sw_maxsurfs = ri.Cvar_Get ("sw_maxsurfs", "0", 0);
- sw_mipcap = ri.Cvar_Get ("sw_mipcap", "0", 0);
- sw_mipscale = ri.Cvar_Get ("sw_mipscale", "1", 0);
- sw_reportedgeout = ri.Cvar_Get ("sw_reportedgeout", "0", 0);
- sw_reportsurfout = ri.Cvar_Get ("sw_reportsurfout", "0", 0);
- sw_stipplealpha = ri.Cvar_Get( "sw_stipplealpha", "0", CVAR_ARCHIVE );
- sw_surfcacheoverride = ri.Cvar_Get ("sw_surfcacheoverride", "0", 0);
- sw_waterwarp = ri.Cvar_Get ("sw_waterwarp", "1", 0);
- sw_mode = ri.Cvar_Get( "sw_mode", "0", CVAR_ARCHIVE );
- r_lefthand = ri.Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE );
- r_speeds = ri.Cvar_Get ("r_speeds", "0", 0);
- r_fullbright = ri.Cvar_Get ("r_fullbright", "0", 0);
- r_drawentities = ri.Cvar_Get ("r_drawentities", "1", 0);
- r_drawworld = ri.Cvar_Get ("r_drawworld", "1", 0);
- r_dspeeds = ri.Cvar_Get ("r_dspeeds", "0", 0);
- r_lightlevel = ri.Cvar_Get ("r_lightlevel", "0", 0);
- r_lerpmodels = ri.Cvar_Get( "r_lerpmodels", "1", 0 );
- r_novis = ri.Cvar_Get( "r_novis", "0", 0 );
- vid_fullscreen = ri.Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE );
- vid_gamma = ri.Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE );
- ri.Cmd_AddCommand ("modellist", Mod_Modellist_f);
- ri.Cmd_AddCommand( "screenshot", R_ScreenShot_f );
- ri.Cmd_AddCommand( "imagelist", R_ImageList_f );
- sw_mode->modified = true; // force us to do mode specific stuff later
- vid_gamma->modified = true; // force us to rebuild the gamma table later
- //PGM
- sw_lockpvs = ri.Cvar_Get ("sw_lockpvs", "0", 0);
- //PGM
- }
- void R_UnRegister (void)
- {
- ri.Cmd_RemoveCommand( "screenshot" );
- ri.Cmd_RemoveCommand ("modellist");
- ri.Cmd_RemoveCommand( "imagelist" );
- }
- /*
- ===============
- R_Init
- ===============
- */
- qboolean R_Init( void *hInstance, void *wndProc )
- {
- R_InitImages ();
- Mod_Init ();
- Draw_InitLocal ();
- R_InitTextures ();
- R_InitTurb ();
- view_clipplanes[0].leftedge = true;
- view_clipplanes[1].rightedge = true;
- view_clipplanes[1].leftedge = view_clipplanes[2].leftedge =
- view_clipplanes[3].leftedge = false;
- view_clipplanes[0].rightedge = view_clipplanes[2].rightedge =
- view_clipplanes[3].rightedge = false;
- r_refdef.xOrigin = XCENTERING;
- r_refdef.yOrigin = YCENTERING;
- // TODO: collect 386-specific code in one place
- #if id386
- Sys_MakeCodeWriteable ((long)R_EdgeCodeStart,
- (long)R_EdgeCodeEnd - (long)R_EdgeCodeStart);
- Sys_SetFPCW (); // get bit masks for FPCW (FIXME: is this id386?)
- #endif // id386
- r_aliasuvscale = 1.0;
- R_Register ();
- Draw_GetPalette ();
- SWimp_Init( hInstance, wndProc );
- // create the window
- R_BeginFrame( 0 );
- ri.Con_Printf (PRINT_ALL, "ref_soft version: "REF_VERSION"\n");
- return true;
- }
- /*
- ===============
- R_Shutdown
- ===============
- */
- void R_Shutdown (void)
- {
- // free z buffer
- if (d_pzbuffer)
- {
- free (d_pzbuffer);
- d_pzbuffer = NULL;
- }
- // free surface cache
- if (sc_base)
- {
- D_FlushCaches ();
- free (sc_base);
- sc_base = NULL;
- }
- // free colormap
- if (vid.colormap)
- {
- free (vid.colormap);
- vid.colormap = NULL;
- }
- R_UnRegister ();
- Mod_FreeAll ();
- R_ShutdownImages ();
- SWimp_Shutdown();
- }
- /*
- ===============
- R_NewMap
- ===============
- */
- void R_NewMap (void)
- {
- r_viewcluster = -1;
- r_cnumsurfs = sw_maxsurfs->value;
- if (r_cnumsurfs <= MINSURFACES)
- r_cnumsurfs = MINSURFACES;
- if (r_cnumsurfs > NUMSTACKSURFACES)
- {
- surfaces = malloc (r_cnumsurfs * sizeof(surf_t));
- surface_p = surfaces;
- surf_max = &surfaces[r_cnumsurfs];
- r_surfsonstack = false;
- // surface 0 doesn't really exist; it's just a dummy because index 0
- // is used to indicate no edge attached to surface
- surfaces--;
- R_SurfacePatch ();
- }
- else
- {
- r_surfsonstack = true;
- }
- r_maxedgesseen = 0;
- r_maxsurfsseen = 0;
- r_numallocatededges = sw_maxedges->value;
- if (r_numallocatededges < MINEDGES)
- r_numallocatededges = MINEDGES;
- if (r_numallocatededges <= NUMSTACKEDGES)
- {
- auxedges = NULL;
- }
- else
- {
- auxedges = malloc (r_numallocatededges * sizeof(edge_t));
- }
- }
- /*
- ===============
- R_MarkLeaves
- Mark the leaves and nodes that are in the PVS for the current
- cluster
- ===============
- */
- void R_MarkLeaves (void)
- {
- byte *vis;
- mnode_t *node;
- int i;
- mleaf_t *leaf;
- int cluster;
- if (r_oldviewcluster == r_viewcluster && !r_novis->value && r_viewcluster != -1)
- return;
-
- // development aid to let you run around and see exactly where
- // the pvs ends
- if (sw_lockpvs->value)
- return;
- r_visframecount++;
- r_oldviewcluster = r_viewcluster;
- if (r_novis->value || r_viewcluster == -1 || !r_worldmodel->vis)
- {
- // mark everything
- for (i=0 ; i<r_worldmodel->numleafs ; i++)
- r_worldmodel->leafs[i].visframe = r_visframecount;
- for (i=0 ; i<r_worldmodel->numnodes ; i++)
- r_worldmodel->nodes[i].visframe = r_visframecount;
- return;
- }
- vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel);
-
- for (i=0,leaf=r_worldmodel->leafs ; i<r_worldmodel->numleafs ; i++, leaf++)
- {
- cluster = leaf->cluster;
- if (cluster == -1)
- continue;
- if (vis[cluster>>3] & (1<<(cluster&7)))
- {
- node = (mnode_t *)leaf;
- do
- {
- if (node->visframe == r_visframecount)
- break;
- node->visframe = r_visframecount;
- node = node->parent;
- } while (node);
- }
- }
- #if 0
- for (i=0 ; i<r_worldmodel->vis->numclusters ; i++)
- {
- if (vis[i>>3] & (1<<(i&7)))
- {
- node = (mnode_t *)&r_worldmodel->leafs[i]; // FIXME: cluster
- do
- {
- if (node->visframe == r_visframecount)
- break;
- node->visframe = r_visframecount;
- node = node->parent;
- } while (node);
- }
- }
- #endif
- }
- /*
- ** R_DrawNullModel
- **
- ** IMPLEMENT THIS!
- */
- void R_DrawNullModel( void )
- {
- }
- /*
- =============
- R_DrawEntitiesOnList
- =============
- */
- void R_DrawEntitiesOnList (void)
- {
- int i;
- qboolean translucent_entities = false;
- if (!r_drawentities->value)
- return;
- // all bmodels have already been drawn by the edge list
- for (i=0 ; i<r_newrefdef.num_entities ; i++)
- {
- currententity = &r_newrefdef.entities[i];
- if ( currententity->flags & RF_TRANSLUCENT )
- {
- translucent_entities = true;
- continue;
- }
- if ( currententity->flags & RF_BEAM )
- {
- modelorg[0] = -r_origin[0];
- modelorg[1] = -r_origin[1];
- modelorg[2] = -r_origin[2];
- VectorCopy( vec3_origin, r_entorigin );
- R_DrawBeam( currententity );
- }
- else
- {
- currentmodel = currententity->model;
- if (!currentmodel)
- {
- R_DrawNullModel();
- continue;
- }
- VectorCopy (currententity->origin, r_entorigin);
- VectorSubtract (r_origin, r_entorigin, modelorg);
- switch (currentmodel->type)
- {
- case mod_sprite:
- R_DrawSprite ();
- break;
- case mod_alias:
- R_AliasDrawModel ();
- break;
- default:
- break;
- }
- }
- }
- if ( !translucent_entities )
- return;
- for (i=0 ; i<r_newrefdef.num_entities ; i++)
- {
- currententity = &r_newrefdef.entities[i];
- if ( !( currententity->flags & RF_TRANSLUCENT ) )
- continue;
- if ( currententity->flags & RF_BEAM )
- {
- modelorg[0] = -r_origin[0];
- modelorg[1] = -r_origin[1];
- modelorg[2] = -r_origin[2];
- VectorCopy( vec3_origin, r_entorigin );
- R_DrawBeam( currententity );
- }
- else
- {
- currentmodel = currententity->model;
- if (!currentmodel)
- {
- R_DrawNullModel();
- continue;
- }
- VectorCopy (currententity->origin, r_entorigin);
- VectorSubtract (r_origin, r_entorigin, modelorg);
- switch (currentmodel->type)
- {
- case mod_sprite:
- R_DrawSprite ();
- break;
- case mod_alias:
- R_AliasDrawModel ();
- break;
- default:
- break;
- }
- }
- }
- }
- /*
- =============
- R_BmodelCheckBBox
- =============
- */
- int R_BmodelCheckBBox (float *minmaxs)
- {
- int i, *pindex, clipflags;
- vec3_t acceptpt, rejectpt;
- float d;
- clipflags = 0;
- for (i=0 ; i<4 ; i++)
- {
- // generate accept and reject points
- // FIXME: do with fast look-ups or integer tests based on the sign bit
- // of the floating point values
- pindex = pfrustum_indexes[i];
- rejectpt[0] = minmaxs[pindex[0]];
- rejectpt[1] = minmaxs[pindex[1]];
- rejectpt[2] = minmaxs[pindex[2]];
-
- d = DotProduct (rejectpt, view_clipplanes[i].normal);
- d -= view_clipplanes[i].dist;
- if (d <= 0)
- return BMODEL_FULLY_CLIPPED;
- acceptpt[0] = minmaxs[pindex[3+0]];
- acceptpt[1] = minmaxs[pindex[3+1]];
- acceptpt[2] = minmaxs[pindex[3+2]];
- d = DotProduct (acceptpt, view_clipplanes[i].normal);
- d -= view_clipplanes[i].dist;
- if (d <= 0)
- clipflags |= (1<<i);
- }
- return clipflags;
- }
- /*
- ===================
- R_FindTopnode
- Find the first node that splits the given box
- ===================
- */
- mnode_t *R_FindTopnode (vec3_t mins, vec3_t maxs)
- {
- mplane_t *splitplane;
- int sides;
- mnode_t *node;
- node = r_worldmodel->nodes;
- while (1)
- {
- if (node->visframe != r_visframecount)
- return NULL; // not visible at all
-
- if (node->contents != CONTENTS_NODE)
- {
- if (node->contents != CONTENTS_SOLID)
- return node; // we've reached a non-solid leaf, so it's
- // visible and not BSP clipped
- return NULL; // in solid, so not visible
- }
-
- splitplane = node->plane;
- sides = BOX_ON_PLANE_SIDE(mins, maxs, (cplane_t *)splitplane);
-
- if (sides == 3)
- return node; // this is the splitter
-
- // not split yet; recurse down the contacted side
- if (sides & 1)
- node = node->children[0];
- else
- node = node->children[1];
- }
- }
- /*
- =============
- RotatedBBox
- Returns an axially aligned box that contains the input box at the given rotation
- =============
- */
- void RotatedBBox (vec3_t mins, vec3_t maxs, vec3_t angles, vec3_t tmins, vec3_t tmaxs)
- {
- vec3_t tmp, v;
- int i, j;
- vec3_t forward, right, up;
- if (!angles[0] && !angles[1] && !angles[2])
- {
- VectorCopy (mins, tmins);
- VectorCopy (maxs, tmaxs);
- return;
- }
- for (i=0 ; i<3 ; i++)
- {
- tmins[i] = 99999;
- tmaxs[i] = -99999;
- }
- AngleVectors (angles, forward, right, up);
- for ( i = 0; i < 8; i++ )
- {
- if ( i & 1 )
- tmp[0] = mins[0];
- else
- tmp[0] = maxs[0];
- if ( i & 2 )
- tmp[1] = mins[1];
- else
- tmp[1] = maxs[1];
- if ( i & 4 )
- tmp[2] = mins[2];
- else
- tmp[2] = maxs[2];
- VectorScale (forward, tmp[0], v);
- VectorMA (v, -tmp[1], right, v);
- VectorMA (v, tmp[2], up, v);
- for (j=0 ; j<3 ; j++)
- {
- if (v[j] < tmins[j])
- tmins[j] = v[j];
- if (v[j] > tmaxs[j])
- tmaxs[j] = v[j];
- }
- }
- }
- /*
- =============
- R_DrawBEntitiesOnList
- =============
- */
- void R_DrawBEntitiesOnList (void)
- {
- int i, clipflags;
- vec3_t oldorigin;
- vec3_t mins, maxs;
- float minmaxs[6];
- mnode_t *topnode;
- if (!r_drawentities->value)
- return;
- VectorCopy (modelorg, oldorigin);
- insubmodel = true;
- r_dlightframecount = r_framecount;
- for (i=0 ; i<r_newrefdef.num_entities ; i++)
- {
- currententity = &r_newrefdef.entities[i];
- currentmodel = currententity->model;
- if (!currentmodel)
- continue;
- if (currentmodel->nummodelsurfaces == 0)
- continue; // clip brush only
- if ( currententity->flags & RF_BEAM )
- continue;
- if (currentmodel->type != mod_brush)
- continue;
- // see if the bounding box lets us trivially reject, also sets
- // trivial accept status
- RotatedBBox (currentmodel->mins, currentmodel->maxs,
- currententity->angles, mins, maxs);
- VectorAdd (mins, currententity->origin, minmaxs);
- VectorAdd (maxs, currententity->origin, (minmaxs+3));
- clipflags = R_BmodelCheckBBox (minmaxs);
- if (clipflags == BMODEL_FULLY_CLIPPED)
- continue; // off the edge of the screen
- topnode = R_FindTopnode (minmaxs, minmaxs+3);
- if (!topnode)
- continue; // no part in a visible leaf
- VectorCopy (currententity->origin, r_entorigin);
- VectorSubtract (r_origin, r_entorigin, modelorg);
- r_pcurrentvertbase = currentmodel->vertexes;
- // FIXME: stop transforming twice
- R_RotateBmodel ();
- // calculate dynamic lighting for bmodel
- R_PushDlights (currentmodel);
- if (topnode->contents == CONTENTS_NODE)
- {
- // not a leaf; has to be clipped to the world BSP
- r_clipflags = clipflags;
- R_DrawSolidClippedSubmodelPolygons (currentmodel, topnode);
- }
- else
- {
- // falls entirely in one leaf, so we just put all the
- // edges in the edge list and let 1/z sorting handle
- // drawing order
- R_DrawSubmodelPolygons (currentmodel, clipflags, topnode);
- }
- // put back world rotation and frustum clipping
- // FIXME: R_RotateBmodel should just work off base_vxx
- VectorCopy (base_vpn, vpn);
- VectorCopy (base_vup, vup);
- VectorCopy (base_vright, vright);
- VectorCopy (oldorigin, modelorg);
- R_TransformFrustum ();
- }
- insubmodel = false;
- }
- /*
- ================
- R_EdgeDrawing
- ================
- */
- void R_EdgeDrawing (void)
- {
- edge_t ledges[NUMSTACKEDGES +
- ((CACHE_SIZE - 1) / sizeof(edge_t)) + 1];
- surf_t lsurfs[NUMSTACKSURFACES +
- ((CACHE_SIZE - 1) / sizeof(surf_t)) + 1];
- if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
- return;
- if (auxedges)
- {
- r_edges = auxedges;
- }
- else
- {
- r_edges = (edge_t *)
- (((long)&ledges[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
- }
- if (r_surfsonstack)
- {
- surfaces = (surf_t *)
- (((long)&lsurfs[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
- surf_max = &surfaces[r_cnumsurfs];
- // surface 0 doesn't really exist; it's just a dummy because index 0
- // is used to indicate no edge attached to surface
- surfaces--;
- R_SurfacePatch ();
- }
- R_BeginEdgeFrame ();
- if (r_dspeeds->value)
- {
- rw_time1 = Sys_Milliseconds ();
- }
- R_RenderWorld ();
- if (r_dspeeds->value)
- {
- rw_time2 = Sys_Milliseconds ();
- db_time1 = rw_time2;
- }
- R_DrawBEntitiesOnList ();
- if (r_dspeeds->value)
- {
- db_time2 = Sys_Milliseconds ();
- se_time1 = db_time2;
- }
- R_ScanEdges ();
- }
- //=======================================================================
- /*
- =============
- R_CalcPalette
- =============
- */
- void R_CalcPalette (void)
- {
- static qboolean modified;
- byte palette[256][4], *in, *out;
- int i, j;
- float alpha, one_minus_alpha;
- vec3_t premult;
- int v;
- alpha = r_newrefdef.blend[3];
- if (alpha <= 0)
- {
- if (modified)
- { // set back to default
- modified = false;
- R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
- return;
- }
- return;
- }
- modified = true;
- if (alpha > 1)
- alpha = 1;
- premult[0] = r_newrefdef.blend[0]*alpha*255;
- premult[1] = r_newrefdef.blend[1]*alpha*255;
- premult[2] = r_newrefdef.blend[2]*alpha*255;
- one_minus_alpha = (1.0 - alpha);
- in = (byte *)d_8to24table;
- out = palette[0];
- for (i=0 ; i<256 ; i++, in+=4, out+=4)
- {
- for (j=0 ; j<3 ; j++)
- {
- v = premult[j] + one_minus_alpha * in[j];
- if (v > 255)
- v = 255;
- out[j] = v;
- }
- out[3] = 255;
- }
- R_GammaCorrectAndSetPalette( ( const unsigned char * ) palette[0] );
- // SWimp_SetPalette( palette[0] );
- }
- //=======================================================================
- void R_SetLightLevel (void)
- {
- vec3_t light;
- if ((r_newrefdef.rdflags & RDF_NOWORLDMODEL) || (!r_drawentities->value) || (!currententity))
- {
- r_lightlevel->value = 150.0;
- return;
- }
- // save off light value for server to look at (BIG HACK!)
- R_LightPoint (r_newrefdef.vieworg, light);
- r_lightlevel->value = 150.0 * light[0];
- }
- /*
- @@@@@@@@@@@@@@@@
- R_RenderFrame
- @@@@@@@@@@@@@@@@
- */
- void R_RenderFrame (refdef_t *fd)
- {
- r_newrefdef = *fd;
- if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
- ri.Sys_Error (ERR_FATAL,"R_RenderView: NULL worldmodel");
- VectorCopy (fd->vieworg, r_refdef.vieworg);
- VectorCopy (fd->viewangles, r_refdef.viewangles);
- if (r_speeds->value || r_dspeeds->value)
- r_time1 = Sys_Milliseconds ();
- R_SetupFrame ();
- R_MarkLeaves (); // done here so we know if we're in water
- R_PushDlights (r_worldmodel);
- R_EdgeDrawing ();
- if (r_dspeeds->value)
- {
- se_time2 = Sys_Milliseconds ();
- de_time1 = se_time2;
- }
- R_DrawEntitiesOnList ();
- if (r_dspeeds->value)
- {
- de_time2 = Sys_Milliseconds ();
- dp_time1 = Sys_Milliseconds ();
- }
- R_DrawParticles ();
- if (r_dspeeds->value)
- dp_time2 = Sys_Milliseconds ();
- R_DrawAlphaSurfaces();
- R_SetLightLevel ();
- if (r_dowarp)
- D_WarpScreen ();
- if (r_dspeeds->value)
- da_time1 = Sys_Milliseconds ();
- if (r_dspeeds->value)
- da_time2 = Sys_Milliseconds ();
- R_CalcPalette ();
- if (sw_aliasstats->value)
- R_PrintAliasStats ();
-
- if (r_speeds->value)
- R_PrintTimes ();
- if (r_dspeeds->value)
- R_PrintDSpeeds ();
- if (sw_reportsurfout->value && r_outofsurfaces)
- ri.Con_Printf (PRINT_ALL,"Short %d surfaces\n", r_outofsurfaces);
- if (sw_reportedgeout->value && r_outofedges)
- ri.Con_Printf (PRINT_ALL,"Short roughly %d edges\n", r_outofedges * 2 / 3);
- }
- /*
- ** R_InitGraphics
- */
- void R_InitGraphics( int width, int height )
- {
- vid.width = width;
- vid.height = height;
- // free z buffer
- if ( d_pzbuffer )
- {
- free( d_pzbuffer );
- d_pzbuffer = NULL;
- }
- // free surface cache
- if ( sc_base )
- {
- D_FlushCaches ();
- free( sc_base );
- sc_base = NULL;
- }
- d_pzbuffer = malloc(vid.width*vid.height*2);
- R_InitCaches ();
- R_GammaCorrectAndSetPalette( ( const unsigned char *) d_8to24table );
- }
- /*
- ** R_BeginFrame
- */
- void R_BeginFrame( float camera_separation )
- {
- extern void Draw_BuildGammaTable( void );
- /*
- ** rebuild the gamma correction palette if necessary
- */
- if ( vid_gamma->modified )
- {
- Draw_BuildGammaTable();
- R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
- vid_gamma->modified = false;
- }
- while ( sw_mode->modified || vid_fullscreen->modified )
- {
- rserr_t err;
- /*
- ** if this returns rserr_invalid_fullscreen then it set the mode but not as a
- ** fullscreen mode, e.g. 320x200 on a system that doesn't support that res
- */
- if ( ( err = SWimp_SetMode( &vid.width, &vid.height, sw_mode->value, vid_fullscreen->value ) ) == rserr_ok )
- {
- R_InitGraphics( vid.width, vid.height );
- sw_state.prev_mode = sw_mode->value;
- vid_fullscreen->modified = false;
- sw_mode->modified = false;
- }
- else
- {
- if ( err == rserr_invalid_mode )
- {
- ri.Cvar_SetValue( "sw_mode", sw_state.prev_mode );
- ri.Con_Printf( PRINT_ALL, "ref_soft::R_BeginFrame() - could not set mode\n" );
- }
- else if ( err == rserr_invalid_fullscreen )
- {
- R_InitGraphics( vid.width, vid.height );
- ri.Cvar_SetValue( "vid_fullscreen", 0);
- ri.Con_Printf( PRINT_ALL, "ref_soft::R_BeginFrame() - fullscreen unavailable in this mode\n" );
- sw_state.prev_mode = sw_mode->value;
- // vid_fullscreen->modified = false;
- // sw_mode->modified = false;
- }
- else
- {
- ri.Sys_Error( ERR_FATAL, "ref_soft::R_BeginFrame() - catastrophic mode change failure\n" );
- }
- }
- }
- }
- /*
- ** R_GammaCorrectAndSetPalette
- */
- void R_GammaCorrectAndSetPalette( const unsigned char *palette )
- {
- int i;
- for ( i = 0; i < 256; i++ )
- {
- sw_state.currentpalette[i*4+0] = sw_state.gammatable[palette[i*4+0]];
- sw_state.currentpalette[i*4+1] = sw_state.gammatable[palette[i*4+1]];
- sw_state.currentpalette[i*4+2] = sw_state.gammatable[palette[i*4+2]];
- }
- SWimp_SetPalette( sw_state.currentpalette );
- }
- /*
- ** R_CinematicSetPalette
- */
- void R_CinematicSetPalette( const unsigned char *palette )
- {
- byte palette32[1024];
- int i, j, w;
- int *d;
- // clear screen to black to avoid any palette flash
- w = abs(vid.rowbytes)>>2; // stupid negative pitch win32 stuff...
- for (i=0 ; i<vid.height ; i++, d+=w)
- {
- d = (int *)(vid.buffer + i*vid.rowbytes);
- for (j=0 ; j<w ; j++)
- d[j] = 0;
- }
- // flush it to the screen
- SWimp_EndFrame ();
- if ( palette )
- {
- for ( i = 0; i < 256; i++ )
- {
- palette32[i*4+0] = palette[i*3+0];
- palette32[i*4+1] = palette[i*3+1];
- palette32[i*4+2] = palette[i*3+2];
- palette32[i*4+3] = 0xFF;
- }
- R_GammaCorrectAndSetPalette( palette32 );
- }
- else
- {
- R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
- }
- }
- /*
- ================
- Draw_BuildGammaTable
- ================
- */
- void Draw_BuildGammaTable (void)
- {
- int i, inf;
- float g;
- g = vid_gamma->value;
- if (g == 1.0)
- {
- for (i=0 ; i<256 ; i++)
- sw_state.gammatable[i] = i;
- return;
- }
-
- for (i=0 ; i<256 ; i++)
- {
- inf = 255 * pow ( (i+0.5)/255.5 , g ) + 0.5;
- if (inf < 0)
- inf = 0;
- if (inf > 255)
- inf = 255;
- sw_state.gammatable[i] = inf;
- }
- }
- /*
- ** R_DrawBeam
- */
- void R_DrawBeam( entity_t *e )
- {
- #define NUM_BEAM_SEGS 6
- int i;
- vec3_t perpvec;
- vec3_t direction, normalized_direction;
- vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS];
- vec3_t oldorigin, origin;
- oldorigin[0] = e->oldorigin[0];
- oldorigin[1] = e->oldorigin[1];
- oldorigin[2] = e->oldorigin[2];
- origin[0] = e->origin[0];
- origin[1] = e->origin[1];
- origin[2] = e->origin[2];
- normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
- normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
- normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
- if ( VectorNormalize( normalized_direction ) == 0 )
- return;
- PerpendicularVector( perpvec, normalized_direction );
- VectorScale( perpvec, e->frame / 2, perpvec );
- for ( i = 0; i < NUM_BEAM_SEGS; i++ )
- {
- RotatePointAroundVector( start_points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i );
- VectorAdd( start_points[i], origin, start_points[i] );
- VectorAdd( start_points[i], direction, end_points[i] );
- }
- for ( i = 0; i < NUM_BEAM_SEGS; i++ )
- {
- R_IMFlatShadedQuad( start_points[i],
- end_points[i],
- end_points[(i+1)%NUM_BEAM_SEGS],
- start_points[(i+1)%NUM_BEAM_SEGS],
- e->skinnum & 0xFF,
- e->alpha );
- }
- }
- //===================================================================
- /*
- ============
- R_SetSky
- ============
- */
- // 3dstudio environment map names
- char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
- int r_skysideimage[6] = {5, 2, 4, 1, 0, 3};
- extern mtexinfo_t r_skytexinfo[6];
- void R_SetSky (char *name, float rotate, vec3_t axis)
- {
- int i;
- char pathname[MAX_QPATH];
- strncpy (skyname, name, sizeof(skyname)-1);
- skyrotate = rotate;
- VectorCopy (axis, skyaxis);
- for (i=0 ; i<6 ; i++)
- {
- Com_sprintf (pathname, sizeof(pathname), "env/%s%s.pcx", skyname, suf[r_skysideimage[i]]);
- r_skytexinfo[i].image = R_FindImage (pathname, it_sky);
- }
- }
- /*
- ===============
- Draw_GetPalette
- ===============
- */
- void Draw_GetPalette (void)
- {
- byte *pal, *out;
- int i;
- int r, g, b;
- // get the palette and colormap
- LoadPCX ("pics/colormap.pcx", &vid.colormap, &pal, NULL, NULL);
- if (!vid.colormap)
- ri.Sys_Error (ERR_FATAL, "Couldn't load pics/colormap.pcx");
- vid.alphamap = vid.colormap + 64*256;
- out = (byte *)d_8to24table;
- for (i=0 ; i<256 ; i++, out+=4)
- {
- r = pal[i*3+0];
- g = pal[i*3+1];
- b = pal[i*3+2];
- out[0] = r;
- out[1] = g;
- out[2] = b;
- }
- free (pal);
- }
- struct image_s *R_RegisterSkin (char *name);
- /*
- @@@@@@@@@@@@@@@@@@@@@
- GetRefAPI
- @@@@@@@@@@@@@@@@@@@@@
- */
- refexport_t GetRefAPI (refimport_t rimp)
- {
- refexport_t re;
- ri = rimp;
- re.api_version = API_VERSION;
- re.BeginRegistration = R_BeginRegistration;
- re.RegisterModel = R_RegisterModel;
- re.RegisterSkin = R_RegisterSkin;
- re.RegisterPic = Draw_FindPic;
- re.SetSky = R_SetSky;
- re.EndRegistration = R_EndRegistration;
- re.RenderFrame = R_RenderFrame;
- re.DrawGetPicSize = Draw_GetPicSize;
- re.DrawPic = Draw_Pic;
- re.DrawStretchPic = Draw_StretchPic;
- re.DrawChar = Draw_Char;
- re.DrawTileClear = Draw_TileClear;
- re.DrawFill = Draw_Fill;
- re.DrawFadeScreen= Draw_FadeScreen;
- re.DrawStretchRaw = Draw_StretchRaw;
- re.Init = R_Init;
- re.Shutdown = R_Shutdown;
- re.CinematicSetPalette = R_CinematicSetPalette;
- re.BeginFrame = R_BeginFrame;
- re.EndFrame = SWimp_EndFrame;
- re.AppActivate = SWimp_AppActivate;
- Swap_Init ();
- return re;
- }
- #ifndef REF_HARD_LINKED
- // this is only here so the functions in q_shared.c and q_shwin.c can link
- void Sys_Error (char *error, ...)
- {
- va_list argptr;
- char text[1024];
- va_start (argptr, error);
- vsprintf (text, error, argptr);
- va_end (argptr);
- ri.Sys_Error (ERR_FATAL, "%s", text);
- }
- void Com_Printf (char *fmt, ...)
- {
- va_list argptr;
- char text[1024];
- va_start (argptr, fmt);
- vsprintf (text, fmt, argptr);
- va_end (argptr);
- ri.Con_Printf (PRINT_ALL, "%s", text);
- }
- #endif
|