From 1a6998781b1d81679a6f51436f6f98e5b2094a47 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Mon, 5 Apr 2021 04:11:25 +0200 Subject: [PATCH] Make r_locksurfaces kinda work refs #357 --- neo/renderer/RenderSystem.cpp | 39 ++++++++++++++++++++--- neo/renderer/RenderWorld.cpp | 40 +++++++++++++++++++++++- neo/renderer/tr_backend.cpp | 2 ++ neo/renderer/tr_local.h | 7 +++-- neo/renderer/tr_main.cpp | 56 +++++++++++++++++---------------- neo/renderer/tr_render.cpp | 58 +++++++++++++++++++++++++++++------ 6 files changed, 158 insertions(+), 44 deletions(-) diff --git a/neo/renderer/RenderSystem.cpp b/neo/renderer/RenderSystem.cpp index 08414a3a..5d87d6ab 100644 --- a/neo/renderer/RenderSystem.cpp +++ b/neo/renderer/RenderSystem.cpp @@ -150,9 +150,10 @@ static void R_IssueRenderCommands( void ) { // r_skipRender is usually more usefull, because it will still // draw 2D graphics if ( !r_skipBackEnd.GetBool() ) { - RB_ExecuteBackEndCommands( frameData->cmdHead ); + RB_ExecuteBackEndCommands( frameData->cmdHead ); // XXX: frameData must contain all the draw commands! } + //if ( ! r_lockSurfaces.GetBool() ) R_ClearCommandChain(); } @@ -213,17 +214,26 @@ This is the main 3D rendering command. A single scene may have multiple views if a mirror, portal, or dynamic texture is present. ============= */ -void R_AddDrawViewCmd( viewDef_t *parms ) { +void R_AddDrawViewCmd( viewDef_t *parms, bool isMain ) { drawSurfsCommand_t *cmd; cmd = (drawSurfsCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) ); cmd->commandId = RC_DRAW_VIEW; + if(isMain && r_lockSurfaces.GetBool()) + { + //parms = tr.lockSurfacesRealViewDef; + } cmd->viewDef = parms; - if ( parms->viewEntitys ) { + //if ( parms->viewEntitys ) { + if ( isMain ) { // save the command for r_lockSurfaces debugging tr.lockSurfacesCmd = *cmd; + if(!r_lockSurfaces.GetBool()) { + //tr.lockSurfacesRenderView = parms->renderView; + //tr.lockSurfacesViewDef = *parms; + } } tr.pc.c_numViews++; @@ -251,12 +261,28 @@ matricies have been changed. This allow the culling tightness to be evaluated interactively. ====================== */ + +void R_SetupViewFrustum( void ); +void R_SetupProjection( viewDef_t * viewDef ); + void R_LockSurfaceScene( viewDef_t *parms ) { drawSurfsCommand_t *cmd; viewEntity_t *vModel; + viewDef_t* oldView = tr.viewDef; + tr.viewDef = tr.lockSurfacesCmd.viewDef; + // set the matrix for world space to eye space R_SetViewMatrix( parms ); + + // 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(tr.viewDef); + tr.lockSurfacesCmd.viewDef->worldSpace = parms->worldSpace; // update the view origin and axis, and all @@ -270,6 +296,9 @@ void R_LockSurfaceScene( viewDef_t *parms ) { // add the stored off surface commands again cmd = (drawSurfsCommand_t *)R_GetCommandBuffer( sizeof( *cmd ) ); *cmd = tr.lockSurfacesCmd; + //cmd->viewDef = parms; + + tr.viewDef = oldView; } /* @@ -715,10 +744,12 @@ void idRenderSystemLocal::EndFrame( int *frontEndMsec, int *backEndMsec ) { // use the other buffers next frame, because another CPU // may still be rendering into the current buffers + R_ToggleSmpFrame(); // we can now release the vertexes used this frame - vertexCache.EndFrame(); + //if (! r_lockSurfaces.GetBool() ) + vertexCache.EndFrame(); if ( session->writeDemo ) { session->writeDemo->WriteInt( DS_RENDER ); diff --git a/neo/renderer/RenderWorld.cpp b/neo/renderer/RenderWorld.cpp index 227c96d2..24d8ee29 100644 --- a/neo/renderer/RenderWorld.cpp +++ b/neo/renderer/RenderWorld.cpp @@ -691,6 +691,12 @@ void idRenderWorldLocal::RenderScene( const renderView_t *renderView ) { return; } + const renderView_t *renderViewReal = renderView; + + // if ( r_lockSurfaces.GetBool() ) { + // renderView = &tr.lockSurfacesViewDef.renderView; + // } + if ( renderView->fov_x <= 0 || renderView->fov_y <= 0 ) { common->Error( "idRenderWorld::RenderScene: bad FOVs: %f, %f", renderView->fov_x, renderView->fov_y ); } @@ -741,21 +747,53 @@ void idRenderWorldLocal::RenderScene( const renderView_t *renderView ) { parms->isMirror = true; } + /* if ( r_lockSurfaces.GetBool() ) { R_LockSurfaceScene( parms ); + //frameData->cmdHead return; } + */ + + if ( r_lockSurfaces.GetBool() ) { + tr.lockSurfacesRealViewDef = *parms; + +/* + viewDef_t* lockedParms = &tr.lockSurfacesViewDef; + parms->renderView = lockedParms->renderView; + parms->projectionMatrix = lockedParms->projectionMatrix; + parms->worldSpace = lockedParms->worldSpace; + parms->initialViewAreaOrigin = lockedParms->initialViewAreaOrigin; +*/ + const viewDef_t* origParms = &tr.lockSurfacesRealViewDef; + *parms = tr.lockSurfacesViewDef; + parms->renderWorld = origParms->renderWorld; + parms->floatTime = origParms->floatTime; + parms->drawSurfs = origParms->drawSurfs; // should be NULL I think + parms->numDrawSurfs = origParms->numDrawSurfs; + parms->maxDrawSurfs = origParms->maxDrawSurfs; + parms->viewLights = origParms->viewLights; + parms->viewEntitys = origParms->viewEntitys; + parms->connectedAreas = origParms->connectedAreas; + + } else { + tr.lockSurfacesViewDef = *parms; + } + // save this world for use by some console commands tr.primaryWorld = this; tr.primaryRenderView = *renderView; tr.primaryView = parms; + + // rendering this view may cause other views to be rendered // for mirrors / portals / shadows / environment maps // this will also cause any necessary entities and lights to be // updated to the demo file - R_RenderView( parms ); + //if ( !r_lockSurfaces.GetBool() ) + R_RenderView( parms, true ); // now write delete commands for any modified-but-not-visible entities, and // add the renderView command to the demo diff --git a/neo/renderer/tr_backend.cpp b/neo/renderer/tr_backend.cpp index 18224a00..a82a2e25 100644 --- a/neo/renderer/tr_backend.cpp +++ b/neo/renderer/tr_backend.cpp @@ -438,6 +438,8 @@ static void RB_SetBuffer( const void *data ) { qglDrawBuffer( cmd->buffer ); + //return; // XXX + // clear screen for debugging // automatically enable this with several other debug tools // that might leave unrendered portions of the screen diff --git a/neo/renderer/tr_local.h b/neo/renderer/tr_local.h index f2a4d659..bbc29bb1 100644 --- a/neo/renderer/tr_local.h +++ b/neo/renderer/tr_local.h @@ -550,7 +550,7 @@ extern frameData_t *frameData; void R_LockSurfaceScene( viewDef_t *parms ); void R_ClearCommandChain( void ); -void R_AddDrawViewCmd( viewDef_t *parms ); +void R_AddDrawViewCmd( viewDef_t *parms, bool isMain=false ); void R_ReloadGuis_f( const idCmdArgs &args ); void R_ListGuis_f( const idCmdArgs &args ); @@ -785,6 +785,9 @@ public: performanceCounters_t pc; // performance counters drawSurfsCommand_t lockSurfacesCmd; // use this when r_lockSurfaces = 1 + //renderView_t lockSurfacesRenderView; + viewDef_t lockSurfacesViewDef; // of locked position/view + viewDef_t lockSurfacesRealViewDef; // of actual player position viewEntity_t identitySpace; // can use if we don't know viewDef->worldSpace is valid int stencilIncr, stencilDecr; // GL_INCR / INCR_WRAP_EXT, GL_DECR / GL_DECR_EXT @@ -1117,7 +1120,7 @@ MAIN ==================================================================== */ -void R_RenderView( viewDef_t *parms ); +void R_RenderView( viewDef_t *parms, bool isMain = false ); // performs radius cull first, then corner cull bool R_CullLocalBox( const idBounds &bounds, const float modelMatrix[16], int numPlanes, const idPlane *planes ); diff --git a/neo/renderer/tr_main.cpp b/neo/renderer/tr_main.cpp index 3f3194eb..ef91cf2b 100644 --- a/neo/renderer/tr_main.cpp +++ b/neo/renderer/tr_main.cpp @@ -185,7 +185,7 @@ R_ToggleSmpFrame */ void R_ToggleSmpFrame( void ) { if ( r_lockSurfaces.GetBool() ) { - return; + //return; } R_FreeDeferredTriSurfs( frameData ); @@ -894,7 +894,7 @@ R_SetupProjection This uses the "infinite far z" trick =============== */ -void R_SetupProjection( void ) { +void R_SetupProjection( viewDef_t * viewDef ) { float xmin, xmax, ymin, ymax; float width, height; float zNear; @@ -915,48 +915,48 @@ void R_SetupProjection( void ) { // set up projection matrix // zNear = r_znear.GetFloat(); - if ( tr.viewDef->renderView.cramZNear ) { + if ( viewDef->renderView.cramZNear ) { zNear *= 0.25; } - ymax = zNear * tan( tr.viewDef->renderView.fov_y * idMath::PI / 360.0f ); + ymax = zNear * tan( viewDef->renderView.fov_y * idMath::PI / 360.0f ); ymin = -ymax; - xmax = zNear * tan( tr.viewDef->renderView.fov_x * idMath::PI / 360.0f ); + xmax = zNear * tan( viewDef->renderView.fov_x * idMath::PI / 360.0f ); xmin = -xmax; width = xmax - xmin; height = ymax - ymin; - jitterx = jitterx * width / ( tr.viewDef->viewport.x2 - tr.viewDef->viewport.x1 + 1 ); + jitterx = jitterx * width / ( viewDef->viewport.x2 - viewDef->viewport.x1 + 1 ); xmin += jitterx; xmax += jitterx; - jittery = jittery * height / ( tr.viewDef->viewport.y2 - tr.viewDef->viewport.y1 + 1 ); + jittery = jittery * height / ( viewDef->viewport.y2 - viewDef->viewport.y1 + 1 ); ymin += jittery; ymax += jittery; - tr.viewDef->projectionMatrix[0] = 2 * zNear / width; - tr.viewDef->projectionMatrix[4] = 0; - tr.viewDef->projectionMatrix[8] = ( xmax + xmin ) / width; // normally 0 - tr.viewDef->projectionMatrix[12] = 0; + viewDef->projectionMatrix[0] = 2 * zNear / width; + viewDef->projectionMatrix[4] = 0; + viewDef->projectionMatrix[8] = ( xmax + xmin ) / width; // normally 0 + viewDef->projectionMatrix[12] = 0; - tr.viewDef->projectionMatrix[1] = 0; - tr.viewDef->projectionMatrix[5] = 2 * zNear / height; - tr.viewDef->projectionMatrix[9] = ( ymax + ymin ) / height; // normally 0 - tr.viewDef->projectionMatrix[13] = 0; + viewDef->projectionMatrix[1] = 0; + viewDef->projectionMatrix[5] = 2 * zNear / height; + viewDef->projectionMatrix[9] = ( ymax + ymin ) / height; // normally 0 + viewDef->projectionMatrix[13] = 0; // this is the far-plane-at-infinity formulation, and // crunches the Z range slightly so w=0 vertexes do not // rasterize right at the wraparound point - tr.viewDef->projectionMatrix[2] = 0; - tr.viewDef->projectionMatrix[6] = 0; - tr.viewDef->projectionMatrix[10] = -0.999f; - tr.viewDef->projectionMatrix[14] = -2.0f * zNear; + viewDef->projectionMatrix[2] = 0; + viewDef->projectionMatrix[6] = 0; + viewDef->projectionMatrix[10] = -0.999f; + viewDef->projectionMatrix[14] = -2.0f * zNear; - tr.viewDef->projectionMatrix[3] = 0; - tr.viewDef->projectionMatrix[7] = 0; - tr.viewDef->projectionMatrix[11] = -1; - tr.viewDef->projectionMatrix[15] = 0; + viewDef->projectionMatrix[3] = 0; + viewDef->projectionMatrix[7] = 0; + viewDef->projectionMatrix[11] = -1; + viewDef->projectionMatrix[15] = 0; } /* @@ -967,7 +967,8 @@ Setup that culling frustum planes for the current view FIXME: derive from modelview matrix times projection matrix ================= */ -static void R_SetupViewFrustum( void ) { +//static +void R_SetupViewFrustum( void ) { int i; float xs, xc; float ang; @@ -1094,7 +1095,7 @@ 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 ) { +void R_RenderView( viewDef_t *parms, bool isMain ) { viewDef_t *oldView; if ( parms->renderView.width <= 0 || parms->renderView.height <= 0 ) { @@ -1119,7 +1120,7 @@ void R_RenderView( viewDef_t *parms ) { // we need to set the projection matrix before doing // portal-to-screen scissor box calculations - R_SetupProjection(); + R_SetupProjection( tr.viewDef ); // identify all the visible portalAreas, and the entityDefs and // lightDefs that are in them and pass culling. @@ -1158,7 +1159,8 @@ void R_RenderView( viewDef_t *parms ) { } // add the rendering commands for this viewDef - R_AddDrawViewCmd( parms ); + //if(!r_lockSurfaces.GetBool() || !isMain) + R_AddDrawViewCmd( parms, isMain ); // restore view in case we are a subview tr.viewDef = oldView; diff --git a/neo/renderer/tr_render.cpp b/neo/renderer/tr_render.cpp index 518cd051..90d74531 100644 --- a/neo/renderer/tr_render.cpp +++ b/neo/renderer/tr_render.cpp @@ -554,23 +554,26 @@ to actually render the visible surfaces for this view ================= */ void RB_BeginDrawingView (void) { + + const viewDef_t* viewDef = backEnd.viewDef; + // set the modelview matrix for the viewer qglMatrixMode(GL_PROJECTION); - qglLoadMatrixf( backEnd.viewDef->projectionMatrix ); + qglLoadMatrixf( viewDef->projectionMatrix ); qglMatrixMode(GL_MODELVIEW); // set the window clipping - qglViewport( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1, - tr.viewportOffset[1] + backEnd.viewDef->viewport.y1, - backEnd.viewDef->viewport.x2 + 1 - backEnd.viewDef->viewport.x1, - backEnd.viewDef->viewport.y2 + 1 - backEnd.viewDef->viewport.y1 ); + qglViewport( tr.viewportOffset[0] + viewDef->viewport.x1, + tr.viewportOffset[1] + viewDef->viewport.y1, + viewDef->viewport.x2 + 1 - viewDef->viewport.x1, + viewDef->viewport.y2 + 1 - viewDef->viewport.y1 ); // the scissor may be smaller than the viewport for subviews - qglScissor( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1 + backEnd.viewDef->scissor.x1, - tr.viewportOffset[1] + backEnd.viewDef->viewport.y1 + backEnd.viewDef->scissor.y1, - backEnd.viewDef->scissor.x2 + 1 - backEnd.viewDef->scissor.x1, - backEnd.viewDef->scissor.y2 + 1 - backEnd.viewDef->scissor.y1 ); - backEnd.currentScissor = backEnd.viewDef->scissor; + qglScissor( tr.viewportOffset[0] + viewDef->viewport.x1 + viewDef->scissor.x1, + tr.viewportOffset[1] + viewDef->viewport.y1 + viewDef->scissor.y1, + viewDef->scissor.x2 + 1 - viewDef->scissor.x1, + viewDef->scissor.y2 + 1 - viewDef->scissor.y1 ); + backEnd.currentScissor = viewDef->scissor; // ensures that depth writes are enabled for the depth clear GL_State( GLS_DEFAULT ); @@ -847,11 +850,46 @@ void RB_CreateSingleDrawInteractions( const drawSurf_t *surf, void (*DrawInterac RB_DrawView ============= */ +extern void R_SetupProjection( viewDef_t * viewDef ); void RB_DrawView( const void *data ) { const drawSurfsCommand_t *cmd; cmd = (const drawSurfsCommand_t *)data; + if(r_lockSurfaces.GetBool()) { + //viewDef = &tr.lockSurfacesRealViewDef; + //const viewDef_t origParms = *backEnd.viewDef; + viewDef_t* parms = cmd->viewDef; + const viewDef_t origParms = *parms; + + *parms = tr.lockSurfacesRealViewDef; // actual current player/camera position - XXX: really? what about projection matrix? + parms->renderWorld = origParms.renderWorld; + parms->floatTime = origParms.floatTime; + parms->drawSurfs = origParms.drawSurfs; + parms->numDrawSurfs = origParms.numDrawSurfs; + parms->maxDrawSurfs = origParms.maxDrawSurfs; + parms->viewLights = origParms.viewLights; + parms->viewEntitys = origParms.viewEntitys; + parms->connectedAreas = origParms.connectedAreas; + + // TODO: is this really the proper one? maybe should've been set before when origParms.projectionMatrix was set? + //memcpy(parms->projectionMatrix, origParms.projectionMatrix, sizeof(origParms.projectionMatrix)); + //memcpy(parms->worldSpace.modelViewMatrix, origParms.worldSpace.modelViewMatrix, sizeof(origParms.worldSpace.modelViewMatrix)); + R_SetupProjection(parms); + // TODO: R_SetupViewFrustum() ? + R_SetViewMatrix(parms); + + // implicit parms->worldSpace = origParms.worldSpace; + + // update the view origin and axis, and all the entity matricies + for( viewEntity_t* vModel = tr.lockSurfacesCmd.viewDef->viewEntitys ; vModel ; vModel = vModel->next ) { + myGlMultMatrix( vModel->modelMatrix, + parms->worldSpace.modelViewMatrix, + vModel->modelViewMatrix ); + } + + } + backEnd.viewDef = cmd->viewDef; // we will need to do a new copyTexSubImage of the screen