/* * R_RenderScene */ void R_RenderScene( const refdef_t *fd ) { int fbFlags = 0; if( r_norefresh->integer ) return; R_Set2DMode( qfalse ); RB_SetTime( fd->time ); if( !( fd->rdflags & RDF_NOWORLDMODEL ) ) rsc.refdef = *fd; rn.refdef = *fd; if( !rn.refdef.minLight ) { rn.refdef.minLight = 0.1f; } if( !rsh.screenWeaponTexture || rn.refdef.weaponAlpha == 1 ) { rn.refdef.rdflags &= ~RDF_WEAPONALPHA; } fd = &rn.refdef; rn.renderFlags = RF_NONE; rn.farClip = R_DefaultFarClip(); rn.clipFlags = 15; if( rsh.worldModel && !( fd->rdflags & RDF_NOWORLDMODEL ) && rsh.worldBrushModel->globalfog ) rn.clipFlags |= 16; rn.meshlist = &r_worldlist; rn.shadowBits = 0; rn.dlightBits = 0; rn.shadowGroup = NULL; fbFlags = 0; rn.fbColorAttachment = rn.fbDepthAttachment = NULL; if( !( fd->rdflags & RDF_NOWORLDMODEL ) ) { // soft particles require GL_EXT_framebuffer_blit as we need to copy the depth buffer // attachment into a texture we're going to read from in GLSL shader if( r_soft_particles->integer && glConfig.ext.framebuffer_blit && ( rsh.screenTexture != NULL ) ) { rn.fbColorAttachment = rsh.screenTexture; rn.fbDepthAttachment = rsh.screenDepthTexture; rn.renderFlags |= RF_SOFT_PARTICLES; fbFlags |= 1; } if( ( fd->rdflags & RDF_WEAPONALPHA ) && ( rsh.screenWeaponTexture != NULL ) ) { fbFlags |= 2; } if( r_fxaa->integer && ( rsh.screenFxaaCopy != NULL ) ) { if( !rn.fbColorAttachment ) { rn.fbColorAttachment = rsh.screenFxaaCopy; } fbFlags |= 4; } } // adjust field of view for widescreen if( glConfig.wideScreen && !( fd->rdflags & RDF_NOFOVADJUSTMENT ) ) AdjustFov( &rn.refdef.fov_x, &rn.refdef.fov_y, glConfig.width, glConfig.height, qfalse ); // clip new scissor region to the one currently set Vector4Set( rn.scissor, fd->scissor_x, fd->scissor_y, fd->scissor_width, fd->scissor_height ); Vector4Set( rn.viewport, fd->x, fd->y, fd->width, fd->height ); VectorCopy( fd->vieworg, rn.pvsOrigin ); VectorCopy( fd->vieworg, rn.lodOrigin ); if( gl_finish->integer && !( fd->rdflags & RDF_NOWORLDMODEL ) ) qglFinish(); if( fbFlags & 2 ) { // clear the framebuffer we're going to render the weapon model to // set the alpha to 0, visible parts of the model will overwrite that, // creating proper alpha mask R_BindFrameBufferObject( rsh.screenWeaponTexture->fbo ); RB_Clear( GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT, 0, 0, 0, 0 ); } R_BindFrameBufferObject( 0 ); R_BuildShadowGroups(); R_RenderView( fd ); R_RenderDebugSurface( fd ); R_RenderDebugBounds(); R_BindFrameBufferObject( 0 ); R_Set2DMode( qtrue ); // blit and blend framebuffers in proper order if( fbFlags & 1 ) { // copy to FXAA or default framebuffer R_BlitTextureToScrFbo( fd, rn.fbColorAttachment, fbFlags & 4 ? rsh.screenFxaaCopy->fbo : 0, GLSL_PROGRAM_TYPE_NONE, colorWhite, 0 ); } if( fbFlags & 2 ) { vec4_t color = { 1, 1, 1, 1 }; color[3] = fd->weaponAlpha; // blend to FXAA or default framebuffer R_BlitTextureToScrFbo( fd, rsh.screenWeaponTexture, fbFlags & 4 ? rsh.screenFxaaCopy->fbo : 0, GLSL_PROGRAM_TYPE_NONE, color, GLSTATE_SRCBLEND_SRC_ALPHA|GLSTATE_DSTBLEND_ONE_MINUS_SRC_ALPHA ); } // blit FXAA to default framebuffer if( fbFlags & 4 ) { // blend to FXAA or default framebuffer R_BlitTextureToScrFbo( fd, rsh.screenFxaaCopy, 0, GLSL_PROGRAM_TYPE_FXAA, colorWhite, 0 ); } }
/* * 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 ); }
/* * 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]; } }