From de5bb2274041bd0ea98dae9a93419104b50b5465 Mon Sep 17 00:00:00 2001 From: havoc Date: Fri, 13 Apr 2018 05:00:22 +0000 Subject: [PATCH] Fix some viewport issues with r_viewfbo and r_bloom by passing view size information when calling the various rendering subsystems - there are still a bunch of bugs but this is a temporary measure before rendertargets are put in. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12389 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_screen.c | 4 +- clvm_cmds.c | 2 +- gl_draw.c | 2 +- gl_rmain.c | 227 +++++++++++++++++++++++++++------------------------- r_shadow.c | 31 ++++--- r_shadow.h | 2 +- render.h | 43 ++++++++-- 7 files changed, 177 insertions(+), 134 deletions(-) diff --git a/cl_screen.c b/cl_screen.c index 733aca06..858673f1 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -1856,7 +1856,7 @@ static void R_Envmap_f (void) r_refdef.view.quality = 1; r_refdef.view.clear = true; R_Mesh_Start(); - R_RenderView(); + R_RenderView(0, NULL, NULL, r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.height); R_Mesh_Finish(); SCR_ScreenShot(filename, buffer1, buffer2, 0, vid.height - (r_refdef.view.y + r_refdef.view.height), size, size, envmapinfo[j].flipx, envmapinfo[j].flipy, envmapinfo[j].flipdiagonaly, false, false, false, false); } @@ -2143,7 +2143,7 @@ static void SCR_DrawScreen (void) else { CL_UpdateEntityShading(); - R_RenderView(); + R_RenderView(0, NULL, NULL, r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.height); } } diff --git a/clvm_cmds.c b/clvm_cmds.c index 02f16078..34baa67a 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -3272,7 +3272,7 @@ static void VM_CL_R_RenderScene (prvm_prog_t *prog) CL_UpdateEntityShading(); // now draw stuff! - R_RenderView(); + R_RenderView(0, NULL, NULL, r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.height); Mod_Mesh_Reset(CL_Mesh_CSQC()); diff --git a/gl_draw.c b/gl_draw.c index 5f8a358d..4f700ff7 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -750,7 +750,7 @@ static void _DrawQ_Setup(void) // see R_ResetViewRendering2D return; DrawQ_FlushUI(); r_refdef.draw2dstage = 1; - R_ResetViewRendering2D_Common(0, NULL, NULL, vid_conwidth.integer, vid_conheight.integer); + R_ResetViewRendering2D_Common(0, NULL, NULL, 0, 0, vid.width, vid.height, vid_conwidth.integer, vid_conheight.integer); } qboolean r_draw2d_force = false; diff --git a/gl_rmain.c b/gl_rmain.c index 938d97f7..fbe5758b 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -2143,28 +2143,6 @@ void R_SetupShader_DepthOrShadow(qboolean notrippy, qboolean depthrgb, qboolean } } -extern qboolean r_shadow_usingdeferredprepass; -extern rtexture_t *r_shadow_attenuationgradienttexture; -extern rtexture_t *r_shadow_attenuation2dtexture; -extern rtexture_t *r_shadow_attenuation3dtexture; -extern qboolean r_shadow_usingshadowmap2d; -extern qboolean r_shadow_usingshadowmaportho; -extern float r_shadow_modelshadowmap_texturescale[4]; -extern float r_shadow_modelshadowmap_parameters[4]; -extern float r_shadow_lightshadowmap_texturescale[4]; -extern float r_shadow_lightshadowmap_parameters[4]; -extern qboolean r_shadow_shadowmapvsdct; -extern rtexture_t *r_shadow_shadowmap2ddepthbuffer; -extern rtexture_t *r_shadow_shadowmap2ddepthtexture; -extern rtexture_t *r_shadow_shadowmapvsdcttexture; -extern matrix4x4_t r_shadow_shadowmapmatrix; -extern int r_shadow_prepass_width; -extern int r_shadow_prepass_height; -extern rtexture_t *r_shadow_prepassgeometrydepthbuffer; -extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture; -extern rtexture_t *r_shadow_prepasslightingdiffusetexture; -extern rtexture_t *r_shadow_prepasslightingspeculartexture; - #define BLENDFUNC_ALLOWS_COLORMOD 1 #define BLENDFUNC_ALLOWS_FOG 2 #define BLENDFUNC_ALLOWS_FOG_HACK0 4 @@ -5567,14 +5545,14 @@ static void R_GetScaledViewSize(int width, int height, int *outwidth, int *outhe *outheight = (int)ceil(height * scale); } -void R_SetupView(qboolean allowwaterclippingplane, int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) +void R_SetupView(qboolean allowwaterclippingplane, int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight) { const float *customclipplane = NULL; float plane[4]; - int /*rtwidth,*/ rtheight, scaledwidth, scaledheight; + int /*rtwidth,*/ rtheight; if (r_refdef.view.useclipplane && allowwaterclippingplane) { - // LordHavoc: couldn't figure out how to make this approach the + // LadyHavoc: couldn't figure out how to make this approach work the same in DPSOFTRAST vec_t dist = r_refdef.view.clipplane.dist - r_water_clippingplanebias.value; vec_t viewdist = DotProduct(r_refdef.view.origin, r_refdef.view.clipplane.normal); if (viewdist < r_refdef.view.clipplane.dist + r_water_clippingplanebias.value) @@ -5586,17 +5564,16 @@ void R_SetupView(qboolean allowwaterclippingplane, int fbo, rtexture_t *depthtex if(vid.renderpath != RENDERPATH_SOFT) customclipplane = plane; } - //rtwidth = fbo ? R_TextureWidth(depthtexture ? depthtexture : colortexture) : vid.width; - rtheight = fbo ? R_TextureHeight(depthtexture ? depthtexture : colortexture) : vid.height; + //rtwidth = viewfbo ? R_TextureWidth(viewdepthtexture ? viewdepthtexture : viewcolortexture) : vid.width; + rtheight = viewfbo ? R_TextureHeight(viewdepthtexture ? viewdepthtexture : viewcolortexture) : vid.height; - R_GetScaledViewSize(r_refdef.view.width, r_refdef.view.height, &scaledwidth, &scaledheight); if (!r_refdef.view.useperspective) - R_Viewport_InitOrtho(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, rtheight - scaledheight - r_refdef.view.y, scaledwidth, scaledheight, -r_refdef.view.ortho_x, -r_refdef.view.ortho_y, r_refdef.view.ortho_x, r_refdef.view.ortho_y, -r_refdef.farclip, r_refdef.farclip, customclipplane); + R_Viewport_InitOrtho(&r_refdef.view.viewport, &r_refdef.view.matrix, viewx, rtheight - viewheight - viewy, viewwidth, viewheight, -r_refdef.view.ortho_x, -r_refdef.view.ortho_y, r_refdef.view.ortho_x, r_refdef.view.ortho_y, -r_refdef.farclip, r_refdef.farclip, customclipplane); else if (vid.stencil && r_useinfinitefarclip.integer) - R_Viewport_InitPerspectiveInfinite(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, rtheight - scaledheight - r_refdef.view.y, scaledwidth, scaledheight, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, customclipplane); + R_Viewport_InitPerspectiveInfinite(&r_refdef.view.viewport, &r_refdef.view.matrix, viewx, rtheight - viewheight - viewy, viewwidth, viewheight, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, customclipplane); else - R_Viewport_InitPerspective(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, rtheight - scaledheight - r_refdef.view.y, scaledwidth, scaledheight, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, r_refdef.farclip, customclipplane); - R_Mesh_SetRenderTargets(fbo, depthtexture, colortexture, NULL, NULL, NULL); + R_Viewport_InitPerspective(&r_refdef.view.viewport, &r_refdef.view.matrix, viewx, rtheight - viewheight - viewy, viewwidth, viewheight, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, r_refdef.farclip, customclipplane); + R_Mesh_SetRenderTargets(viewfbo, viewdepthtexture, viewcolortexture, NULL, NULL, NULL); R_SetViewport(&r_refdef.view.viewport); if (r_refdef.view.useclipplane && allowwaterclippingplane && vid.renderpath == RENDERPATH_SOFT) { @@ -5655,15 +5632,15 @@ void R_EntityMatrix(const matrix4x4_t *matrix) } } -void R_ResetViewRendering2D_Common(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, float x2, float y2) +void R_ResetViewRendering2D_Common(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight, float x2, float y2) { r_viewport_t viewport; CHECKGLERROR // GL is weird because it's bottom to top, r_refdef.view.y is top to bottom - R_Viewport_InitOrtho(&viewport, &identitymatrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, 0, 0, x2, y2, -10, 100, NULL); - R_Mesh_SetRenderTargets(fbo, depthtexture, colortexture, NULL, NULL, NULL); + R_Viewport_InitOrtho(&viewport, &identitymatrix, viewx, vid.height - viewheight - viewy, viewwidth, viewheight, 0, 0, x2, y2, -10, 100, NULL); + R_Mesh_SetRenderTargets(viewfbo, viewdepthtexture, viewcolortexture, NULL, NULL, NULL); R_SetViewport(&viewport); GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height); GL_Color(1, 1, 1, 1); @@ -5698,18 +5675,18 @@ void R_ResetViewRendering2D_Common(int fbo, rtexture_t *depthtexture, rtexture_t CHECKGLERROR } -void R_ResetViewRendering2D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) +void R_ResetViewRendering2D(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight) { DrawQ_Finish(); - R_ResetViewRendering2D_Common(fbo, depthtexture, colortexture, 1, 1); + R_ResetViewRendering2D_Common(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight, 1.0f, 1.0f); } -void R_ResetViewRendering3D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) +void R_ResetViewRendering3D(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight) { DrawQ_Finish(); - R_SetupView(true, fbo, depthtexture, colortexture); + R_SetupView(true, viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); GL_Scissor(r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height); GL_Color(1, 1, 1, 1); GL_ColorMask(r_refdef.view.colormask[0], r_refdef.view.colormask[1], r_refdef.view.colormask[2], 1); @@ -5757,9 +5734,6 @@ void R_RenderView_UpdateViewVectors(void) Matrix4x4_Invert_Full(&r_refdef.view.inverse_matrix, &r_refdef.view.matrix); } -void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture); -void R_RenderWaterPlanes(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture); - static void R_Water_StartFrame(void) { int i; @@ -5979,18 +5953,21 @@ void R_Water_AddWaterPlane(msurface_t *surface, int entno) extern cvar_t r_drawparticles; extern cvar_t r_drawdecals; -static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) +static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, int x, int y, int width, int height) { int myscissor[4]; r_refdef_view_t originalview; r_refdef_view_t myview; int planeindex, qualityreduction = 0, old_r_dynamic = 0, old_r_shadows = 0, old_r_worldrtlight = 0, old_r_dlight = 0, old_r_particles = 0, old_r_decals = 0; + int waterx, watery; r_waterstate_waterplane_t *p; vec3_t visorigin; qboolean usewaterfbo = (r_viewfbo.integer >= 1 || r_water_fbo.integer >= 1) && vid.support.ext_framebuffer_object && vid.support.arb_texture_non_power_of_two && vid.samples < 2; char vabuf[1024]; originalview = r_refdef.view; + waterx = usewaterfbo ? 0 : x; + watery = usewaterfbo ? 0 : y; // lowquality hack, temporarily shut down some cvars and restore afterwards qualityreduction = r_water_lowquality.integer; @@ -6069,6 +6046,8 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t // render views r_refdef.view = originalview; r_refdef.view.showdebug = false; + r_refdef.view.x = waterx; + r_refdef.view.y = watery; r_refdef.view.width = r_fb.water.waterwidth; r_refdef.view.height = r_fb.water.waterheight; r_refdef.view.useclipplane = true; @@ -6083,7 +6062,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t r_refdef.view = myview; if(r_water_scissormode.integer) { - R_SetupView(true, p->fbo_reflection, r_fb.water.depthtexture, p->texture_reflection); + R_SetupView(true, p->fbo_reflection, r_fb.water.depthtexture, p->texture_reflection, waterx, watery, r_fb.water.waterwidth, r_fb.water.waterheight); if(R_ScissorForBBox(p->mins, p->maxs, myscissor)) continue; // FIXME the plane then still may get rendered but with broken texture, but it sure won't be visible } @@ -6106,8 +6085,12 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t } r_fb.water.hideplayer = ((r_water_hideplayer.integer >= 2) && !chase_active.integer); - R_ResetViewRendering3D(p->fbo_reflection, r_fb.water.depthtexture, p->texture_reflection); + R_ResetViewRendering3D(p->fbo_reflection, r_fb.water.depthtexture, p->texture_reflection, waterx, watery, r_fb.water.waterwidth, r_fb.water.waterheight); + if (p->fbo_reflection) + GL_ScissorTest(false); R_ClearScreen(r_refdef.fogenabled); + if (p->fbo_reflection) + GL_ScissorTest(true); if(r_water_scissormode.integer & 2) R_View_UpdateWithScissor(myscissor); else @@ -6115,10 +6098,10 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t R_AnimCache_CacheVisibleEntities(); if(r_water_scissormode.integer & 1) GL_Scissor(myscissor[0], myscissor[1], myscissor[2], myscissor[3]); - R_RenderScene(p->fbo_reflection, r_fb.water.depthtexture, p->texture_reflection); + R_RenderScene(p->fbo_reflection, r_fb.water.depthtexture, p->texture_reflection, waterx, watery, r_fb.water.waterwidth, r_fb.water.waterheight); if (!p->fbo_reflection) - R_Mesh_CopyToTexture(p->texture_reflection, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height); + R_Mesh_CopyToTexture(p->texture_reflection, 0, 0, waterx, watery, r_fb.water.waterwidth, r_fb.water.waterheight); r_fb.water.hideplayer = false; } @@ -6129,7 +6112,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t r_refdef.view = myview; if(r_water_scissormode.integer) { - R_SetupView(true, p->fbo_refraction, r_fb.water.depthtexture, p->texture_refraction); + R_SetupView(true, p->fbo_refraction, r_fb.water.depthtexture, p->texture_refraction, waterx, watery, r_fb.water.waterwidth, r_fb.water.waterheight); if(R_ScissorForBBox(p->mins, p->maxs, myscissor)) continue; // FIXME the plane then still may get rendered but with broken texture, but it sure won't be visible } @@ -6155,8 +6138,12 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t PlaneClassify(&r_refdef.view.clipplane); - R_ResetViewRendering3D(p->fbo_refraction, r_fb.water.depthtexture, p->texture_refraction); + R_ResetViewRendering3D(p->fbo_refraction, r_fb.water.depthtexture, p->texture_refraction, waterx, watery, r_fb.water.waterwidth, r_fb.water.waterheight); + if (p->fbo_refraction) + GL_ScissorTest(false); R_ClearScreen(r_refdef.fogenabled); + if (p->fbo_refraction) + GL_ScissorTest(true); if(r_water_scissormode.integer & 2) R_View_UpdateWithScissor(myscissor); else @@ -6164,10 +6151,10 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t R_AnimCache_CacheVisibleEntities(); if(r_water_scissormode.integer & 1) GL_Scissor(myscissor[0], myscissor[1], myscissor[2], myscissor[3]); - R_RenderScene(p->fbo_refraction, r_fb.water.depthtexture, p->texture_refraction); + R_RenderScene(p->fbo_refraction, r_fb.water.depthtexture, p->texture_refraction, waterx, watery, r_fb.water.waterwidth, r_fb.water.waterheight); if (!p->fbo_refraction) - R_Mesh_CopyToTexture(p->texture_refraction, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height); + R_Mesh_CopyToTexture(p->texture_refraction, 0, 0, waterx, watery, r_fb.water.waterwidth, r_fb.water.waterheight); r_fb.water.hideplayer = false; } else if (p->materialflags & MATERIALFLAG_CAMERA) @@ -6178,6 +6165,8 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t VectorNegate(r_refdef.view.clipplane.normal, r_refdef.view.clipplane.normal); r_refdef.view.clipplane.dist = -r_refdef.view.clipplane.dist; + r_refdef.view.x = waterx; + r_refdef.view.y = watery; r_refdef.view.width = r_fb.water.camerawidth; r_refdef.view.height = r_fb.water.cameraheight; r_refdef.view.frustum_x = 1; // tan(45 * M_PI / 180.0); @@ -6213,14 +6202,18 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t r_fb.water.hideplayer = false; - R_ResetViewRendering3D(p->fbo_camera, r_fb.water.depthtexture, p->texture_camera); + R_ResetViewRendering3D(p->fbo_camera, r_fb.water.depthtexture, p->texture_camera, waterx, watery, r_fb.water.camerawidth, r_fb.water.cameraheight); + if (p->fbo_camera) + GL_ScissorTest(false); R_ClearScreen(r_refdef.fogenabled); + if (p->fbo_camera) + GL_ScissorTest(true); R_View_Update(); R_AnimCache_CacheVisibleEntities(); - R_RenderScene(p->fbo_camera, r_fb.water.depthtexture, p->texture_camera); + R_RenderScene(p->fbo_camera, r_fb.water.depthtexture, p->texture_camera, waterx, watery, r_fb.water.camerawidth, r_fb.water.cameraheight); if (!p->fbo_camera) - R_Mesh_CopyToTexture(p->texture_camera, 0, 0, r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height); + R_Mesh_CopyToTexture(p->texture_camera, 0, 0, waterx, watery, r_fb.water.camerawidth, r_fb.water.cameraheight); r_fb.water.hideplayer = false; } @@ -6228,7 +6221,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t if(vid.renderpath==RENDERPATH_SOFT) DPSOFTRAST_ClipPlane(0, 0, 0, 1); r_fb.water.renderingscene = false; r_refdef.view = originalview; - R_ResetViewRendering3D(fbo, depthtexture, colortexture); + R_ResetViewRendering3D(fbo, depthtexture, colortexture, x, y, width, height); if (!r_fb.water.depthtexture) R_ClearScreen(r_refdef.fogenabled); R_View_Update(); @@ -6442,21 +6435,13 @@ static void R_Bloom_StartFrame(void) // set up a texcoord array for the full resolution screen image // (we have to keep this around to copy back during final render) r_fb.screentexcoord2f[0] = 0; - r_fb.screentexcoord2f[1] = (float)viewheight / (float)r_fb.screentextureheight; + r_fb.screentexcoord2f[1] = 1.0f; r_fb.screentexcoord2f[2] = (float)viewwidth / (float)r_fb.screentexturewidth; - r_fb.screentexcoord2f[3] = (float)viewheight / (float)r_fb.screentextureheight; + r_fb.screentexcoord2f[3] = 1.0f; r_fb.screentexcoord2f[4] = (float)viewwidth / (float)r_fb.screentexturewidth; - r_fb.screentexcoord2f[5] = 0; + r_fb.screentexcoord2f[5] = 1.0f - (float)viewheight / (float)r_fb.screentextureheight; r_fb.screentexcoord2f[6] = 0; - r_fb.screentexcoord2f[7] = 0; - - if(r_fb.fbo) - { - for (i = 1;i < 8;i += 2) - { - r_fb.screentexcoord2f[i] += 1 - (float)(viewheight + r_refdef.view.y) / (float)r_fb.screentextureheight; - } - } + r_fb.screentexcoord2f[7] = 1.0f - (float)viewheight / (float)r_fb.screentextureheight; // set up a texcoord array for the reduced resolution bloom image // (which will be additive blended over the screen image) @@ -6491,7 +6476,7 @@ static void R_Bloom_StartFrame(void) break; } - R_Viewport_InitOrtho(&r_fb.bloomviewport, &identitymatrix, 0, 0, r_fb.bloomwidth, r_fb.bloomheight, 0, 0, 1, 1, -10, 100, NULL); + R_Viewport_InitOrtho(&r_fb.bloomviewport, &identitymatrix, r_fb.fbo ? 0 : r_refdef.view.x, r_fb.fbo ? 0 : r_refdef.view.y, r_fb.bloomwidth, r_fb.bloomheight, 0, 0, 1, 1, -10, 100, NULL); if (r_fb.fbo) r_refdef.view.clear = true; @@ -6642,7 +6627,7 @@ static void R_Bloom_MakeTexture(void) } } -static void R_BlendView(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) +static void R_BlendView(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight) { dpuint64 permutation; float uservecs[4][4]; @@ -6712,7 +6697,7 @@ static void R_BlendView(int fbo, rtexture_t *depthtexture, rtexture_t *colortext cl.motionbluralpha = bound(0, cl.motionbluralpha, r_motionblur_maxblur.value); // apply the blur - R_ResetViewRendering2D(fbo, depthtexture, colortexture); + R_ResetViewRendering2D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); if (cl.motionbluralpha > 0 && !r_refdef.envmap && r_fb.ghosttexture_valid) { GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -6754,7 +6739,7 @@ static void R_BlendView(int fbo, rtexture_t *depthtexture, rtexture_t *colortext if (r_refdef.viewblend[3] >= (1.0f / 256.0f)) { // apply a color tint to the whole view - R_ResetViewRendering2D(0, NULL, NULL); + R_ResetViewRendering2D(0, NULL, NULL, viewx, viewy, viewwidth, viewheight); GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]); R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL); R_SetupShader_Generic_NoTexture(false, true); @@ -6783,7 +6768,8 @@ static void R_BlendView(int fbo, rtexture_t *depthtexture, rtexture_t *colortext if (r_glsl_postprocess_uservec4_enable.integer) sscanf(r_glsl_postprocess_uservec4.string, "%f %f %f %f", &uservecs[3][0], &uservecs[3][1], &uservecs[3][2], &uservecs[3][3]); - R_ResetViewRendering2D(0, NULL, NULL); // here we render to the real framebuffer! + // render to the screen fbo + R_ResetViewRendering2D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); GL_Color(1, 1, 1, 1); GL_BlendFunc(GL_ONE, GL_ZERO); @@ -6859,7 +6845,7 @@ static void R_BlendView(int fbo, rtexture_t *depthtexture, rtexture_t *colortext if (r_refdef.viewblend[3] >= (1.0f / 256.0f)) { // apply a color tint to the whole view - R_ResetViewRendering2D(0, NULL, NULL); + R_ResetViewRendering2D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]); R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, NULL); R_SetupShader_Generic_NoTexture(false, true); @@ -7121,12 +7107,13 @@ R_RenderView */ int dpsoftrast_test; extern cvar_t r_shadow_bouncegrid; -void R_RenderView(void) +void R_RenderView(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, int x, int y, int width, int height) { matrix4x4_t originalmatrix = r_refdef.view.matrix, offsetmatrix; - int fbo; - rtexture_t *depthtexture; - rtexture_t *colortexture; + int viewfbo = 0; + rtexture_t *viewdepthtexture = NULL; + rtexture_t *viewcolortexture = NULL; + int viewx = r_refdef.view.x, viewy = r_refdef.view.y, viewwidth = r_refdef.view.width, viewheight = r_refdef.view.height; dpsoftrast_test = r_test.integer; @@ -7164,7 +7151,7 @@ void R_RenderView(void) r_fb.water.enabled = false; r_fb.water.numwaterplanes = 0; - R_RenderScene(0, NULL, NULL); + R_RenderScene(fbo, depthtexture, colortexture, x, y, width, height); r_refdef.view.matrix = originalmatrix; @@ -7189,31 +7176,41 @@ void R_RenderView(void) R_Shadow_UpdateWorldLightSelection(); + // this will set up r_fb.fbo R_Bloom_StartFrame(); // apply bloom brightness offset if(r_fb.bloomtexture[0]) r_refdef.view.colorscale *= r_bloom_scenebrightness.value; - R_Water_StartFrame(); + // R_Bloom_StartFrame probably set up an fbo for us to render into, it will be rendered to the window later in R_BlendView + if (r_fb.fbo) + { + viewfbo = r_fb.fbo; + viewdepthtexture = r_fb.depthtexture; + viewcolortexture = r_fb.colortexture; + viewx = 0; + viewy = 0; + viewwidth = width; + viewheight = height; + } - // now we probably have an fbo to render into - fbo = r_fb.fbo; - depthtexture = r_fb.depthtexture; - colortexture = r_fb.colortexture; + R_Water_StartFrame(); CHECKGLERROR if (r_timereport_active) R_TimeReport("viewsetup"); - R_ResetViewRendering3D(fbo, depthtexture, colortexture); + R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); + + // clear the whole fbo every frame - otherwise the driver will consider + // it to be an inter-frame texture and stall in multi-gpu configurations + if (viewfbo) + GL_ScissorTest(false); + R_ClearScreen(r_refdef.fogenabled); + if (r_timereport_active) + R_TimeReport("viewclear"); - if (r_refdef.view.clear || r_refdef.fogenabled || fbo) - { - R_ClearScreen(r_refdef.fogenabled); - if (r_timereport_active) - R_TimeReport("viewclear"); - } r_refdef.view.clear = true; r_refdef.view.showdebug = true; @@ -7232,24 +7229,31 @@ void R_RenderView(void) r_fb.water.numwaterplanes = 0; if (r_fb.water.enabled) - R_RenderWaterPlanes(fbo, depthtexture, colortexture); - - R_RenderScene(fbo, depthtexture, colortexture); + R_RenderWaterPlanes(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); + + // for the actual view render we use scissoring a fair amount, so scissor + // test needs to be on + if (viewfbo) + GL_ScissorTest(true); + GL_Scissor(viewx, viewy, viewwidth, viewheight); + R_RenderScene(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); r_fb.water.numwaterplanes = 0; - R_BlendView(fbo, depthtexture, colortexture); + // postprocess uses textures that are not aligned with the viewport we're rendering, so no scissoring + GL_ScissorTest(false); + + // R_BlendView will render the viewfbo image into the provided fbo using + // the postprocess shader (including gamma correction and sRGB) + R_BlendView(fbo, depthtexture, colortexture, x, y, width, height); if (r_timereport_active) R_TimeReport("blendview"); - GL_Scissor(0, 0, vid.width, vid.height); - GL_ScissorTest(false); - r_refdef.view.matrix = originalmatrix; CHECKGLERROR } -void R_RenderWaterPlanes(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) +void R_RenderWaterPlanes(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight) { if (cl.csqc_vidvars.drawworld && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawAddWaterPlanes) { @@ -7268,7 +7272,7 @@ void R_RenderWaterPlanes(int fbo, rtexture_t *depthtexture, rtexture_t *colortex if (r_fb.water.numwaterplanes) { - R_Water_ProcessPlanes(fbo, depthtexture, colortexture); + R_Water_ProcessPlanes(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); if (r_timereport_active) R_TimeReport("waterscenes"); } @@ -7281,7 +7285,7 @@ static void R_DrawModelDecals(void); extern cvar_t cl_decals_newsystem; extern qboolean r_shadow_usingdeferredprepass; extern int r_shadow_shadowmapatlas_modelshadows_size; -void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) +void R_RenderScene(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight) { qboolean shadowmapping = false; @@ -7324,16 +7328,25 @@ void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) if (skyrendermasked && skyrenderlater) { // we have to force off the water clipping plane while rendering sky - R_SetupView(false, fbo, depthtexture, colortexture); + R_SetupView(false, viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); R_Sky(); - R_SetupView(true, fbo, depthtexture, colortexture); + R_SetupView(true, viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); if (r_timereport_active) R_TimeReport("sky"); } } + // save the framebuffer info for R_Shadow_RenderMode_Reset during this view render + r_shadow_viewfbo = viewfbo; + r_shadow_viewdepthtexture = viewdepthtexture; + r_shadow_viewcolortexture = viewcolortexture; + r_shadow_viewx = viewx; + r_shadow_viewy = viewy; + r_shadow_viewwidth = viewwidth; + r_shadow_viewheight = viewheight; + R_Shadow_PrepareModelShadows(); - R_Shadow_PrepareLights(fbo, depthtexture, colortexture); + R_Shadow_PrepareLights(); if (r_timereport_active) R_TimeReport("preparelights"); @@ -7385,9 +7398,9 @@ void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && !r_shadows_drawafterrtlighting.integer && r_refdef.scene.lightmapintensity > 0) { - R_ResetViewRendering3D(fbo, depthtexture, colortexture); + R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); R_Shadow_DrawModelShadows(); - R_ResetViewRendering3D(fbo, depthtexture, colortexture); + R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); // don't let sound skip if going slow if (r_refdef.scene.extraupdate) S_ExtraUpdate (); @@ -7406,9 +7419,9 @@ void R_RenderScene(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) if ((r_shadows.integer == 1 || (r_shadows.integer > 0 && !shadowmapping)) && r_shadows_drawafterrtlighting.integer && r_refdef.scene.lightmapintensity > 0) { - R_ResetViewRendering3D(fbo, depthtexture, colortexture); + R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); R_Shadow_DrawModelShadows(); - R_ResetViewRendering3D(fbo, depthtexture, colortexture); + R_ResetViewRendering3D(viewfbo, viewdepthtexture, viewcolortexture, viewx, viewy, viewwidth, viewheight); // don't let sound skip if going slow if (r_refdef.scene.extraupdate) S_ExtraUpdate (); diff --git a/r_shadow.c b/r_shadow.c index d767804a..c7ecb5a1 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -269,10 +269,13 @@ rtexture_t *r_shadow_prepassgeometrynormalmaptexture; rtexture_t *r_shadow_prepasslightingdiffusetexture; rtexture_t *r_shadow_prepasslightingspeculartexture; -// keep track of the provided framebuffer info -static int r_shadow_fb_fbo; -static rtexture_t *r_shadow_fb_depthtexture; -static rtexture_t *r_shadow_fb_colortexture; +int r_shadow_viewfbo; +rtexture_t *r_shadow_viewdepthtexture; +rtexture_t *r_shadow_viewcolortexture; +int r_shadow_viewx; +int r_shadow_viewy; +int r_shadow_viewwidth; +int r_shadow_viewheight; // lights are reloaded when this changes char r_shadow_mapname[MAX_QPATH]; @@ -2111,7 +2114,7 @@ void R_Shadow_RenderMode_ActiveLight(const rtlight_t *rtlight) void R_Shadow_RenderMode_Reset(void) { R_Mesh_ResetTextureState(); - R_Mesh_SetRenderTargets(r_shadow_fb_fbo, r_shadow_fb_depthtexture, r_shadow_fb_colortexture, NULL, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_viewfbo, r_shadow_viewdepthtexture, r_shadow_viewcolortexture, NULL, NULL, NULL); R_SetViewport(&r_refdef.view.viewport); GL_Scissor(r_shadow_lightscissor[0], r_shadow_lightscissor[1], r_shadow_lightscissor[2], r_shadow_lightscissor[3]); GL_DepthRange(0, 1); @@ -5330,7 +5333,7 @@ qboolean R_Shadow_PrepareLights_AddSceneLight(rtlight_t *rtlight) } void R_Shadow_DrawLightSprites(void); -void R_Shadow_PrepareLights(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) +void R_Shadow_PrepareLights(void) { int flag; int lnum; @@ -5354,10 +5357,6 @@ void R_Shadow_PrepareLights(int fbo, rtexture_t *depthtexture, rtexture_t *color r_shadow_shadowmapdepthtexture != r_fb.usedepthtextures) R_Shadow_FreeShadowMaps(); - r_shadow_fb_fbo = fbo; - r_shadow_fb_depthtexture = depthtexture; - r_shadow_fb_colortexture = colortexture; - r_shadow_usingshadowmaportho = false; switch (vid.renderpath) @@ -5799,15 +5798,15 @@ void R_Shadow_DrawModelShadows(void) if (!r_shadow_nummodelshadows || (r_shadow_shadowmode != R_SHADOW_SHADOWMODE_STENCIL && r_shadows.integer != 1)) return; - R_ResetViewRendering3D(r_shadow_fb_fbo, r_shadow_fb_depthtexture, r_shadow_fb_colortexture); + R_ResetViewRendering3D(r_shadow_viewfbo, r_shadow_viewdepthtexture, r_shadow_viewcolortexture, r_shadow_viewx, r_shadow_viewy, r_shadow_viewwidth, r_shadow_viewheight); //GL_Scissor(r_refdef.view.viewport.x, r_refdef.view.viewport.y, r_refdef.view.viewport.width, r_refdef.view.viewport.height); //GL_Scissor(r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height); R_Shadow_RenderMode_Begin(); R_Shadow_RenderMode_ActiveLight(NULL); - r_shadow_lightscissor[0] = r_refdef.view.x; - r_shadow_lightscissor[1] = vid.height - r_refdef.view.y - r_refdef.view.height; - r_shadow_lightscissor[2] = r_refdef.view.width; - r_shadow_lightscissor[3] = r_refdef.view.height; + r_shadow_lightscissor[0] = r_shadow_viewx; + r_shadow_lightscissor[1] = (r_shadow_viewfbo ? r_shadow_viewheight : vid.height) - r_shadow_viewy - r_shadow_viewheight; + r_shadow_lightscissor[2] = r_shadow_viewwidth; + r_shadow_lightscissor[3] = r_shadow_viewheight; R_Shadow_RenderMode_StencilShadowVolumes(false); // get shadow dir @@ -5851,7 +5850,7 @@ void R_Shadow_DrawModelShadows(void) //GL_ScissorTest(true); //R_EntityMatrix(&identitymatrix); //R_Mesh_ResetTextureState(); - R_ResetViewRendering2D(r_shadow_fb_fbo, r_shadow_fb_depthtexture, r_shadow_fb_colortexture); + R_ResetViewRendering2D(r_shadow_viewfbo, r_shadow_viewdepthtexture, r_shadow_viewcolortexture, r_shadow_viewx, r_shadow_viewy, r_shadow_viewwidth, r_shadow_viewheight); // set up a darkening blend on shadowed areas GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); diff --git a/r_shadow.h b/r_shadow.h index 809805eb..82f5c88e 100644 --- a/r_shadow.h +++ b/r_shadow.h @@ -135,7 +135,7 @@ void R_RTLight_Update(rtlight_t *rtlight, int isstatic, matrix4x4_t *matrix, vec void R_RTLight_Compile(rtlight_t *rtlight); void R_RTLight_Uncompile(rtlight_t *rtlight); -void R_Shadow_PrepareLights(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture); +void R_Shadow_PrepareLights(void); void R_Shadow_ClearShadowMapTexture(void); void R_Shadow_DrawPrepass(void); void R_Shadow_DrawLights(void); diff --git a/render.h b/render.h index d8fd0343..81f3a541 100644 --- a/render.h +++ b/render.h @@ -127,7 +127,7 @@ extern cvar_t r_wateralpha; extern cvar_t r_dynamic; void R_UpdateVariables(void); // must call after setting up most of r_refdef, but before calling R_RenderView -void R_RenderView(void); // must set r_refdef and call R_UpdateVariables and CL_UpdateEntityShading first +void R_RenderView(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, int x, int y, int width, int height); // must set r_refdef and call R_UpdateVariables and CL_UpdateEntityShading first void R_RenderView_UpdateViewVectors(void); // just updates r_refdef.view.{forward,left,up,origin,right,inverse_matrix} typedef enum r_refdef_scene_type_s { @@ -460,7 +460,6 @@ void RSurf_SetupDepthAndCulling(void); texture_t *R_GetCurrentTexture(texture_t *t); void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean debug, qboolean prepass); -void R_AddWaterPlanes(entity_render_t *ent); void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass); void R_DrawCustomSurface_Texture(texture_t *texture, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass); @@ -574,10 +573,10 @@ extern r_framebufferstate_t r_fb; extern cvar_t r_viewfbo; -void R_ResetViewRendering2D_Common(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, float x2, float y2); // this is called by R_ResetViewRendering2D and _DrawQ_Setup and internal -void R_ResetViewRendering2D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture); -void R_ResetViewRendering3D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture); -void R_SetupView(qboolean allowwaterclippingplane, int fbo, rtexture_t *depthtexture, rtexture_t *colortexture); +void R_ResetViewRendering2D_Common(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight, float x2, float y2); // this is called by R_ResetViewRendering2D and _DrawQ_Setup and internal +void R_ResetViewRendering2D(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight); +void R_ResetViewRendering3D(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight); +void R_SetupView(qboolean allowwaterclippingplane, int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight); extern const float r_screenvertex3f[12]; extern cvar_t r_shadows; extern cvar_t r_shadows_darken; @@ -595,6 +594,38 @@ extern cvar_t r_transparent_sortarraysize; extern cvar_t r_transparent_sortmindist; extern cvar_t r_transparent_sortmaxdist; +extern qboolean r_shadow_usingdeferredprepass; +extern rtexture_t *r_shadow_attenuationgradienttexture; +extern rtexture_t *r_shadow_attenuation2dtexture; +extern rtexture_t *r_shadow_attenuation3dtexture; +extern qboolean r_shadow_usingshadowmap2d; +extern qboolean r_shadow_usingshadowmaportho; +extern float r_shadow_modelshadowmap_texturescale[4]; +extern float r_shadow_modelshadowmap_parameters[4]; +extern float r_shadow_lightshadowmap_texturescale[4]; +extern float r_shadow_lightshadowmap_parameters[4]; +extern qboolean r_shadow_shadowmapvsdct; +extern rtexture_t *r_shadow_shadowmap2ddepthbuffer; +extern rtexture_t *r_shadow_shadowmap2ddepthtexture; +extern rtexture_t *r_shadow_shadowmapvsdcttexture; +extern matrix4x4_t r_shadow_shadowmapmatrix; +extern int r_shadow_prepass_width; +extern int r_shadow_prepass_height; +extern rtexture_t *r_shadow_prepassgeometrydepthbuffer; +extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture; +extern rtexture_t *r_shadow_prepasslightingdiffusetexture; +extern rtexture_t *r_shadow_prepasslightingspeculartexture; +extern int r_shadow_viewfbo; +extern rtexture_t *r_shadow_viewdepthtexture; +extern rtexture_t *r_shadow_viewcolortexture; +extern int r_shadow_viewx; +extern int r_shadow_viewy; +extern int r_shadow_viewwidth; +extern int r_shadow_viewheight; + +void R_RenderScene(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight); +void R_RenderWaterPlanes(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight); + void R_Model_Sprite_Draw(entity_render_t *ent); struct prvm_prog_s; -- 2.39.2