/* ================= SCR_CalcRefdef Must be called whenever vid changes Internal use only ================= */ static void SCR_CalcRefdef(void) { vrect_t vrect; float size; scr_fullupdate = 0; // force a background redraw vid.recalc_refdef = 0; // force the status bar to redraw Sbar_Changed(); //======================================== // bound viewsize if (scr_viewsize.value < 30) Cvar_Set("viewsize", "30"); if (scr_viewsize.value > 120) Cvar_Set("viewsize", "120"); // bound field of view if (scr_fov.value < 10) Cvar_Set("fov", "10"); if (scr_fov.value > 170) Cvar_Set("fov", "170"); r_refdef.fov_x = scr_fov.value; r_refdef.fov_y = CalcFov(r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); // intermission is always full screen if (cl.intermission) size = 120; else size = scr_viewsize.value; if (size >= 120) sb_lines = 0; // no status bar at all else if (size >= 110) sb_lines = 24; // no inventory else sb_lines = 24 + 16 + 8; // these calculations mirror those in R_Init() for r_refdef, but take no // account of water warping vrect.x = 0; vrect.y = 0; vrect.width = vid.width; vrect.height = vid.height; R_SetVrect(&vrect, &scr_vrect, sb_lines); // guard against going from one mode to another that's less than half the // vertical resolution if (scr_con_current > vid.height) scr_con_current = vid.height; // notify the refresh of the change R_ViewChanged(&vrect, sb_lines, vid.aspect); }
void V_Move(int mx, int my) { float fov; float fx, fy; float dx, dy; float c_x, c_y; float dX, dY; vec3_t forward, up, right; vec3_t newangles; vec3_t farpoint; pmtrace_t tr; fov = CalcFov(in_fov, (float)ScreenWidth, (float)ScreenHeight); c_x = (float)ScreenWidth / 2.0; c_y = (float)ScreenHeight / 2.0; dx = (float)mx - c_x; dy = (float)my - c_y; // Proportion we moved in each direction fx = dx / c_x; fy = dy / c_y; dX = fx * in_fov / 2.0; dY = fy * fov / 2.0; newangles = v_angles; newangles[YAW] -= dX; newangles[PITCH] += dY; // Now rotate v_forward around that point AngleVectors(newangles, forward, right, up); farpoint = v_origin + 8192 * forward; // Trace tr = *(gEngfuncs.PM_TraceLine((float *)&v_origin, (float *)&farpoint, PM_TRACELINE_PHYSENTSONLY, 2 /*point sized hull*/, -1)); if(tr.fraction != 1.0 && tr.ent != 0) { hitent = PM_GetInfo(tr.ent); PM_ParticleLine((float *)&v_origin, (float *)&tr.endpos, 5, 1.0, 0.0); } else { hitent = -1; } }
int SYS::window_create() { #ifdef WIN32 glClearStencil(0); glStencilFunc(GL_ALWAYS, 1, 1); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); //glMTexCoord2fSGIS = (lpMTexFUNC) wglGetProcAddress("glMultiTexCoord2fARB"); //glSelectTextureSGIS = (lpSelTexFUNC) wglGetProcAddress("glActiveTextureARB"); //if(glMTexCoord2fSGIS == NULL) // glMTexCoord2fSGIS = (lpMTexFUNC) wglGetProcAddress("glMTexCoord2fSGIS"); /*GetWindowRect(openGL,&rc); ClipCursor(&rc); ShowCursor(FALSE); GLWindow.Size(rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top); */ glColor4f(1, 1, 1, 1.0f); glViewport(0, 0, DS_SCREEN_WIDTH - 1, DS_SCREEN_HEIGHT - 1); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //gluPerspective(73.74, 256.0 / 192.0, 0.005, 40.0); //gluPerspective(68.3, (float)800 / (float)600, 0.005, 40.0); //gluPerspective(73.74, (float)DS_SCREEN_WIDTH / (float)DS_SCREEN_HEIGHT, 5, 10000.0); MYgluPerspective(CalcFov(90, DS_SCREEN_WIDTH, DS_SCREEN_HEIGHT), (float)DS_SCREEN_WIDTH / (float)DS_SCREEN_HEIGHT, 4, 8192); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); //glDisable(GL_TEXTURE_2D); ShowCursor(0); #endif set_position(0, 0, 400, 240); build_font(); return 0; }
static void VQH_CalcRefdef() { // bound field of view if ( scr_fov->value < 10 ) { Cvar_Set( "fov","10" ); } if ( scr_fov->value > 170 ) { Cvar_Set( "fov","170" ); } cl.refdef.x = scr_vrect.x * cls.glconfig.vidWidth / viddef.width; cl.refdef.y = scr_vrect.y * cls.glconfig.vidHeight / viddef.height; cl.refdef.width = scr_vrect.width * cls.glconfig.vidWidth / viddef.width; cl.refdef.height = scr_vrect.height * cls.glconfig.vidHeight / viddef.height; cl.refdef.fov_x = GGameType & GAME_Hexen2 && !( GGameType & GAME_HexenWorld ) ? 90 : scr_fov->value; cl.refdef.fov_y = CalcFov( cl.refdef.fov_x, cl.refdef.width, cl.refdef.height ); }
/* * CG_DrawModel */ static void CG_DrawModel( int x, int y, int align, int w, int h, struct model_s *model, struct shader_s *shader, vec3_t origin, vec3_t angles, bool outline ) { refdef_t refdef; entity_t entity; if( !model ) return; x = CG_HorizontalAlignForWidth( x, align, w ); y = CG_VerticalAlignForHeight( y, align, h ); memset( &refdef, 0, sizeof( refdef ) ); refdef.x = x; refdef.y = y; refdef.width = w; refdef.height = h; refdef.fov_x = 30; refdef.fov_y = CalcFov( refdef.fov_x, w, h ); refdef.time = cg.time; refdef.rdflags = RDF_NOWORLDMODEL; Matrix3_Copy( axis_identity, refdef.viewaxis ); refdef.scissor_x = x; refdef.scissor_y = y; refdef.scissor_width = w; refdef.scissor_height = h; memset( &entity, 0, sizeof( entity ) ); entity.model = model; entity.customShader = shader; entity.scale = 1.0f; entity.renderfx = RF_FULLBRIGHT | RF_NOSHADOW | RF_FORCENOLOD; VectorCopy( origin, entity.origin ); VectorCopy( entity.origin, entity.origin2 ); AnglesToAxis( angles, entity.axis ); if( outline ) { entity.outlineHeight = DEFAULT_OUTLINE_HEIGHT; Vector4Set( entity.outlineRGBA, 0, 0, 0, 255 ); } trap_R_ClearScene(); CG_SetBoneposesForTemporaryEntity( &entity ); CG_AddEntityToScene( &entity ); trap_R_RenderScene( &refdef ); }
/* * R_SetupShadowmapView */ static float R_SetupShadowmapView( shadowGroup_t *group, refdef_t *refdef, int lod ) { int width, height; float farClip; image_t *shadowmap; // clamp LOD to a sane value clamp( lod, 0, SHADOWMAP_MAX_LOD ); shadowmap = group->shadowmap; width = shadowmap->upload_width >> lod; height = shadowmap->upload_height >> lod; if( !width || !height ) { return 0.0f; } refdef->x = 0; refdef->y = 0; refdef->width = width; refdef->height = height; // default fov to 90, R_SetupFrame will most likely alter the values to give depth more precision refdef->fov_x = 90; refdef->fov_y = CalcFov( refdef->fov_x, refdef->width, refdef->height ); refdef->ortho_x = refdef->width; refdef->ortho_y = refdef->height; refdef->rdflags = group->useOrtho ? RDF_USEORTHO : 0; // set the view matrix // view axis are expected to be FLU (forward left up) NormalVectorToAxis( group->lightDir, refdef->viewaxis ); VectorInverse( &refdef->viewaxis[AXIS_RIGHT] ); // position the light source in the opposite direction VectorMA( group->origin, -group->projDist * 0.5, group->lightDir, refdef->vieworg ); // attempt to maximize the area the occulder occupies in viewport farClip = R_FitOccluder( group, refdef ); // store viewport and texture parameters for group, we'll need them later as GLSL uniforms group->viewportSize[0] = refdef->width; group->viewportSize[1] = refdef->height; group->textureSize[0] = shadowmap->upload_width; group->textureSize[1] = shadowmap->upload_height; return farClip; }
/* ============= UI_DrawMainCursor3D Draws a rotating quad damage model. ============= */ void UI_DrawMainCursor3D (int32_t x, int32_t y) { refdef_t refdef; entity_t quadEnt, *ent; float rx, ry, rw, rh; int32_t yaw; yaw = anglemod(cls.realtime/10); memset(&refdef, 0, sizeof(refdef)); memset (&quadEnt, 0, sizeof(quadEnt)); // size 24x34 rx = x; ry = y; rw = 24; rh = 34; SCR_AdjustFrom640 (&rx, &ry, &rw, &rh, ALIGN_CENTER); refdef.x = rx; refdef.y = ry; refdef.width = rw; refdef.height = rh; refdef.fov_x = 40; refdef.fov_y = CalcFov (refdef.fov_x, refdef.width, refdef.height); refdef.time = cls.realtime*0.001; refdef.areabits = 0; refdef.lightstyles = 0; refdef.rdflags = RDF_NOWORLDMODEL; refdef.num_entities = 0; refdef.entities = &quadEnt; ent = &quadEnt; ent->model = R_RegisterModel(QUAD_CURSOR_MODEL); ent->flags = RF_FULLBRIGHT|RF_NOSHADOW|RF_DEPTHHACK; VectorSet (ent->origin, 40, 0, -18); VectorCopy( ent->origin, ent->oldorigin ); ent->frame = 0; ent->oldframe = 0; ent->backlerp = 0.0; ent->angles[1] = yaw; refdef.num_entities++; R_RenderFrame( &refdef ); }
/* * R_DrawSkyPortal */ void R_DrawSkyPortal( const entity_t *e, skyportal_t *skyportal, vec3_t mins, vec3_t maxs ) { int x, y, w, h; if( !R_ScissorForEntity( e, mins, maxs, &x, &y, &w, &h ) ) { return; } if( !R_PushRefInst() ) { return; } rn.renderFlags = ( rn.renderFlags|RF_SKYPORTALVIEW|RF_SOFT_PARTICLES ); VectorCopy( skyportal->vieworg, rn.pvsOrigin ); rn.farClip = R_DefaultFarClip(); rn.clipFlags = 15; rn.shadowGroup = NULL; rn.meshlist = &r_skyportallist; //Vector4Set( rn.scissor, rn.refdef.x + x, rn.refdef.y + y, w, h ); if( skyportal->noEnts ) { rn.renderFlags |= RF_NOENTS; } if( skyportal->scale ) { vec3_t centre, diff; VectorAdd( rsh.worldModel->mins, rsh.worldModel->maxs, centre ); VectorScale( centre, 0.5f, centre ); VectorSubtract( centre, rn.viewOrigin, diff ); VectorMA( skyportal->vieworg, -skyportal->scale, diff, rn.refdef.vieworg ); } else { VectorCopy( skyportal->vieworg, rn.refdef.vieworg ); } // FIXME if( !VectorCompare( skyportal->viewanglesOffset, vec3_origin ) ) { vec3_t angles; mat3_t axis; Matrix3_Copy( rn.refdef.viewaxis, axis ); VectorInverse( &axis[AXIS_RIGHT] ); Matrix3_ToAngles( axis, angles ); VectorAdd( angles, skyportal->viewanglesOffset, angles ); AnglesToAxis( angles, axis ); Matrix3_Copy( axis, rn.refdef.viewaxis ); } rn.refdef.rdflags &= ~( RDF_UNDERWATER|RDF_CROSSINGWATER|RDF_SKYPORTALINVIEW ); if( skyportal->fov ) { rn.refdef.fov_x = skyportal->fov; rn.refdef.fov_y = CalcFov( rn.refdef.fov_x, rn.refdef.width, rn.refdef.height ); if( glConfig.wideScreen && !( rn.refdef.rdflags & RDF_NOFOVADJUSTMENT ) ) AdjustFov( &rn.refdef.fov_x, &rn.refdef.fov_y, glConfig.width, glConfig.height, qfalse ); } R_RenderView( &rn.refdef ); // restore modelview and projection matrices, scissoring, etc for the main view R_PopRefInst( ~GL_COLOR_BUFFER_BIT ); }
void CRender::ViewSetup3D( const CViewSetup *pView, Frustum frustumPlanes ) { VPROF("CRender::ViewSetup3D"); m_view = *pView; m_yFOV = CalcFov( m_view.fov, ( float )m_view.width, ( float )m_view.height ); if( g_nFrameBuffersToClear > 0 ) { SetViewport( m_view.x, m_view.y, m_view.width, m_view.height ); materialSystemInterface->ClearBuffers( true, m_view.clearDepth ); g_nFrameBuffersToClear--; } SetViewport( m_view.x, m_view.y + m_view.height * ( 1.0f - g_ViewportScale ), m_view.width * g_ViewportScale, m_view.height * g_ViewportScale ); if( m_view.clearColor || m_view.clearDepth ) { materialSystemInterface->ClearBuffers( m_view.clearColor, m_view.clearDepth ); } materialSystemInterface->DepthRange( 0, 1 ); // build the transformation matrix for the given view angles VectorCopy( m_view.origin, r_origin ); AngleVectors( m_view.angles, &vpn, &vright, &vup ); // vup = -vup; // Copy for VectorTransform VectorCopy( &vpn.x, asmvpn ); VectorCopy( &vright.x, asmvright ); VectorCopy( &vup.x, asmvup ); if ( pView->m_bOrtho ) { SetProjectionMatrixOrtho(pView->m_OrthoLeft, pView->m_OrthoTop, pView->m_OrthoRight, pView->m_OrthoBottom, pView->zNear, pView->zFar); } else { SetProjectionMatrix( m_view.fov, m_view.zNear, m_view.zFar, m_view.m_bForceAspectRatio1To1 ); } SetViewMatrix( m_view.origin, m_view.angles ); ExtractMatrices(); if ( pView->m_bOrtho ) { OrthoExtractFrustumPlanes( frustumPlanes ); } else { ExtractFrustumPlanes(frustumPlanes); } OcclusionSystem()->SetView( m_view.origin, m_view.fov, m_matrixView, m_matrixProjection, frustumPlanes[ FRUSTUM_NEARZ ] ); R_SceneBegin(); // debug, build leaf volume LeafVisBuild( Vector(r_origin) ); }
bool V_RenderView() { guard(V_RenderView); if (cls.state != ca_active) return false; if (!cl.rendererReady) return false; // still loading if (!bspfile.clientLoaded) return false; // map already unloaded (by server), but client is still active (ca_active) if (timedemo->integer) { static unsigned lastTime = 0; unsigned time = appMilliseconds(); if (!cl.timedemoStart) { cl.timedemoStart = time; // cl.timedemoLongestFrame = 0; -- cleared anyway within a new server map // cl.timedemoFrames = 0; } else { unsigned timeDelta = time - lastTime; if (timeDelta > cl.timedemoLongestFrame) //?? && !fileFromPak) cl.timedemoLongestFrame = timeDelta; } lastTime = time; cl.timedemoFrames++; } #if PROFILE_VIEW unsigned beforePrep = 0, beforeDebug = 0, beforeEffects = 0, afterEffects = 0, beforeRender, afterRender; #endif // an invalid frame will just use the exact previous refdef // we can't use the old frame if the video mode has changed, though... if (cl.frame.valid && (cl.forceViewFrame || !cl_paused->integer)) { PRF(beforePrep = appCycles()); cl.forceViewFrame = false; CalcVrect(); TileClear(); V_ClearScene(); cl.refdef.rdflags = cl.frame.playerstate.rdflags; // build a renderer entity list and calc cl.sim* // this also calls CL_CalcViewValues which loads // v_forward, etc. CL_AddEntities(); PRF(beforeEffects = appCycles()); CL_AddEffects(); PRF(afterEffects = appCycles()); CL_AddTEnts(); #if !NO_DEBUG if (cl_testentities->integer) TestEntities(); if (cl_testlights->integer) TestLights(); if (cl_testblend->integer) { r_blend[0] = 1; r_blend[1] = 0.5; r_blend[2] = 0.25; r_blend[3] = 0.5; } // debug output // free debug memory from previous frame if (debugMem) { delete debugMem; debugMem = NULL; } PRF(beforeDebug = appCycles()); if (r_playerpos->integer) DrawOriginInfo(); if (r_surfinfo->integer) DrawSurfInfo(); DrawBrush(); #endif // NO_DEBUG #if 0 // never let it sit exactly on a node line, because a water plane can // dissapear when viewed with the eye exactly on it. // the server protocol only specifies to 1/8 pixel, so add 1/16 in each axis cl.refdef.vieworg[0] += 1.0f/16; //?? cl.refdef.vieworg[1] += 1.0f/16; cl.refdef.vieworg[2] += 1.0f/16; #endif cl.refdef.x = scr_vrect.x; cl.refdef.y = scr_vrect.y; cl.refdef.width = scr_vrect.width; cl.refdef.height = scr_vrect.height; cl.refdef.fov_y = CalcFov(cl.refdef.fov_x, cl.refdef.width, cl.refdef.height); cl.refdef.time = cl.ftime; cl.refdef.zonebits = cl.frame.zonebits; if (!cl_add_entities->integer) r_numentities = 0; if (!cl_add_lights->integer) r_numdlights = 0; if (!cl_add_blend->integer || cl.refdef.rdflags & RDF_THIRD_PERSON) r_blend[3] = 0; cl.refdef.num_entities = r_numentities; cl.refdef.entities = r_entities; cl.refdef.particles = cl_add_particles->integer ? active_particles : NULL; cl.refdef.beams = active_beams; cl.refdef.num_dlights = r_numdlights; cl.refdef.dlights = r_dlights; cl.refdef.lightstyles = cl_lightstyles; // underwater fov warp (taken from Q3 game source) if (cl.refdef.rdflags & RDF_UNDERWATER) { float v = sin(cl.ftime * 0.4f * M_PI * 2); cl.refdef.fov_x += v; cl.refdef.fov_y -= v; } FixWaterVis(); } PRF(beforeRender = appCycles()); // render scene RE_RenderFrame(&cl.refdef); PRF(afterRender = appCycles()); // add full-screen blend if (r_blend[3]) RE_Fill(cl.refdef.x, cl.refdef.y, cl.refdef.width, cl.refdef.height, RGBAS(r_blend[0], r_blend[1], r_blend[2], r_blend[3])); #if PROFILE_VIEW RE_DrawTextLeft(va("V: prep1: %5.2f fx: %5.2f prep2: %5.2f dbg: %5.2f render: %5.2f", appCyclesToMsecf(beforeEffects - beforePrep), appCyclesToMsecf(afterEffects - beforeEffects), appCyclesToMsecf(beforeDebug - afterEffects), appCyclesToMsecf(beforeRender - beforeDebug), appCyclesToMsecf(afterRender - beforeRender)), RGB(0.2,1,0.2)); #endif // stats if (r_drawfps->integer) DrawFpsInfo(); return true; unguard; }
/* ================= SCR_CalcRefdef Must be called whenever vid changes Internal use only ================= */ static void SCR_CalcRefdef (void) { vrect_t vrect; float size; int h; qboolean full = false; scr_fullupdate = 0; // force a background redraw vid.recalc_refdef = 0; // force the status bar to redraw Sbar_Changed (); //======================================== // bound viewsize if (scr_viewsize.value < 30) Cvar_Set ("viewsize","30"); if (scr_viewsize.value > 120) Cvar_Set ("viewsize","120"); // bound field of view if (scr_fov.value < 10) Cvar_Set ("fov","10"); if (scr_fov.value > 170) Cvar_Set ("fov","170"); // intermission is always full screen if (cl.intermission) size = 120; else size = scr_viewsize.value; if (size >= 120) sb_lines = 0; // no status bar at all else if (size >= 110) sb_lines = 24; // no inventory else sb_lines = 24+16+8; if (scr_viewsize.value >= 100.0) { full = true; size = 100.0; } else size = scr_viewsize.value; if (cl.intermission) { full = true; size = 100; sb_lines = 0; } size /= 100.0; h = vid.height - sb_lines; r_refdef.vrect.width = vid.width * size; if (r_refdef.vrect.width < 96) { size = 96.0 / r_refdef.vrect.width; r_refdef.vrect.width = 96; // min for icons } r_refdef.vrect.height = vid.height * size; if (r_refdef.vrect.height > vid.height - sb_lines) r_refdef.vrect.height = vid.height - sb_lines; if (r_refdef.vrect.height > vid.height) r_refdef.vrect.height = vid.height; r_refdef.vrect.x = (vid.width - r_refdef.vrect.width)/2; if (full) r_refdef.vrect.y = 0; else r_refdef.vrect.y = (h - r_refdef.vrect.height)/2; r_refdef.fov_x = scr_fov.value; r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); scr_vrect = r_refdef.vrect; }
/* ===================== SetupFrustum ===================== */ void FrustumCheck::SetFrustum(Q_vec3_t vAngles, Q_vec3_t vOrigin, float flFOV_x, float flFarDist, bool bView) { Q_vec3_t vVpn, vUp, vRight; Q_AngleVectors(vAngles, vVpn, vRight, vUp); if (flFOV_x == 90) { VectorAdd(vVpn, vRight, m_sFrustum[0].vNormal); VectorSubtract(vVpn, vRight, m_sFrustum[1].vNormal); VectorAdd(vVpn, vUp, m_sFrustum[2].vNormal); VectorSubtract(vVpn, vUp, m_sFrustum[3].vNormal); } else { if (bView) { float flFOV_y = CalcFov(flFOV_x, ScreenWidth, ScreenHeight); Q_RotatePointAroundVector(m_sFrustum[0].vNormal, vUp, vVpn, -(90 - flFOV_x / 2)); Q_RotatePointAroundVector(m_sFrustum[1].vNormal, vUp, vVpn, 90 - flFOV_x / 2); Q_RotatePointAroundVector(m_sFrustum[2].vNormal, vRight, vVpn, 90 - flFOV_y / 2); Q_RotatePointAroundVector(m_sFrustum[3].vNormal, vRight, vVpn, -(90 - flFOV_y / 2)); } else { Q_RotatePointAroundVector(m_sFrustum[0].vNormal, vUp, vVpn, -(90 - flFOV_x / 2)); Q_RotatePointAroundVector(m_sFrustum[1].vNormal, vUp, vVpn, 90 - flFOV_x / 2); Q_RotatePointAroundVector(m_sFrustum[2].vNormal, vRight, vVpn, 90 - flFOV_x / 2); Q_RotatePointAroundVector(m_sFrustum[3].vNormal, vRight, vVpn, -(90 - flFOV_x / 2)); } } for (int i = 0; i < 4; i++) { m_sFrustum[i].type = PLANE_ANYZ; m_sFrustum[i].flDist = DotProduct(vOrigin, m_sFrustum[i].vNormal); m_sFrustum[i].signbits = Q_SignbitsForPlane(&m_sFrustum[i]); } // Reset this value m_iFarClip = FARCLIP_OFF; if (bView && !gHUD.m_pFogSettings.affectsky) return; if (flFarDist) { if (gBSPRenderer.m_pCvarRadialFog->value > 0 && gBSPRenderer.m_bRadialFogSupport && bView) { m_vCullBoxMins[0] = vOrigin[0] - flFarDist; m_vCullBoxMins[1] = vOrigin[1] - flFarDist; m_vCullBoxMins[2] = vOrigin[2] - flFarDist; m_vCullBoxMaxs[0] = vOrigin[0] + flFarDist; m_vCullBoxMaxs[1] = vOrigin[1] + flFarDist; m_vCullBoxMaxs[2] = vOrigin[2] + flFarDist; m_iFarClip = FARCLIP_RADIAL; } else { Q_vec3_t vFarPoint; VectorCopy(vVpn, vFarPoint); vFarPoint[0] *= flFarDist; vFarPoint[1] *= flFarDist; vFarPoint[2] *= flFarDist; VectorAdd(vOrigin, vFarPoint, vFarPoint); m_sFrustum[4].vNormal[0] = vVpn[0] * (-1); m_sFrustum[4].vNormal[1] = vVpn[1] * (-1); m_sFrustum[4].vNormal[2] = vVpn[2] * (-1); m_sFrustum[4].type = PLANE_ANYZ; m_sFrustum[4].flDist = DotProduct(vFarPoint, m_sFrustum[4].vNormal); m_sFrustum[4].signbits = Q_SignbitsForPlane(&m_sFrustum[4]); m_iFarClip = FARCLIP_DEPTH; } } }
/* SCR_CalcRefdef Must be called whenever vid changes Internal use only */ static void SCR_CalcRefdef (void) { vrect_t vrect; float size; int h; qboolean full = false; scr_fullupdate = 0; // force a background redraw vid.recalc_refdef = 0; // force the status bar to redraw Sbar_Changed (); //======================================== // bound viewsize Cvar_SetValue (scr_viewsize, bound (30, scr_viewsize->int_val, 120)); // bound field of view Cvar_SetValue (scr_fov, bound (10, scr_fov->value, 170)); if (scr_viewsize->int_val >= 120) sb_lines = 0; // no status bar at all else if (scr_viewsize->int_val >= 110) sb_lines = 24; // no inventory else sb_lines = 24 + 16 + 8; if (scr_viewsize->int_val >= 100) { full = true; size = 100.0; } else { size = scr_viewsize->int_val; } // intermission is always full screen if (cl.intermission) { full = true; size = 100.0; sb_lines = 0; } size /= 100.0; if (!cl_sbar->int_val && full) h = vid.height; else h = vid.height - sb_lines; r_refdef.vrect.width = vid.width * size + 0.5; if (r_refdef.vrect.width < 96) { size = 96.0 / r_refdef.vrect.width; r_refdef.vrect.width = 96; // min for icons } r_refdef.vrect.height = vid.height * size + 0.5; if (cl_sbar->int_val || !full) { if (r_refdef.vrect.height > vid.height - sb_lines) r_refdef.vrect.height = vid.height - sb_lines; } else if (r_refdef.vrect.height > vid.height) r_refdef.vrect.height = vid.height; r_refdef.vrect.x = (vid.width - r_refdef.vrect.width) / 2; if (full) r_refdef.vrect.y = 0; else r_refdef.vrect.y = (h - r_refdef.vrect.height) / 2; r_refdef.fov_x = scr_fov->int_val; r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); scr_vrect = r_refdef.vrect; // these calculations mirror those in R_Init() for r_refdef, but take no // account of water warping vrect.x = 0; vrect.y = 0; vrect.width = vid.width; vrect.height = vid.height; R_SetVrect (&vrect, &scr_vrect, sb_lines); // guard against going from one mode to another that's less than half the // vertical resolution if (scr_con_current > vid.height) scr_con_current = vid.height; // notify the refresh of the change R_ViewChanged (&vrect, sb_lines, vid.aspect); }
/* ================= SCR_CalcRefdef Must be called whenever vid changes Internal use only ================= */ static void SCR_CalcRefdef (void) { int h; float size; qboolean full = false; scr_fullupdate = 0; // force a background redraw vid.recalc_refdef = 0; // force the status bar to redraw Sbar_Changed (); //======================================== // bound viewsize if (scr_viewsize.value < 30) Cvar_SetValueByRef (&scr_viewsize, 30); if (scr_viewsize.value > 120) Cvar_SetValueByRef (&scr_viewsize, 120); // bound field of view if (scr_fov.value < 10) Cvar_SetValueByRef (&scr_fov, 10); if (scr_fov.value > 170) Cvar_SetValueByRef (&scr_fov, 170); // intermission is always full screen if (cl.intermission) size = 120; else size = scr_viewsize.value; if (size >= 120) sb_lines = 0; // no status bar at all else if (size >= 110) sb_lines = 24; // no inventory else sb_lines = 24+16+8; if (scr_viewsize.value >= 100.0) { full = true; size = 100.0; } else { size = scr_viewsize.value; } if (cl.intermission) { full = true; size = 100; sb_lines = 0; } size /= 100.0; if (cl_sbar.value >= 1.0) { h = vid.height - sb_lines; } else { // LordHavoc: always fullscreen rendering h = vid.height; } r_refdef.vrect.width = (int)(vid.width * size); if (r_refdef.vrect.width < 96) { size = 96.0 / r_refdef.vrect.width; r_refdef.vrect.width = 96; // min for icons } r_refdef.vrect.height = (int)(vid.height * size); if (cl_sbar.value >= 1.0) { // Baker 3.97: Only if we are displaying the sbar if (r_refdef.vrect.height > vid.height - sb_lines) r_refdef.vrect.height = vid.height - sb_lines; } if (r_refdef.vrect.height > (int) vid.height) r_refdef.vrect.height = vid.height; r_refdef.vrect.x = (vid.width - r_refdef.vrect.width)/2; if (full) r_refdef.vrect.y = 0; else r_refdef.vrect.y = (h - r_refdef.vrect.height)/2; //r_refdef.fov_x = scr_fov.value; //r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); if ((glwidth/glheight) > 1.34) { r_refdef.fov_y = CalcFov (scr_fov.value, r_refdef.vrect.height * (320.0f / 240.0f), r_refdef.vrect.height); r_refdef.fov_x = CalcFov (r_refdef.fov_y, vid.height, r_refdef.vrect.width); } else { r_refdef.fov_x = scr_fov.value; r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); } scr_vrect = r_refdef.vrect; }
void Menu_Draw ( menuframework_t *menu ) { char scratch[MAX_QPATH]; static int yaw; // int maxframe = 29; entity_t entity; int i; menucommon_t *item; refdef_t refdef; // Draw rotating Quake II Symbol memset( &refdef, 0, sizeof( refdef ) ); memset( &entity, 0, sizeof( entity ) ); refdef.x = 0; refdef.y = 0; refdef.width = viddef.width; refdef.height = viddef.height; refdef.fov_x = 35; refdef.fov_y = CalcFov( refdef.fov_x, refdef.width, refdef.height ); refdef.time = cls.realtime * 0.001; refdef.areabits = NULL; refdef.num_entities = 1; //refdef.lightstyles = 5; // Gentle Pulse refdef.lightstyles = 63; // Testing (FULLBRIGHT) refdef.rdflags = RDF_NOWORLDMODEL; refdef.blend[0] = 1.0; refdef.blend[1] = 1.0; refdef.blend[2] = 1.0; refdef.blend[3] = 0.0; refdef.dlights = NULL; refdef.num_dlights = 0; refdef.num_particles = 0; refdef.particles = NULL; VectorSet(refdef.viewangles, 1.0, 0.0, 0.0); VectorClear(refdef.vieworg); //if (!strcmp(vid_ref->string, "soft")) // Com_sprintf( scratch, sizeof( scratch ), "models/items/quaddama/tris.md2"); //else Com_sprintf( scratch, sizeof( scratch ), "models/MenuModel/quad.md2"); entity.model = re.RegisterModel( scratch ); //entity.Model_Type = 0; entity.flags = RF_MINLIGHT | RF_DEPTHHACK | RF_FULLBRIGHT | RF_GLOW | RF_NOSHADOW; entity.origin[0] = 80; entity.origin[1] = 0; entity.origin[2] = -18; // -18 compensates for the float height of the model VectorCopy( entity.origin, entity.oldorigin ); entity.frame = 0; entity.oldframe = 0; entity.backlerp = 0.0; entity.angles[1] = yaw++; if ( ++yaw > 360 ) yaw -= 360; refdef.entities = &entity; // Fog the scene //refdef.blend[0] = 0.55; //refdef.blend[1] = 0.55; //refdef.blend[2] = 0.55; //refdef.blend[3] = 0.55; if (cl_3dmenubg->value) { // Draw scene MenuRefdefActive = 1; re.RenderFrame( &refdef ); //Menu_DrawBackground("q2bg.tga"); } // Draw the menu version information if (cl_menustamp->value > 0) { /* 1 - Regular string 2 - Regular string plus drop shadow (green... not effective) 3 - All green string */ if (cl_menustamp->value == 1) { // Draw the text Menu_DrawString (viddef.width - (strlen(MENUSTAMP) * FONTSIZE) - (FONTSIZE * 3), viddef.height - FONTSIZE, MENUSTAMP); } else if (cl_menustamp->value == 2) { // Draw the drop shadow (we need black characters) DrawAltString (viddef.width - (strlen(MENUSTAMP) * FONTSIZE) - (FONTSIZE * 3) - 1, viddef.height - FONTSIZE, MENUSTAMP); // Draw the text Menu_DrawString (viddef.width - (strlen(MENUSTAMP) * FONTSIZE) - (FONTSIZE * 3), viddef.height - FONTSIZE - 1, MENUSTAMP); } else if (cl_menustamp->value == 3) { // Draw the text DrawAltString (viddef.width - (strlen(MENUSTAMP) * FONTSIZE) - (FONTSIZE * 3), viddef.height - FONTSIZE, MENUSTAMP); } } // Menu drawing prevention hack for main menu if ((menu->x == -1) && (menu->y == -1)) return; /* ** draw contents */ for ( i = 0; i < menu->nitems; i++ ) { switch ( ( ( menucommon_t * ) menu->items[i] )->type ) { case MTYPE_FIELD: Field_Draw( ( menufield_t * ) menu->items[i] ); break; case MTYPE_SLIDER: Slider_Draw( ( menuslider_t * ) menu->items[i] ); break; case MTYPE_LIST: MenuList_Draw( ( menulist_t * ) menu->items[i] ); break; case MTYPE_SPINCONTROL: SpinControl_Draw( ( menulist_t * ) menu->items[i] ); break; case MTYPE_ACTION: Action_Draw( ( menuaction_t * ) menu->items[i] ); break; case MTYPE_SEPARATOR: Separator_Draw( ( menuseparator_t * ) menu->items[i] ); break; } } item = Menu_ItemAtCursor( menu ); if ( item && item->cursordraw ) { item->cursordraw( item ); } else if ( menu->cursordraw ) { menu->cursordraw( menu ); } else if ( item && item->type != MTYPE_FIELD ) { if ( item->flags & QMF_LEFT_JUSTIFY ) { Draw_Char( menu->x + item->x - 24 + item->cursor_offset, menu->y + item->y, 12 + ( ( int ) ( Sys_Milliseconds()/250 ) & 1 ) ); } else { Draw_Char( menu->x + item->cursor_offset, menu->y + item->y, 12 + ( ( int ) ( Sys_Milliseconds()/250 ) & 1 ) ); } } if ( item ) { if ( item->statusbarfunc ) item->statusbarfunc( ( void * ) item ); else if ( item->statusbar ) Menu_DrawStatusBar( item->statusbar ); else Menu_DrawStatusBar( menu->statusbar ); } else { Menu_DrawStatusBar( menu->statusbar ); } }
void PlayerConfig_MenuDraw (void) { refdef_t refdef; float rx, ry, rw, rh; Menu_DrawBanner ("m_banner_plauer_setup"); // typo for image name is id's fault memset(&refdef, 0, sizeof(refdef)); rx = 0; ry = 0; rw = SCREEN_WIDTH; rh = SCREEN_HEIGHT; SCR_AdjustFrom640 (&rx, &ry, &rw, &rh, ALIGN_CENTER); refdef.x = rx; refdef.y = ry; refdef.width = rw; refdef.height = rh; refdef.fov_x = 50; refdef.fov_y = CalcFov (refdef.fov_x, refdef.width, refdef.height); refdef.time = cls.realtime*0.001; if ( s_pmi[s_player_model_box.curvalue].skindisplaynames ) { int yaw; int maxframe = 29; vec3_t modelOrg; // Psychopspaz's support for showing weapon model entity_t entity[2], *ent; refdef.num_entities = 0; refdef.entities = entity; yaw = anglemod(cl.time/10); VectorSet (modelOrg, 150, (hand->value==1)?25:-25, 0); // was 80, 0, 0 // Setup player model ent = &entity[0]; memset (&entity[0], 0, sizeof(entity[0])); // moved registration code to init and change only ent->model = playermodel; ent->skin = playerskin; ent->flags = RF_FULLBRIGHT|RF_NOSHADOW|RF_DEPTHHACK; if (hand->value == 1) ent->flags |= RF_MIRRORMODEL; ent->origin[0] = modelOrg[0]; ent->origin[1] = modelOrg[1]; ent->origin[2] = modelOrg[2]; VectorCopy( ent->origin, ent->oldorigin ); ent->frame = 0; ent->oldframe = 0; ent->backlerp = 0.0; ent->angles[1] = yaw; //if ( ++yaw > 360 ) // yaw -= 360; if (hand->value == 1) ent->angles[1] = 360 - ent->angles[1]; refdef.num_entities++; // Setup weapon model ent = &entity[1]; memset (&entity[1], 0, sizeof(entity[1])); // moved registration code to init and change only ent->model = weaponmodel; if (ent->model) { ent->skinnum = 0; ent->flags = RF_FULLBRIGHT|RF_NOSHADOW|RF_DEPTHHACK; if (hand->value == 1) ent->flags |= RF_MIRRORMODEL; ent->origin[0] = modelOrg[0]; ent->origin[1] = modelOrg[1]; ent->origin[2] = modelOrg[2]; VectorCopy( ent->origin, ent->oldorigin ); ent->frame = 0; ent->oldframe = 0; ent->backlerp = 0.0; ent->angles[1] = yaw; if (hand->value == 1) ent->angles[1] = 360 - ent->angles[1]; refdef.num_entities++; } refdef.areabits = 0; refdef.lightstyles = 0; refdef.rdflags = RDF_NOWORLDMODEL; Menu_Draw( &s_player_config_menu ); // skin selection preview PlayerConfig_DrawSkinSelection (); R_RenderFrame( &refdef ); } }
/* * CG_SetupViewDef */ static void CG_SetupViewDef( cg_viewdef_t *view, int type, bool flipped ) { memset( view, 0, sizeof( cg_viewdef_t ) ); // // VIEW SETTINGS // view->type = type; view->flipped = flipped; if( view->type == VIEWDEF_PLAYERVIEW ) { view->POVent = cg.frame.playerState.POVnum; view->draw2D = true; // set up third-person if( cgs.demoPlaying ) view->thirdperson = CG_DemoCam_GetThirdPerson(); else if( chaseCam.mode == CAM_THIRDPERSON ) view->thirdperson = true; else view->thirdperson = ( cg_thirdPerson->integer != 0 ); if( cg_entities[view->POVent].serverFrame != cg.frame.serverFrame ) view->thirdperson = false; // check for drawing gun if( !view->thirdperson && view->POVent > 0 && view->POVent <= gs.maxclients ) { if( ( cg_entities[view->POVent].serverFrame == cg.frame.serverFrame ) && ( cg_entities[view->POVent].current.weapon != 0 ) ) view->drawWeapon = ( cg_gun->integer != 0 ) && ( cg_gun_alpha->value > 0 ); } // check for chase cams if( !( cg.frame.playerState.pmove.pm_flags & PMF_NO_PREDICTION ) ) { if( (unsigned)view->POVent == cgs.playerNum + 1 ) { if( cg_predict->integer && !cgs.demoPlaying ) { view->playerPrediction = true; } } } } else if( view->type == VIEWDEF_CAMERA ) { CG_DemoCam_GetViewDef( view ); } else { module_Error( "CG_SetupView: Invalid view type %i\n", view->type ); } // // SETUP REFDEF FOR THE VIEW SETTINGS // if( view->type == VIEWDEF_PLAYERVIEW ) { int i; vec3_t viewoffset; if( view->playerPrediction ) { CG_PredictMovement(); // fixme: crouching is predicted now, but it looks very ugly VectorSet( viewoffset, 0.0f, 0.0f, cg.predictedPlayerState.viewheight ); for( i = 0; i < 3; i++ ) { view->origin[i] = cg.predictedPlayerState.pmove.origin[i] + viewoffset[i] - ( 1.0f - cg.lerpfrac ) * cg.predictionError[i]; view->angles[i] = cg.predictedPlayerState.viewangles[i]; } CG_ViewSmoothPredictedSteps( view->origin ); // smooth out stair climbing if( cg_viewBob->integer && !cg_thirdPerson->integer ) { view->origin[2] += CG_ViewSmoothFallKick() * 6.5f; } } else { cg.predictingTimeStamp = cg.time; cg.predictFrom = 0; // we don't run prediction, but we still set cg.predictedPlayerState with the interpolation CG_InterpolatePlayerState( &cg.predictedPlayerState ); VectorSet( viewoffset, 0.0f, 0.0f, cg.predictedPlayerState.viewheight ); VectorAdd( cg.predictedPlayerState.pmove.origin, viewoffset, view->origin ); VectorCopy( cg.predictedPlayerState.viewangles, view->angles ); } view->refdef.fov_x = cg.predictedPlayerState.fov; CG_CalcViewBob(); VectorCopy( cg.predictedPlayerState.pmove.velocity, view->velocity ); } else if( view->type == VIEWDEF_CAMERA ) { view->refdef.fov_x = CG_DemoCam_GetOrientation( view->origin, view->angles, view->velocity ); } Matrix3_FromAngles( view->angles, view->axis ); if( view->flipped ) VectorInverse( &view->axis[AXIS_RIGHT] ); // view rectangle size view->refdef.x = scr_vrect.x; view->refdef.y = scr_vrect.y; view->refdef.width = scr_vrect.width; view->refdef.height = scr_vrect.height; view->refdef.time = cg.time; view->refdef.areabits = cg.frame.areabits; view->refdef.scissor_x = scr_vrect.x; view->refdef.scissor_y = scr_vrect.y; view->refdef.scissor_width = scr_vrect.width; view->refdef.scissor_height = scr_vrect.height; view->refdef.fov_y = CalcFov( view->refdef.fov_x, view->refdef.width, view->refdef.height ); AdjustFov( &view->refdef.fov_x, &view->refdef.fov_y, view->refdef.width, view->refdef.height, false ); view->fracDistFOV = tan( view->refdef.fov_x * ( M_PI/180 ) * 0.5f ); view->refdef.minLight = 0.3f; if( view->thirdperson ) CG_ThirdPersonOffsetView( view ); if( !view->playerPrediction ) cg.predictedWeaponSwitch = 0; VectorCopy( cg.view.origin, view->refdef.vieworg ); Matrix3_Copy( cg.view.axis, view->refdef.viewaxis ); VectorInverse( &view->refdef.viewaxis[AXIS_RIGHT] ); view->refdef.colorCorrection = NULL; if( cg_colorCorrection->integer ) { int colorCorrection = GS_ColorCorrection(); if( ( colorCorrection > 0 ) && ( colorCorrection < MAX_IMAGES ) ) view->refdef.colorCorrection = cgs.imagePrecache[colorCorrection]; } }
/** * Must be called whenever vid changes * * Internal use only */ static void SCR_CalcRefdef(void) { float size, fov; int h; bool full = false; scr_fullupdate = 0; // force a background redraw vid.recalc_refdef = 0; //======================================== size = scr_viewsize.getFloat(); fov = scr_fov.getFloat(); // bound viewsize size = max(30, size); size = min(120, size); // bound field of view fov = max(10, fov); fov = min(170, fov); if (size != scr_viewsize.getFloat()) scr_viewsize.set(size); if (fov != scr_fov.getFloat()) scr_fov.set(fov); sb_lines = 24 + 16 + 8; if (size >= 100.0) { full = true; size = 100.0; } if (cl.intermission) { full = true; size = 100; sb_lines = 0; } size /= 100.0f; // TODO: remove sb_lines variable h = vid.height; // - sb_lines; r_refdef.vrect.width = vid.width * size; if (r_refdef.vrect.width < 96) { size = 96.0 / r_refdef.vrect.width; r_refdef.vrect.width = 96; // min for icons } r_refdef.vrect.height = (signed)vid.height * size; //if (r_refdef.vrect.height > (signed)vid.height - sb_lines) // r_refdef.vrect.height = (signed)vid.height - sb_lines; if (r_refdef.vrect.height > (signed)vid.height) r_refdef.vrect.height = vid.height; r_refdef.vrect.x = (vid.width - r_refdef.vrect.width) / 2; if (full) r_refdef.vrect.y = 0; else r_refdef.vrect.y = (h - r_refdef.vrect.height) / 2; r_refdef.fov_x = fov; r_refdef.fov_y = CalcFov(r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); scr_vrect = r_refdef.vrect; }
/* ================= SCR_CalcRefdef Must be called whenever vid changes Internal use only ================= */ void SCR_CalcRefdef (void) { float size; // bound viewsize if (scr_viewsize.value < 100) Cvar_Set (&scr_viewsize, "100"); if (scr_viewsize.value > 120) Cvar_Set (&scr_viewsize, "120"); // bound field of view if (scr_fov.value < 10) Cvar_Set (&scr_fov, "10"); if (scr_fov.value > (r_refdef2.allow_cheats ? 170 : 140)) Cvar_SetValue (&scr_fov, r_refdef2.allow_cheats ? 170 : 140); // intermission is always full screen if (cl.intermission) { size = 100.0; sb_drawinventory = sb_drawmain = false; } else { size = scr_viewsize.value; // decide how much of the status bar to draw if (size >= 120) { // no status bar at all sb_drawinventory = sb_drawmain = false; } else if (size >= 110) { // no inventory sb_drawinventory = false; sb_drawmain = true; } else { // full status bar sb_drawinventory = sb_drawmain = true; } if (size > 100.0) size = 100.0; } size /= 100.0; scr_vrect.width = (int)(vid.width * size + 1.0) & ~1; if (scr_vrect.width < 96) { size = 96.0 / scr_vrect.width; scr_vrect.width = 96; // min for icons } scr_vrect.height = (int)(vid.height * size + 1.0) & ~1; scr_vrect.x = (vid.width - scr_vrect.width)/2; scr_vrect.y = (vid.height - scr_vrect.height)/2; r_refdef2.vrect = scr_vrect; if (scr_fov_adapt.value) r_refdef2.fov_x = AdaptFovx(scr_fov.value, r_refdef2.vrect.width, r_refdef2.vrect.height); else r_refdef2.fov_x = scr_fov.value; r_refdef2.fov_x = clamp(10, r_refdef2.fov_x, 170); r_refdef2.fov_y = CalcFov (r_refdef2.fov_x, scr_vrect.width, scr_vrect.height); }
/* ================= SCR_CalcRefdef Must be called whenever vid changes Internal use only ================= */ static void SCR_CalcRefdef (void) { float size; int h; qboolean full = false; scr_fullupdate = 0; // force a background redraw vid.recalc_refdef = 0; r_refdef.fovscale_x = 1; r_refdef.fovscale_y = 1; // force the status bar to redraw Sbar_Changed (); //======================================== // bound viewsize if (scr_viewsize.value < 30) Cvar_Set ("viewsize","30"); if (scr_viewsize.value > 120) Cvar_Set ("viewsize","120"); // bound field of view if (scr_fov.value < 10) Cvar_Set ("fov","10"); if (scr_fov.value > 170) Cvar_Set ("fov","170"); // intermission is always full screen if (cl.intermission) size = 120; else size = scr_viewsize.value; /* Always draw status bar and inventory if (size >= 120) sb_lines = 0; // no status bar at all else if (size >= 110) sb_lines = 24; // no inventory else*/ sb_lines = 24+16+8; if (scr_viewsize.value >= 100.0) { full = true; size = 100.0; } else size = scr_viewsize.value; if (cl.intermission) { full = true; size = 100; sb_lines = 0; } size /= 100.0; h = vid.height;// - sb_lines; r_refdef.vrect.width = vid.width * size; if (r_refdef.vrect.width < 96) { size = 96.0 / r_refdef.vrect.width; r_refdef.vrect.width = 96; // min for icons } r_refdef.vrect.height = (signed)vid.height * size; //if (r_refdef.vrect.height > (signed)vid.height - sb_lines) // r_refdef.vrect.height = (signed)vid.height - sb_lines; if (r_refdef.vrect.height > (signed)vid.height) r_refdef.vrect.height = vid.height; r_refdef.vrect.x = (vid.width - r_refdef.vrect.width)/2; if (full) r_refdef.vrect.y = 0; else r_refdef.vrect.y = (h - r_refdef.vrect.height)/2; if (scr_fov.value * r_refdef.fovscale_x < 1 || scr_fov.value * r_refdef.fovscale_y > 179) { Con_Printf ("Invalid FOV: %f - resetting.", scr_fov.value); Cvar_SetValue ("fov", 90); } r_refdef.fov_x = scr_fov.value*r_refdef.fovscale_x; r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height*r_refdef.fovscale_y); //r_refdef.fov_y = (CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height)) * r_refdef.fovscale_y; scr_vrect = r_refdef.vrect; }
/* SCR_CalcRefdef Must be called whenever vid changes Internal use only */ static void SCR_CalcRefdef (void) { float size; int h; qboolean full = false; scr_fullupdate = 0; // force a background redraw vid.recalc_refdef = 0; // force the status bar to redraw Sbar_Changed (); //======================================== // bound viewsize Cvar_SetValue (scr_viewsize, bound (30, scr_viewsize->int_val, 120)); // bound field of view Cvar_SetValue (scr_fov, bound (10, scr_fov->value, 170)); if (scr_viewsize->int_val >= 120) sb_lines = 0; // no status bar at all else if (scr_viewsize->int_val >= 110) sb_lines = 24; // no inventory else sb_lines = 24 + 16 + 8; if (scr_viewsize->int_val >= 100) { full = true; size = 100.0; } else { size = scr_viewsize->int_val; } // intermission is always full screen if (cl.intermission) { full = true; size = 100.0; sb_lines = 0; } size /= 100.0; if (!cl_sbar->int_val && full) h = vid.height; else h = vid.height - sb_lines; r_refdef.vrect.width = vid.width * size + 0.5; if (r_refdef.vrect.width < 96) { size = 96.0 / r_refdef.vrect.width; r_refdef.vrect.width = 96; // min for icons } r_refdef.vrect.height = vid.height * size + 0.5; if (cl_sbar->int_val || !full) { if (r_refdef.vrect.height > vid.height - sb_lines) r_refdef.vrect.height = vid.height - sb_lines; } else if (r_refdef.vrect.height > vid.height) r_refdef.vrect.height = vid.height; r_refdef.vrect.x = (vid.width - r_refdef.vrect.width) / 2; if (full) r_refdef.vrect.y = 0; else r_refdef.vrect.y = (h - r_refdef.vrect.height) / 2; r_refdef.fov_x = scr_fov->int_val; r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); scr_vrect = r_refdef.vrect; }