/* ================ idGuiModel::EmitFullScreen Creates a view that covers the screen and emit the surfaces ================ */ void idGuiModel::EmitFullScreen( void ) { viewDef_t *viewDef; if( surfaces[0].numVerts == 0 ) { return; } viewDef = ( viewDef_t * )R_ClearedFrameAlloc( sizeof( *viewDef ) ); // for gui editor if( !tr.viewDef || !tr.viewDef->isEditor ) { viewDef->renderView.x = 0; viewDef->renderView.y = 0; viewDef->renderView.width = SCREEN_WIDTH; viewDef->renderView.height = SCREEN_HEIGHT; tr.RenderViewToViewport( &viewDef->renderView, &viewDef->viewport ); viewDef->scissor.x1 = 0; viewDef->scissor.y1 = 0; viewDef->scissor.x2 = viewDef->viewport.x2 - viewDef->viewport.x1; viewDef->scissor.y2 = viewDef->viewport.y2 - viewDef->viewport.y1; } else { viewDef->renderView.x = tr.viewDef->renderView.x; viewDef->renderView.y = tr.viewDef->renderView.y; viewDef->renderView.width = tr.viewDef->renderView.width; viewDef->renderView.height = tr.viewDef->renderView.height; viewDef->viewport.x1 = tr.viewDef->renderView.x; viewDef->viewport.x2 = tr.viewDef->renderView.x + tr.viewDef->renderView.width; viewDef->viewport.y1 = tr.viewDef->renderView.y; viewDef->viewport.y2 = tr.viewDef->renderView.y + tr.viewDef->renderView.height; viewDef->scissor.x1 = tr.viewDef->scissor.x1; viewDef->scissor.y1 = tr.viewDef->scissor.y1; viewDef->scissor.x2 = tr.viewDef->scissor.x2; viewDef->scissor.y2 = tr.viewDef->scissor.y2; } viewDef->floatTime = tr.frameShaderTime; // glOrtho( 0, 640, 480, 0, 0, 1 ); // always assume 640x480 virtual coordinates viewDef->projectionMatrix[0] = 2.0f / 640.0f; viewDef->projectionMatrix[5] = -2.0f / 480.0f; viewDef->projectionMatrix[10] = -2.0f / 1.0f; viewDef->projectionMatrix[12] = -1.0f; viewDef->projectionMatrix[13] = 1.0f; viewDef->projectionMatrix[14] = -1.0f; viewDef->projectionMatrix[15] = 1.0f; viewDef->worldSpace.modelViewMatrix[0] = 1.0f; viewDef->worldSpace.modelViewMatrix[5] = 1.0f; viewDef->worldSpace.modelViewMatrix[10] = 1.0f; viewDef->worldSpace.modelViewMatrix[15] = 1.0f; viewDef->maxDrawSurfs = surfaces.Num(); viewDef->drawSurfs = ( drawSurf_t ** )R_FrameAlloc( viewDef->maxDrawSurfs * sizeof( viewDef->drawSurfs[0] ) ); viewDef->numDrawSurfs = 0; viewDef_t *oldViewDef = tr.viewDef; tr.viewDef = viewDef; // add the surfaces to this view for( int i = 0 ; i < surfaces.Num() ; i++ ) { EmitSurface( &surfaces[i], viewDef->worldSpace.modelMatrix, viewDef->worldSpace.modelViewMatrix, false ); } tr.viewDef = oldViewDef; // add the command to draw this view R_AddDrawViewCmd( viewDef ); }
/* ================ R_RenderView A view may be either the actual camera view, a mirror / remote location, or a 3D view on a gui surface. Parms will typically be allocated with R_FrameAlloc ================ */ void R_RenderView( viewDef_t *parms ) { viewDef_t *oldView; if ( parms->renderView.width <= 0 || parms->renderView.height <= 0 ) { return; } tr.viewCount++; // save view in case we are a subview oldView = tr.viewDef; tr.viewDef = parms; tr.sortOffset = 0; // set the matrix for world space to eye space R_SetViewMatrix( tr.viewDef ); // the four sides of the view frustum are needed // for culling and portal visibility R_SetupViewFrustum(); // we need to set the projection matrix before doing // portal-to-screen scissor box calculations R_SetupProjection(); // identify all the visible portalAreas, and the entityDefs and // lightDefs that are in them and pass culling. static_cast<idRenderWorldLocal *>(parms->renderWorld)->FindViewLightsAndEntities(); // constrain the view frustum to the view lights and entities R_ConstrainViewFrustum(); // make sure that interactions exist for all light / entity combinations // that are visible // add any pre-generated light shadows, and calculate the light shader values R_AddLightSurfaces(); // adds ambient surfaces and create any necessary interaction surfaces to add to the light // lists R_AddModelSurfaces(); // any viewLight that didn't have visible surfaces can have it's shadows removed R_RemoveUnecessaryViewLights(); // sort all the ambient surfaces for translucency ordering R_SortDrawSurfs(); // generate any subviews (mirrors, cameras, etc) before adding this view if ( R_GenerateSubViews() ) { // if we are debugging subviews, allow the skipping of the // main view draw if ( r_subviewOnly.GetBool() ) { return; } } // write everything needed to the demo file if ( session->writeDemo ) { static_cast<idRenderWorldLocal *>(parms->renderWorld)->WriteVisibleDefs( tr.viewDef ); } // add the rendering commands for this viewDef R_AddDrawViewCmd( parms ); // restore view in case we are a subview tr.viewDef = oldView; }
/* ================ R_RenderView A view may be either the actual camera view, a mirror / remote location, or a 3D view on a gui surface. Parms will typically be allocated with R_FrameAlloc ================ */ void R_RenderView( viewDef_t *parms ) { // save view in case we are a subview viewDef_t * oldView = tr.viewDef; tr.viewDef = parms; // setup the matrix for world space to eye space R_SetupViewMatrix( tr.viewDef ); // we need to set the projection matrix before doing // portal-to-screen scissor calculations R_SetupProjectionMatrix( tr.viewDef ); // setup render matrices for faster culling idRenderMatrix::Transpose( *(idRenderMatrix *)tr.viewDef->projectionMatrix, tr.viewDef->projectionRenderMatrix ); idRenderMatrix viewRenderMatrix; idRenderMatrix::Transpose( *(idRenderMatrix *)tr.viewDef->worldSpace.modelViewMatrix, viewRenderMatrix ); idRenderMatrix::Multiply( tr.viewDef->projectionRenderMatrix, viewRenderMatrix, tr.viewDef->worldSpace.mvp ); // the planes of the view frustum are needed for portal visibility culling idRenderMatrix::GetFrustumPlanes( tr.viewDef->frustum, tr.viewDef->worldSpace.mvp, false, true ); // the DOOM 3 frustum planes point outside the frustum for ( int i = 0; i < 6; i++ ) { tr.viewDef->frustum[i] = - tr.viewDef->frustum[i]; } // remove the Z-near to avoid portals from being near clipped tr.viewDef->frustum[4][3] -= r_znear.GetFloat(); // identify all the visible portal areas, and create view lights and view entities // for all the the entityDefs and lightDefs that are in the visible portal areas static_cast<idRenderWorldLocal *>(parms->renderWorld)->FindViewLightsAndEntities(); // wait for any shadow volume jobs from the previous frame to finish tr.frontEndJobList->Wait(); // make sure that interactions exist for all light / entity combinations that are visible // add any pre-generated light shadows, and calculate the light shader values R_AddLights(); // adds ambient surfaces and create any necessary interaction surfaces to add to the light lists R_AddModels(); // build up the GUIs on world surfaces R_AddInGameGuis( tr.viewDef->drawSurfs, tr.viewDef->numDrawSurfs ); // any viewLight that didn't have visible surfaces can have it's shadows removed R_OptimizeViewLightsList(); // sort all the ambient surfaces for translucency ordering R_SortDrawSurfs( tr.viewDef->drawSurfs, tr.viewDef->numDrawSurfs ); // generate any subviews (mirrors, cameras, etc) before adding this view if ( R_GenerateSubViews( tr.viewDef->drawSurfs, tr.viewDef->numDrawSurfs ) ) { // if we are debugging subviews, allow the skipping of the main view draw if ( r_subviewOnly.GetBool() ) { return; } } // write everything needed to the demo file if ( common->WriteDemo() ) { static_cast<idRenderWorldLocal *>(parms->renderWorld)->WriteVisibleDefs( tr.viewDef ); } // add the rendering commands for this viewDef R_AddDrawViewCmd( parms, false ); // restore view in case we are a subview tr.viewDef = oldView; }
/* ================ idGuiModel::EmitFullScreen Creates a view that covers the screen and emit the surfaces ================ */ void idGuiModel::EmitFullScreen() { if( surfaces[0].numIndexes == 0 ) { return; } SCOPED_PROFILE_EVENT( "Gui::EmitFullScreen" ); viewDef_t* viewDef = ( viewDef_t* )R_ClearedFrameAlloc( sizeof( *viewDef ), FRAME_ALLOC_VIEW_DEF ); viewDef->is2Dgui = true; tr.GetCroppedViewport( &viewDef->viewport ); bool stereoEnabled = ( renderSystem->GetStereo3DMode() != STEREO3D_OFF ); if( stereoEnabled ) { const float screenSeparation = GetScreenSeparationForGuis(); // this will be negated on the alternate eyes, both rendered each frame viewDef->renderView.stereoScreenSeparation = screenSeparation; extern idCVar stereoRender_swapEyes; viewDef->renderView.viewEyeBuffer = 0; // render to both buffers if( stereoRender_swapEyes.GetBool() ) { viewDef->renderView.stereoScreenSeparation = -screenSeparation; } } viewDef->scissor.x1 = 0; viewDef->scissor.y1 = 0; viewDef->scissor.x2 = viewDef->viewport.x2 - viewDef->viewport.x1; viewDef->scissor.y2 = viewDef->viewport.y2 - viewDef->viewport.y1; viewDef->projectionMatrix[0 * 4 + 0] = 2.0f / renderSystem->GetVirtualWidth(); viewDef->projectionMatrix[0 * 4 + 1] = 0.0f; viewDef->projectionMatrix[0 * 4 + 2] = 0.0f; viewDef->projectionMatrix[0 * 4 + 3] = 0.0f; viewDef->projectionMatrix[1 * 4 + 0] = 0.0f; viewDef->projectionMatrix[1 * 4 + 1] = -2.0f / renderSystem->GetVirtualHeight(); viewDef->projectionMatrix[1 * 4 + 2] = 0.0f; viewDef->projectionMatrix[1 * 4 + 3] = 0.0f; viewDef->projectionMatrix[2 * 4 + 0] = 0.0f; viewDef->projectionMatrix[2 * 4 + 1] = 0.0f; viewDef->projectionMatrix[2 * 4 + 2] = -2.0f; viewDef->projectionMatrix[2 * 4 + 3] = 0.0f; viewDef->projectionMatrix[3 * 4 + 0] = -1.0f; viewDef->projectionMatrix[3 * 4 + 1] = 1.0f; viewDef->projectionMatrix[3 * 4 + 2] = -1.0f; viewDef->projectionMatrix[3 * 4 + 3] = 1.0f; // make a tech5 renderMatrix for faster culling idRenderMatrix::Transpose( *( idRenderMatrix* )viewDef->projectionMatrix, viewDef->projectionRenderMatrix ); viewDef->worldSpace.modelMatrix[0 * 4 + 0] = 1.0f; viewDef->worldSpace.modelMatrix[1 * 4 + 1] = 1.0f; viewDef->worldSpace.modelMatrix[2 * 4 + 2] = 1.0f; viewDef->worldSpace.modelMatrix[3 * 4 + 3] = 1.0f; viewDef->worldSpace.modelViewMatrix[0 * 4 + 0] = 1.0f; viewDef->worldSpace.modelViewMatrix[1 * 4 + 1] = 1.0f; viewDef->worldSpace.modelViewMatrix[2 * 4 + 2] = 1.0f; viewDef->worldSpace.modelViewMatrix[3 * 4 + 3] = 1.0f; viewDef->maxDrawSurfs = surfaces.Num(); viewDef->drawSurfs = ( drawSurf_t** )R_FrameAlloc( viewDef->maxDrawSurfs * sizeof( viewDef->drawSurfs[0] ), FRAME_ALLOC_DRAW_SURFACE_POINTER ); viewDef->numDrawSurfs = 0; #if 1 // RB: give renderView the current time to calculate 2D shader effects int shaderTime = tr.frameShaderTime * 1000; //Sys_Milliseconds(); viewDef->renderView.time[0] = shaderTime; viewDef->renderView.time[1] = shaderTime; // RB end #endif viewDef_t* oldViewDef = tr.viewDef; tr.viewDef = viewDef; EmitSurfaces( viewDef->worldSpace.modelMatrix, viewDef->worldSpace.modelViewMatrix, false /* depthHack */ , stereoEnabled /* stereoDepthSort */, false /* link as entity */ ); tr.viewDef = oldViewDef; // add the command to draw this view R_AddDrawViewCmd( viewDef, true ); }