12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145 |
- /*
- Copyright (C) 1996-1997 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 "quakedef.h"
- entity_t r_worldentity;
- qboolean r_cache_thrash; // compatability
- vec3_t modelorg, r_entorigin;
- entity_t *currententity;
- int r_visframecount; // bumped when going to a new PVS
- int r_framecount; // used for dlight push checking
- mplane_t frustum[4];
- int c_brush_polys, c_alias_polys;
- qboolean envmap; // true during envmap command capture
- int currenttexture = -1; // to avoid unnecessary texture sets
- int cnttextures[2] = {-1, -1}; // cached
- int particletexture; // little dot for particles
- int playertextures; // up to 16 color translated skins
- int mirrortexturenum; // quake texturenum, not gltexturenum
- qboolean mirror;
- mplane_t *mirror_plane;
- //
- // view origin
- //
- vec3_t vup;
- vec3_t vpn;
- vec3_t vright;
- vec3_t r_origin;
- float r_world_matrix[16];
- float r_base_world_matrix[16];
- //
- // screen size info
- //
- refdef_t r_refdef;
- mleaf_t *r_viewleaf, *r_oldviewleaf;
- texture_t *r_notexture_mip;
- int d_lightstylevalue[256]; // 8.8 fraction of base light value
- void R_MarkLeaves (void);
- cvar_t r_norefresh = {"r_norefresh","0"};
- cvar_t r_drawentities = {"r_drawentities","1"};
- cvar_t r_drawviewmodel = {"r_drawviewmodel","1"};
- cvar_t r_speeds = {"r_speeds","0"};
- cvar_t r_fullbright = {"r_fullbright","0"};
- cvar_t r_lightmap = {"r_lightmap","0"};
- cvar_t r_shadows = {"r_shadows","0"};
- cvar_t r_mirroralpha = {"r_mirroralpha","1"};
- cvar_t r_wateralpha = {"r_wateralpha","1"};
- cvar_t r_dynamic = {"r_dynamic","1"};
- cvar_t r_novis = {"r_novis","0"};
- cvar_t r_netgraph = {"r_netgraph","0"};
- cvar_t gl_clear = {"gl_clear","0"};
- cvar_t gl_cull = {"gl_cull","1"};
- cvar_t gl_texsort = {"gl_texsort","1"};
- cvar_t gl_smoothmodels = {"gl_smoothmodels","1"};
- cvar_t gl_affinemodels = {"gl_affinemodels","0"};
- cvar_t gl_polyblend = {"gl_polyblend","1"};
- cvar_t gl_flashblend = {"gl_flashblend","1"};
- cvar_t gl_playermip = {"gl_playermip","0"};
- cvar_t gl_nocolors = {"gl_nocolors","0"};
- cvar_t gl_keeptjunctions = {"gl_keeptjunctions","1"};
- cvar_t gl_reporttjunctions = {"gl_reporttjunctions","0"};
- cvar_t gl_finish = {"gl_finish","0"};
- extern cvar_t gl_ztrick;
- extern cvar_t scr_fov;
- /*
- =================
- R_CullBox
- Returns true if the box is completely outside the frustom
- =================
- */
- qboolean R_CullBox (vec3_t mins, vec3_t maxs)
- {
- int i;
- for (i=0 ; i<4 ; i++)
- if (BoxOnPlaneSide (mins, maxs, &frustum[i]) == 2)
- return true;
- return false;
- }
- void R_RotateForEntity (entity_t *e)
- {
- glTranslatef (e->origin[0], e->origin[1], e->origin[2]);
- glRotatef (e->angles[1], 0, 0, 1);
- glRotatef (-e->angles[0], 0, 1, 0);
- //ZOID: fixed z angle
- glRotatef (e->angles[2], 1, 0, 0);
- }
- /*
- =============================================================
- SPRITE MODELS
- =============================================================
- */
- /*
- ================
- R_GetSpriteFrame
- ================
- */
- mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
- {
- msprite_t *psprite;
- mspritegroup_t *pspritegroup;
- mspriteframe_t *pspriteframe;
- int i, numframes, frame;
- float *pintervals, fullinterval, targettime, time;
- psprite = currententity->model->cache.data;
- frame = currententity->frame;
- if ((frame >= psprite->numframes) || (frame < 0))
- {
- Con_Printf ("R_DrawSprite: no such frame %d\n", frame);
- frame = 0;
- }
- if (psprite->frames[frame].type == SPR_SINGLE)
- {
- pspriteframe = psprite->frames[frame].frameptr;
- }
- else
- {
- pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr;
- pintervals = pspritegroup->intervals;
- numframes = pspritegroup->numframes;
- fullinterval = pintervals[numframes-1];
- time = cl.time + currententity->syncbase;
- // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values
- // are positive, so we don't have to worry about division by 0
- targettime = time - ((int)(time / fullinterval)) * fullinterval;
- for (i=0 ; i<(numframes-1) ; i++)
- {
- if (pintervals[i] > targettime)
- break;
- }
- pspriteframe = pspritegroup->frames[i];
- }
- return pspriteframe;
- }
- /*
- =================
- R_DrawSpriteModel
- =================
- */
- void R_DrawSpriteModel (entity_t *e)
- {
- vec3_t point;
- mspriteframe_t *frame;
- float *up, *right;
- vec3_t v_forward, v_right, v_up;
- msprite_t *psprite;
- // don't even bother culling, because it's just a single
- // polygon without a surface cache
- frame = R_GetSpriteFrame (e);
- psprite = currententity->model->cache.data;
- if (psprite->type == SPR_ORIENTED)
- { // bullet marks on walls
- AngleVectors (currententity->angles, v_forward, v_right, v_up);
- up = v_up;
- right = v_right;
- }
- else
- { // normal sprite
- up = vup;
- right = vright;
- }
- glColor3f (1,1,1);
- GL_DisableMultitexture();
- GL_Bind(frame->gl_texturenum);
- glEnable (GL_ALPHA_TEST);
- glBegin (GL_QUADS);
- glEnable (GL_ALPHA_TEST);
- glBegin (GL_QUADS);
- glTexCoord2f (0, 1);
- VectorMA (e->origin, frame->down, up, point);
- VectorMA (point, frame->left, right, point);
- glVertex3fv (point);
- glTexCoord2f (0, 0);
- VectorMA (e->origin, frame->up, up, point);
- VectorMA (point, frame->left, right, point);
- glVertex3fv (point);
- glTexCoord2f (1, 0);
- VectorMA (e->origin, frame->up, up, point);
- VectorMA (point, frame->right, right, point);
- glVertex3fv (point);
- glTexCoord2f (1, 1);
- VectorMA (e->origin, frame->down, up, point);
- VectorMA (point, frame->right, right, point);
- glVertex3fv (point);
-
- glEnd ();
- glDisable (GL_ALPHA_TEST);
- }
- /*
- =============================================================
- ALIAS MODELS
- =============================================================
- */
- #define NUMVERTEXNORMALS 162
- float r_avertexnormals[NUMVERTEXNORMALS][3] = {
- #include "anorms.h"
- };
- vec3_t shadevector;
- float shadelight, ambientlight;
- // precalculated dot products for quantized angles
- #define SHADEDOT_QUANT 16
- float r_avertexnormal_dots[SHADEDOT_QUANT][256] =
- #include "anorm_dots.h"
- ;
- float *shadedots = r_avertexnormal_dots[0];
- int lastposenum;
- /*
- =============
- GL_DrawAliasFrame
- =============
- */
- void GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum)
- {
- float l;
- trivertx_t *verts;
- int *order;
- int count;
- lastposenum = posenum;
- verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata);
- verts += posenum * paliashdr->poseverts;
- order = (int *)((byte *)paliashdr + paliashdr->commands);
- while (1)
- {
- // get the vertex count and primitive type
- count = *order++;
- if (!count)
- break; // done
- if (count < 0)
- {
- count = -count;
- glBegin (GL_TRIANGLE_FAN);
- }
- else
- glBegin (GL_TRIANGLE_STRIP);
- do
- {
- // texture coordinates come from the draw list
- glTexCoord2f (((float *)order)[0], ((float *)order)[1]);
- order += 2;
- // normals and vertexes come from the frame list
- l = shadedots[verts->lightnormalindex] * shadelight;
- glColor3f (l, l, l);
- glVertex3f (verts->v[0], verts->v[1], verts->v[2]);
- verts++;
- } while (--count);
- glEnd ();
- }
- }
- /*
- =============
- GL_DrawAliasShadow
- =============
- */
- extern vec3_t lightspot;
- void GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum)
- {
- trivertx_t *verts;
- int *order;
- vec3_t point;
- float height, lheight;
- int count;
- lheight = currententity->origin[2] - lightspot[2];
- height = 0;
- verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata);
- verts += posenum * paliashdr->poseverts;
- order = (int *)((byte *)paliashdr + paliashdr->commands);
- height = -lheight + 1.0;
- while (1)
- {
- // get the vertex count and primitive type
- count = *order++;
- if (!count)
- break; // done
- if (count < 0)
- {
- count = -count;
- glBegin (GL_TRIANGLE_FAN);
- }
- else
- glBegin (GL_TRIANGLE_STRIP);
- do
- {
- // texture coordinates come from the draw list
- // (skipped for shadows) glTexCoord2fv ((float *)order);
- order += 2;
- // normals and vertexes come from the frame list
- point[0] = verts->v[0] * paliashdr->scale[0] + paliashdr->scale_origin[0];
- point[1] = verts->v[1] * paliashdr->scale[1] + paliashdr->scale_origin[1];
- point[2] = verts->v[2] * paliashdr->scale[2] + paliashdr->scale_origin[2];
- point[0] -= shadevector[0]*(point[2]+lheight);
- point[1] -= shadevector[1]*(point[2]+lheight);
- point[2] = height;
- // height -= 0.001;
- glVertex3fv (point);
- verts++;
- } while (--count);
- glEnd ();
- }
- }
- /*
- =================
- R_SetupAliasFrame
- =================
- */
- void R_SetupAliasFrame (int frame, aliashdr_t *paliashdr)
- {
- int pose, numposes;
- float interval;
- if ((frame >= paliashdr->numframes) || (frame < 0))
- {
- Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame);
- frame = 0;
- }
- pose = paliashdr->frames[frame].firstpose;
- numposes = paliashdr->frames[frame].numposes;
- if (numposes > 1)
- {
- interval = paliashdr->frames[frame].interval;
- pose += (int)(cl.time / interval) % numposes;
- }
- GL_DrawAliasFrame (paliashdr, pose);
- }
- /*
- =================
- R_DrawAliasModel
- =================
- */
- void R_DrawAliasModel (entity_t *e)
- {
- int i;
- int lnum;
- vec3_t dist;
- float add;
- model_t *clmodel;
- vec3_t mins, maxs;
- aliashdr_t *paliashdr;
- float an;
- int anim;
- clmodel = currententity->model;
- VectorAdd (currententity->origin, clmodel->mins, mins);
- VectorAdd (currententity->origin, clmodel->maxs, maxs);
- if (R_CullBox (mins, maxs))
- return;
- VectorCopy (currententity->origin, r_entorigin);
- VectorSubtract (r_origin, r_entorigin, modelorg);
- //
- // get lighting information
- //
- ambientlight = shadelight = R_LightPoint (currententity->origin);
- // allways give the gun some light
- if (e == &cl.viewent && ambientlight < 24)
- ambientlight = shadelight = 24;
- for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
- {
- if (cl_dlights[lnum].die >= cl.time)
- {
- VectorSubtract (currententity->origin,
- cl_dlights[lnum].origin,
- dist);
- add = cl_dlights[lnum].radius - Length(dist);
- if (add > 0) {
- ambientlight += add;
- //ZOID models should be affected by dlights as well
- shadelight += add;
- }
- }
- }
- // clamp lighting so it doesn't overbright as much
- if (ambientlight > 128)
- ambientlight = 128;
- if (ambientlight + shadelight > 192)
- shadelight = 192 - ambientlight;
- // ZOID: never allow players to go totally black
- if (!strcmp(clmodel->name, "progs/player.mdl")) {
- if (ambientlight < 8)
- ambientlight = shadelight = 8;
- } else if (!strcmp (clmodel->name, "progs/flame2.mdl")
- || !strcmp (clmodel->name, "progs/flame.mdl") )
- // HACK HACK HACK -- no fullbright colors, so make torches full light
- ambientlight = shadelight = 256;
- shadedots = r_avertexnormal_dots[((int)(e->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
- shadelight = shadelight / 200.0;
-
- an = e->angles[1]/180*M_PI;
- shadevector[0] = cos(-an);
- shadevector[1] = sin(-an);
- shadevector[2] = 1;
- VectorNormalize (shadevector);
- //
- // locate the proper data
- //
- paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model);
- c_alias_polys += paliashdr->numtris;
- //
- // draw all the triangles
- //
- GL_DisableMultitexture();
- glPushMatrix ();
- R_RotateForEntity (e);
- if (!strcmp (clmodel->name, "progs/eyes.mdl") ) {
- glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2] - (22 + 8));
- // double size of eyes, since they are really hard to see in gl
- glScalef (paliashdr->scale[0]*2, paliashdr->scale[1]*2, paliashdr->scale[2]*2);
- } else {
- glTranslatef (paliashdr->scale_origin[0], paliashdr->scale_origin[1], paliashdr->scale_origin[2]);
- glScalef (paliashdr->scale[0], paliashdr->scale[1], paliashdr->scale[2]);
- }
- anim = (int)(cl.time*10) & 3;
- GL_Bind(paliashdr->gl_texturenum[currententity->skinnum][anim]);
- // we can't dynamically colormap textures, so they are cached
- // seperately for the players. Heads are just uncolored.
- if (currententity->scoreboard && !gl_nocolors.value)
- {
- i = currententity->scoreboard - cl.players;
- if (!currententity->scoreboard->skin) {
- Skin_Find(currententity->scoreboard);
- R_TranslatePlayerSkin(i);
- }
- if (i >= 0 && i<MAX_CLIENTS)
- GL_Bind(playertextures + i);
- }
- if (gl_smoothmodels.value)
- glShadeModel (GL_SMOOTH);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- if (gl_affinemodels.value)
- glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
- R_SetupAliasFrame (currententity->frame, paliashdr);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glShadeModel (GL_FLAT);
- if (gl_affinemodels.value)
- glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
- glPopMatrix ();
- if (r_shadows.value)
- {
- glPushMatrix ();
- R_RotateForEntity (e);
- glDisable (GL_TEXTURE_2D);
- glEnable (GL_BLEND);
- glColor4f (0,0,0,0.5);
- GL_DrawAliasShadow (paliashdr, lastposenum);
- glEnable (GL_TEXTURE_2D);
- glDisable (GL_BLEND);
- glColor4f (1,1,1,1);
- glPopMatrix ();
- }
- }
- //==================================================================================
- /*
- =============
- R_DrawEntitiesOnList
- =============
- */
- void R_DrawEntitiesOnList (void)
- {
- int i;
- if (!r_drawentities.value)
- return;
- // draw sprites seperately, because of alpha blending
- for (i=0 ; i<cl_numvisedicts ; i++)
- {
- currententity = &cl_visedicts[i];
- switch (currententity->model->type)
- {
- case mod_alias:
- R_DrawAliasModel (currententity);
- break;
- case mod_brush:
- R_DrawBrushModel (currententity);
- break;
- default:
- break;
- }
- }
- for (i=0 ; i<cl_numvisedicts ; i++)
- {
- currententity = &cl_visedicts[i];
- switch (currententity->model->type)
- {
- case mod_sprite:
- R_DrawSpriteModel (currententity);
- break;
- default :
- break;
- }
- }
- }
- /*
- =============
- R_DrawViewModel
- =============
- */
- void R_DrawViewModel (void)
- {
- float ambient[4], diffuse[4];
- int j;
- int lnum;
- vec3_t dist;
- float add;
- dlight_t *dl;
- int ambientlight, shadelight;
- if (!r_drawviewmodel.value || !Cam_DrawViewModel())
- return;
- if (envmap)
- return;
- if (!r_drawentities.value)
- return;
- if (cl.stats[STAT_ITEMS] & IT_INVISIBILITY)
- return;
- if (cl.stats[STAT_HEALTH] <= 0)
- return;
- currententity = &cl.viewent;
- if (!currententity->model)
- return;
- j = R_LightPoint (currententity->origin);
- if (j < 24)
- j = 24; // allways give some light on gun
- ambientlight = j;
- shadelight = j;
- // add dynamic lights
- for (lnum=0 ; lnum<MAX_DLIGHTS ; lnum++)
- {
- dl = &cl_dlights[lnum];
- if (!dl->radius)
- continue;
- if (!dl->radius)
- continue;
- if (dl->die < cl.time)
- continue;
- VectorSubtract (currententity->origin, dl->origin, dist);
- add = dl->radius - Length(dist);
- if (add > 0)
- ambientlight += add;
- }
- ambient[0] = ambient[1] = ambient[2] = ambient[3] = (float)ambientlight / 128;
- diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = (float)shadelight / 128;
- // hack the depth range to prevent view model from poking into walls
- glDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
- R_DrawAliasModel (currententity);
- glDepthRange (gldepthmin, gldepthmax);
- }
- /*
- ============
- R_PolyBlend
- ============
- */
- void R_PolyBlend (void)
- {
- if (!gl_polyblend.value)
- return;
- if (!v_blend[3])
- return;
- //Con_Printf("R_PolyBlend(): %4.2f %4.2f %4.2f %4.2f\n",v_blend[0], v_blend[1], v_blend[2], v_blend[3]);
- GL_DisableMultitexture();
- glDisable (GL_ALPHA_TEST);
- glEnable (GL_BLEND);
- glDisable (GL_DEPTH_TEST);
- glDisable (GL_TEXTURE_2D);
- glLoadIdentity ();
- glRotatef (-90, 1, 0, 0); // put Z going up
- glRotatef (90, 0, 0, 1); // put Z going up
- glColor4fv (v_blend);
- glBegin (GL_QUADS);
- glVertex3f (10, 100, 100);
- glVertex3f (10, -100, 100);
- glVertex3f (10, -100, -100);
- glVertex3f (10, 100, -100);
- glEnd ();
- glDisable (GL_BLEND);
- glEnable (GL_TEXTURE_2D);
- glEnable (GL_ALPHA_TEST);
- }
- int SignbitsForPlane (mplane_t *out)
- {
- int bits, j;
- // for fast box on planeside test
- bits = 0;
- for (j=0 ; j<3 ; j++)
- {
- if (out->normal[j] < 0)
- bits |= 1<<j;
- }
- return bits;
- }
- void R_SetFrustum (void)
- {
- int i;
- if (r_refdef.fov_x == 90)
- {
- // front side is visible
- VectorAdd (vpn, vright, frustum[0].normal);
- VectorSubtract (vpn, vright, frustum[1].normal);
- VectorAdd (vpn, vup, frustum[2].normal);
- VectorSubtract (vpn, vup, frustum[3].normal);
- }
- else
- {
- // rotate VPN right by FOV_X/2 degrees
- RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_refdef.fov_x / 2 ) );
- // rotate VPN left by FOV_X/2 degrees
- RotatePointAroundVector( frustum[1].normal, vup, vpn, 90-r_refdef.fov_x / 2 );
- // rotate VPN up by FOV_X/2 degrees
- RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_refdef.fov_y / 2 );
- // rotate VPN down by FOV_X/2 degrees
- RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_refdef.fov_y / 2 ) );
- }
- for (i=0 ; i<4 ; i++)
- {
- frustum[i].type = PLANE_ANYZ;
- frustum[i].dist = DotProduct (r_origin, frustum[i].normal);
- frustum[i].signbits = SignbitsForPlane (&frustum[i]);
- }
- }
- /*
- ===============
- R_SetupFrame
- ===============
- */
- void R_SetupFrame (void)
- {
- // don't allow cheats in multiplayer
- r_fullbright.value = 0;
- r_lightmap.value = 0;
- if (!atoi(Info_ValueForKey(cl.serverinfo, "watervis")))
- r_wateralpha.value = 1;
- R_AnimateLight ();
- r_framecount++;
- // build the transformation matrix for the given view angles
- VectorCopy (r_refdef.vieworg, r_origin);
- AngleVectors (r_refdef.viewangles, vpn, vright, vup);
- // current viewleaf
- r_oldviewleaf = r_viewleaf;
- r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel);
- V_SetContentsColor (r_viewleaf->contents);
- V_CalcBlend ();
- r_cache_thrash = false;
- c_brush_polys = 0;
- c_alias_polys = 0;
- }
- void MYgluPerspective( GLdouble fovy, GLdouble aspect,
- GLdouble zNear, GLdouble zFar )
- {
- GLdouble xmin, xmax, ymin, ymax;
- ymax = zNear * tan( fovy * M_PI / 360.0 );
- ymin = -ymax;
- xmin = ymin * aspect;
- xmax = ymax * aspect;
- glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
- }
- /*
- =============
- R_SetupGL
- =============
- */
- void R_SetupGL (void)
- {
- float screenaspect;
- extern int glwidth, glheight;
- int x, x2, y2, y, w, h;
- //
- // set up viewpoint
- //
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity ();
- x = r_refdef.vrect.x * glwidth/vid.width;
- x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/vid.width;
- y = (vid.height-r_refdef.vrect.y) * glheight/vid.height;
- y2 = (vid.height - (r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/vid.height;
- // fudge around because of frac screen scale
- if (x > 0)
- x--;
- if (x2 < glwidth)
- x2++;
- if (y2 < 0)
- y2--;
- if (y < glheight)
- y++;
- w = x2 - x;
- h = y - y2;
- if (envmap)
- {
- x = y2 = 0;
- w = h = 256;
- }
- glViewport (glx + x, gly + y2, w, h);
- screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height;
- // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI;
- // yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect;
- // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov.value*2)/M_PI;
- // MYgluPerspective (yfov, screenaspect, 4, 4096);
- MYgluPerspective (r_refdef.fov_y, screenaspect, 4, 4096);
- if (mirror)
- {
- if (mirror_plane->normal[2])
- glScalef (1, -1, 1);
- else
- glScalef (-1, 1, 1);
- glCullFace(GL_BACK);
- }
- else
- glCullFace(GL_FRONT);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity ();
- glRotatef (-90, 1, 0, 0); // put Z going up
- glRotatef (90, 0, 0, 1); // put Z going up
- glRotatef (-r_refdef.viewangles[2], 1, 0, 0);
- glRotatef (-r_refdef.viewangles[0], 0, 1, 0);
- glRotatef (-r_refdef.viewangles[1], 0, 0, 1);
- glTranslatef (-r_refdef.vieworg[0], -r_refdef.vieworg[1], -r_refdef.vieworg[2]);
- glGetFloatv (GL_MODELVIEW_MATRIX, r_world_matrix);
- //
- // set drawing parms
- //
- if (gl_cull.value)
- glEnable(GL_CULL_FACE);
- else
- glDisable(GL_CULL_FACE);
- glDisable(GL_BLEND);
- glDisable(GL_ALPHA_TEST);
- glEnable(GL_DEPTH_TEST);
- }
- /*
- ================
- R_RenderScene
- r_refdef must be set before the first call
- ================
- */
- void R_RenderScene (void)
- {
- R_SetupFrame ();
- R_SetFrustum ();
- R_SetupGL ();
- R_MarkLeaves (); // done here so we know if we're in water
- R_DrawWorld (); // adds static entities to the list
- S_ExtraUpdate (); // don't let sound get messed up if going slow
- R_DrawEntitiesOnList ();
- GL_DisableMultitexture();
- R_RenderDlights ();
- R_DrawParticles ();
- #ifdef GLTEST
- Test_Draw ();
- #endif
- }
- /*
- =============
- R_Clear
- =============
- */
- void R_Clear (void)
- {
- if (r_mirroralpha.value != 1.0)
- {
- if (gl_clear.value)
- glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- else
- glClear (GL_DEPTH_BUFFER_BIT);
- gldepthmin = 0;
- gldepthmax = 0.5;
- glDepthFunc (GL_LEQUAL);
- }
- else if (gl_ztrick.value)
- {
- static int trickframe;
- if (gl_clear.value)
- glClear (GL_COLOR_BUFFER_BIT);
- trickframe++;
- if (trickframe & 1)
- {
- gldepthmin = 0;
- gldepthmax = 0.49999;
- glDepthFunc (GL_LEQUAL);
- }
- else
- {
- gldepthmin = 1;
- gldepthmax = 0.5;
- glDepthFunc (GL_GEQUAL);
- }
- }
- else
- {
- if (gl_clear.value)
- glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- else
- glClear (GL_DEPTH_BUFFER_BIT);
- gldepthmin = 0;
- gldepthmax = 1;
- glDepthFunc (GL_LEQUAL);
- }
- glDepthRange (gldepthmin, gldepthmax);
- }
- #if 0 //!!! FIXME, Zoid, mirror is disabled for now
- /*
- =============
- R_Mirror
- =============
- */
- void R_Mirror (void)
- {
- float d;
- msurface_t *s;
- entity_t *ent;
- if (!mirror)
- return;
- memcpy (r_base_world_matrix, r_world_matrix, sizeof(r_base_world_matrix));
- d = DotProduct (r_refdef.vieworg, mirror_plane->normal) - mirror_plane->dist;
- VectorMA (r_refdef.vieworg, -2*d, mirror_plane->normal, r_refdef.vieworg);
- d = DotProduct (vpn, mirror_plane->normal);
- VectorMA (vpn, -2*d, mirror_plane->normal, vpn);
- r_refdef.viewangles[0] = -asin (vpn[2])/M_PI*180;
- r_refdef.viewangles[1] = atan2 (vpn[1], vpn[0])/M_PI*180;
- r_refdef.viewangles[2] = -r_refdef.viewangles[2];
- ent = &cl_entities[cl.viewentity];
- if (cl_numvisedicts < MAX_VISEDICTS)
- {
- cl_visedicts[cl_numvisedicts] = ent;
- cl_numvisedicts++;
- }
- gldepthmin = 0.5;
- gldepthmax = 1;
- glDepthRange (gldepthmin, gldepthmax);
- glDepthFunc (GL_LEQUAL);
- R_RenderScene ();
- R_DrawWaterSurfaces ();
- gldepthmin = 0;
- gldepthmax = 0.5;
- glDepthRange (gldepthmin, gldepthmax);
- glDepthFunc (GL_LEQUAL);
- // blend on top
- glEnable (GL_BLEND);
- glMatrixMode(GL_PROJECTION);
- if (mirror_plane->normal[2])
- glScalef (1,-1,1);
- else
- glScalef (-1,1,1);
- glCullFace(GL_FRONT);
- glMatrixMode(GL_MODELVIEW);
- glLoadMatrixf (r_base_world_matrix);
- glColor4f (1,1,1,r_mirroralpha.value);
- s = cl.worldmodel->textures[mirrortexturenum]->texturechain;
- for ( ; s ; s=s->texturechain)
- R_RenderBrushPoly (s);
- cl.worldmodel->textures[mirrortexturenum]->texturechain = NULL;
- glDisable (GL_BLEND);
- glColor4f (1,1,1,1);
- }
- #endif
- /*
- ================
- R_RenderView
- r_refdef must be set before the first call
- ================
- */
- void R_RenderView (void)
- {
- double time1 = 0, time2;
- if (r_norefresh.value)
- return;
- if (!r_worldentity.model || !cl.worldmodel)
- Sys_Error ("R_RenderView: NULL worldmodel");
- if (r_speeds.value)
- {
- glFinish ();
- time1 = Sys_DoubleTime ();
- c_brush_polys = 0;
- c_alias_polys = 0;
- }
- mirror = false;
- if (gl_finish.value)
- glFinish ();
- R_Clear ();
- // render normal view
- R_RenderScene ();
- R_DrawViewModel ();
- R_DrawWaterSurfaces ();
- // render mirror view
- // R_Mirror ();
- R_PolyBlend ();
- if (r_speeds.value)
- {
- // glFinish ();
- time2 = Sys_DoubleTime ();
- Con_Printf ("%3i ms %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys);
- }
- }
|