Added v_isometric cvars, this mode is mostly a curiosity but it's useful for testing...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 14 Apr 2018 06:54:35 +0000 (06:54 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 14 Apr 2018 06:54:35 +0000 (06:54 +0000)
Fixed a few bugs where distance culling was misbehaving with non-perspective rendering.

Make r_refdef.view.ismain more useful - it's now cleared after R_RenderView rather than before, so R_RenderView can make use of it (for r_motionblur ghost texture updates and anything else that wants to happen just on the main view).

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12396 d7cf8633-e32d-0410-b094-e92efae38249

cl_particles.c
cl_screen.c
clvm_cmds.c
csprogs.c
gl_rmain.c
gl_rsurf.c
view.c

index b159698..4247755 100644 (file)
@@ -2612,7 +2612,7 @@ void R_DrawDecals (void)
                if (!drawdecals)
                        continue;
 
-               if (DotProduct(r_refdef.view.origin, decal->normal) > DotProduct(decal->org, decal->normal) && VectorDistance2(decal->org, r_refdef.view.origin) < drawdist2 * (decal->size * decal->size))
+               if (!r_refdef.view.useperspective || (DotProduct(r_refdef.view.origin, decal->normal) > DotProduct(decal->org, decal->normal) && VectorDistance2(decal->org, r_refdef.view.origin) < drawdist2 * (decal->size * decal->size)))
                        R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, decal->org, R_DrawDecal_TransparentCallback, NULL, i, NULL);
                continue;
 killdecal:
@@ -3132,7 +3132,7 @@ void R_DrawParticles (void)
                                                                continue;
                                        }
                        // anything else just has to be in front of the viewer and visible at this distance
-                       if (DotProduct(p->org, r_refdef.view.forward) >= minparticledist_start && VectorDistance2(p->org, r_refdef.view.origin) < drawdist2 * (p->size * p->size))
+                       if (!r_refdef.view.useperspective || (DotProduct(p->org, r_refdef.view.forward) >= minparticledist_start && VectorDistance2(p->org, r_refdef.view.origin) < drawdist2 * (p->size * p->size)))
                                R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, p->sortorigin, R_DrawParticle_TransparentCallback, NULL, i, NULL);
                        break;
                }
index 7fb41d1..afdeab6 100644 (file)
@@ -1844,6 +1844,7 @@ static void R_Envmap_f (void)
        r_refdef.view.depth = 1;
        r_refdef.view.useperspective = true;
        r_refdef.view.isoverlay = false;
+       r_refdef.view.ismain = true;
 
        r_refdef.view.frustum_x = 1; // tan(45 * M_PI / 180.0);
        r_refdef.view.frustum_y = 1; // tan(45 * M_PI / 180.0);
@@ -2065,6 +2066,8 @@ void R_ClearScreen(qboolean fogcolor)
 }
 
 int r_stereo_side;
+extern cvar_t v_isometric;
+extern cvar_t v_isometric_verticalfov;
 
 static void SCR_DrawScreen (void)
 {
@@ -2128,20 +2131,34 @@ static void SCR_DrawScreen (void)
                        r_refdef.view.z = 0;
                }
 
-               // LordHavoc: viewzoom (zoom in for sniper rifles, etc)
-               // LordHavoc: this is designed to produce widescreen fov values
-               // when the screen is wider than 4/3 width/height aspect, to do
-               // this it simply assumes the requested fov is the vertical fov
-               // for a 4x3 display, if the ratio is not 4x3 this makes the fov
-               // higher/lower according to the ratio
-               r_refdef.view.useperspective = true;
-               r_refdef.view.frustum_y = tan(scr_fov.value * M_PI / 360.0) * (3.0/4.0) * cl.viewzoom;
-               r_refdef.view.frustum_x = r_refdef.view.frustum_y * (float)r_refdef.view.width / (float)r_refdef.view.height / vid_pixelheight.value;
-
-               r_refdef.view.frustum_x *= r_refdef.frustumscale_x;
-               r_refdef.view.frustum_y *= r_refdef.frustumscale_y;
-               r_refdef.view.ortho_x = atan(r_refdef.view.frustum_x) * (360.0 / M_PI); // abused as angle by VM_CL_R_SetView
-               r_refdef.view.ortho_y = atan(r_refdef.view.frustum_y) * (360.0 / M_PI); // abused as angle by VM_CL_R_SetView
+               if (v_isometric.integer)
+               {
+                       r_refdef.view.useperspective = false;
+                       r_refdef.view.frustum_y = v_isometric_verticalfov.value * cl.viewzoom;
+                       r_refdef.view.frustum_x = r_refdef.view.frustum_y * (float)r_refdef.view.width / (float)r_refdef.view.height / vid_pixelheight.value;
+                       r_refdef.view.frustum_x *= r_refdef.frustumscale_x;
+                       r_refdef.view.frustum_y *= r_refdef.frustumscale_y;
+                       r_refdef.view.ortho_x = r_refdef.view.frustum_x; // used by VM_CL_R_SetView
+                       r_refdef.view.ortho_y = r_refdef.view.frustum_y; // used by VM_CL_R_SetView
+               }
+               else
+               {
+                       // LordHavoc: viewzoom (zoom in for sniper rifles, etc)
+                       // LordHavoc: this is designed to produce widescreen fov values
+                       // when the screen is wider than 4/3 width/height aspect, to do
+                       // this it simply assumes the requested fov is the vertical fov
+                       // for a 4x3 display, if the ratio is not 4x3 this makes the fov
+                       // higher/lower according to the ratio
+                       r_refdef.view.useperspective = true;
+                       r_refdef.view.frustum_y = tan(scr_fov.value * M_PI / 360.0) * (3.0 / 4.0) * cl.viewzoom;
+                       r_refdef.view.frustum_x = r_refdef.view.frustum_y * (float)r_refdef.view.width / (float)r_refdef.view.height / vid_pixelheight.value;
+
+                       r_refdef.view.frustum_x *= r_refdef.frustumscale_x;
+                       r_refdef.view.frustum_y *= r_refdef.frustumscale_y;
+                       r_refdef.view.ortho_x = atan(r_refdef.view.frustum_x) * (360.0 / M_PI); // abused as angle by VM_CL_R_SetView
+                       r_refdef.view.ortho_y = atan(r_refdef.view.frustum_y) * (360.0 / M_PI); // abused as angle by VM_CL_R_SetView
+               }
+               r_refdef.view.ismain = true;
 
                // if CSQC is loaded, it is required to provide the CSQC_UpdateView function,
                // and won't render a view if it does not call that.
index 4734484..5ee778f 100644 (file)
@@ -3252,18 +3252,15 @@ static void VM_CL_GetEntity (prvm_prog_t *prog)
 // --blub
 static void VM_CL_R_RenderScene (prvm_prog_t *prog)
 {
+       qboolean ismain = r_refdef.view.ismain;
        double t = Sys_DirtyTime();
        VM_SAFEPARMCOUNT(0, VM_CL_R_RenderScene);
 
        // update the views
-       if(r_refdef.view.ismain)
+       if(ismain)
        {
                // set the main view
                csqc_main_r_refdef_view = r_refdef.view;
-
-               // clear the flags so no other view becomes "main" unless CSQC sets VF_MAINVIEW
-               r_refdef.view.ismain = false;
-               csqc_original_r_refdef_view.ismain = false;
        }
 
        // we need to update any RENDER_VIEWMODEL entities at this point because
@@ -3280,6 +3277,14 @@ static void VM_CL_R_RenderScene (prvm_prog_t *prog)
        // callprofile fixing hack: do not include this time in what is counted for CSQC_UpdateView
        t = Sys_DirtyTime() - t;if (t < 0 || t >= 1800) t = 0;
        prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= t;
+
+       // update the views
+       if (ismain)
+       {
+               // clear the flags so no other view becomes "main" unless CSQC sets VF_MAINVIEW
+               r_refdef.view.ismain = false;
+               csqc_original_r_refdef_view.ismain = false;
+       }
 }
 
 //void(string texturename, float flag[, float is2d]) R_BeginPolygon
index 3e609ea..f0a01a2 100644 (file)
--- a/csprogs.c
+++ b/csprogs.c
@@ -476,7 +476,6 @@ qboolean CL_VM_UpdateView (double frametime)
                return false;
        R_TimeReport("pre-UpdateView");
        CSQC_BEGIN
-               r_refdef.view.ismain = true;
                csqc_original_r_refdef_view = r_refdef.view;
                csqc_main_r_refdef_view = r_refdef.view;
                //VectorCopy(cl.viewangles, oldangles);
index 386d12f..5eaff43 100644 (file)
@@ -5474,15 +5474,15 @@ static void R_View_SetFrustum(const int *scissor)
        }
        else
        {
-               VectorScale(left, -r_refdef.view.ortho_x, r_refdef.view.frustum[0].normal);
-               VectorScale(left,  r_refdef.view.ortho_x, r_refdef.view.frustum[1].normal);
-               VectorScale(up, -r_refdef.view.ortho_y, r_refdef.view.frustum[2].normal);
-               VectorScale(up,  r_refdef.view.ortho_y, r_refdef.view.frustum[3].normal);
-               VectorCopy(forward, r_refdef.view.frustum[4].normal);
-               r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[0].normal) + r_refdef.view.ortho_x;
-               r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[1].normal) + r_refdef.view.ortho_x;
-               r_refdef.view.frustum[2].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[2].normal) + r_refdef.view.ortho_y;
-               r_refdef.view.frustum[3].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[3].normal) + r_refdef.view.ortho_y;
+               VectorScale(forward, -1.0f, r_refdef.view.frustum[0].normal);
+               VectorScale(forward,  1.0f, r_refdef.view.frustum[1].normal);
+               VectorScale(left, -1.0f, r_refdef.view.frustum[2].normal);
+               VectorScale(left,  1.0f, r_refdef.view.frustum[3].normal);
+               VectorScale(up, -1.0f, r_refdef.view.frustum[4].normal);
+               r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[0].normal) - r_refdef.view.ortho_x;
+               r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[1].normal) - r_refdef.view.ortho_x;
+               r_refdef.view.frustum[2].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[2].normal) - r_refdef.view.ortho_y;
+               r_refdef.view.frustum[3].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[3].normal) - r_refdef.view.ortho_y;
                r_refdef.view.frustum[4].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[4].normal) + r_refdef.nearclip;
        }
        r_refdef.view.numfrustumplanes = 5;
@@ -6920,6 +6920,8 @@ R_RenderView
 */
 int dpsoftrast_test;
 extern cvar_t r_shadow_bouncegrid;
+extern cvar_t v_isometric;
+extern void V_MakeViewIsometric(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;
@@ -6978,6 +6980,9 @@ void R_RenderView(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, i
                return;
        }
 
+       if (v_isometric.integer && r_refdef.view.ismain)
+               V_MakeViewIsometric();
+
        r_refdef.view.colorscale = r_hdr_scenebrightness.value * r_hdr_irisadaptation_value.value;
 
        if(vid_sRGB.integer && vid_sRGB_fallback.integer && !vid.sRGB3D)
index d0477c3..84027b1 100644 (file)
@@ -487,7 +487,7 @@ void R_View_WorldVisibility(qboolean forcenovis)
 
                // if floating around in the void (no pvs data available, and no
                // portals available), simply use all on-screen leafs.
-               if (!viewleaf || viewleaf->clusterindex < 0 || forcenovis || r_trippy.integer)
+               if (!viewleaf || viewleaf->clusterindex < 0 || forcenovis || r_trippy.integer || !r_refdef.view.useperspective)
                {
                        // no visibility method: (used when floating around in the void)
                        // simply cull each leaf to the frustum (view pyramid)
diff --git a/view.c b/view.c
index cb352ef..df73f19 100644 (file)
--- a/view.c
+++ b/view.c
@@ -92,6 +92,25 @@ cvar_t v_ipitch_level = {0, "v_ipitch_level", "0.3", "v_idlescale pitch amount"}
 
 cvar_t v_idlescale = {0, "v_idlescale", "0", "how much of the quake 'drunken view' effect to use"};
 
+cvar_t v_isometric = {0, "v_isometric", "0", "changes view to isometric (non-perspective)"};
+cvar_t v_isometric_verticalfov = { 0, "v_isometric_verticalfov", "512", "vertical field of view in game units (horizontal is computed using aspect ratio based on this)"};
+cvar_t v_isometric_xx = {0, "v_isometric_xx", "0", "camera matrix"};
+cvar_t v_isometric_xy = {0, "v_isometric_xy", "-1", "camera matrix"};
+cvar_t v_isometric_xz = {0, "v_isometric_xz", "0", "camera matrix"};
+cvar_t v_isometric_yx = {0, "v_isometric_yx", "-1", "camera matrix"};
+cvar_t v_isometric_yy = {0, "v_isometric_yy", "0", "camera matrix"};
+cvar_t v_isometric_yz = {0, "v_isometric_yz", "0", "camera matrix"};
+cvar_t v_isometric_zx = {0, "v_isometric_zx", "0", "camera matrix"};
+cvar_t v_isometric_zy = {0, "v_isometric_zy", "0", "camera matrix"};
+cvar_t v_isometric_zz = {0, "v_isometric_zz", "1", "camera matrix"};
+cvar_t v_isometric_tx = {0, "v_isometric_tx", "1767", "camera position"};
+cvar_t v_isometric_ty = {0, "v_isometric_ty", "1767", "camera position"};
+cvar_t v_isometric_tz = {0, "v_isometric_tz", "1425", "camera position"};
+cvar_t v_isometric_rot_pitch = {0, "v_isometric_rot_pitch", "0", "camera rotation"};
+cvar_t v_isometric_rot_yaw = {0, "v_isometric_rot_yaw", "-45", "camera rotation"};
+cvar_t v_isometric_rot_roll = {0, "v_isometric_rot_roll", "-60", "camera rotation"};
+cvar_t v_isometric_locked_orientation = {0, "v_isometric_locked_orientation", "1", "camera rotation is fixed"};
+
 cvar_t crosshair = {CVAR_SAVE, "crosshair", "0", "selects crosshair to use (0 is none)"};
 
 cvar_t v_centermove = {0, "v_centermove", "0.15", "how long before the view begins to center itself (if freelook/+mlook/+jlook/+klook are off)"};
@@ -943,6 +962,45 @@ void V_CalcRefdef (void)
        }
 }
 
+void V_MakeViewIsometric(void)
+{
+       // when using isometric view to play normal games we have to rotate the camera to make the Ortho matrix do the right thing (forward as up the screen, etc)
+       matrix4x4_t relative;
+       matrix4x4_t modifiedview;
+       matrix4x4_t modify;
+       float t[4][4];
+       t[0][0] = v_isometric_xx.value;
+       t[0][1] = v_isometric_xy.value;
+       t[0][2] = v_isometric_xz.value;
+       t[0][3] = 0.0f;
+       t[1][0] = v_isometric_yx.value;
+       t[1][1] = v_isometric_yy.value;
+       t[1][2] = v_isometric_yz.value;
+       t[1][3] = 0.0f;
+       t[2][0] = v_isometric_zx.value;
+       t[2][1] = v_isometric_zy.value;
+       t[2][2] = v_isometric_zz.value;
+       t[2][3] = 0.0f;
+       t[3][0] = 0.0f;
+       t[3][1] = 0.0f;
+       t[3][2] = 0.0f;
+       t[3][3] = 1.0f;
+       Matrix4x4_FromArrayFloatGL(&modify, t[0]);
+
+       // if the orientation is locked, extract the origin and create just a translate matrix to start with
+       if (v_isometric_locked_orientation.integer)
+       {
+               vec3_t vx, vy, vz, origin;
+               Matrix4x4_ToVectors(&r_refdef.view.matrix, vx, vy, vz, origin);
+               Matrix4x4_CreateTranslate(&r_refdef.view.matrix, origin[0], origin[1], origin[2]);
+       }
+
+       Matrix4x4_Concat(&modifiedview, &r_refdef.view.matrix, &modify);
+       Matrix4x4_CreateFromQuakeEntity(&relative, v_isometric_tx.value, v_isometric_ty.value, v_isometric_tz.value, v_isometric_rot_pitch.value, v_isometric_rot_yaw.value, v_isometric_rot_roll.value, 1.0f);
+       Matrix4x4_Concat(&r_refdef.view.matrix, &modifiedview, &relative);
+}
+
+
 void V_FadeViewFlashs(void)
 {
        // don't flash if time steps backwards
@@ -1125,6 +1183,25 @@ void V_Init (void)
        Cvar_RegisterVariable (&v_iroll_level);
        Cvar_RegisterVariable (&v_ipitch_level);
 
+       Cvar_RegisterVariable(&v_isometric);
+       Cvar_RegisterVariable(&v_isometric_verticalfov);
+       Cvar_RegisterVariable(&v_isometric_xx);
+       Cvar_RegisterVariable(&v_isometric_xy);
+       Cvar_RegisterVariable(&v_isometric_xz);
+       Cvar_RegisterVariable(&v_isometric_yx);
+       Cvar_RegisterVariable(&v_isometric_yy);
+       Cvar_RegisterVariable(&v_isometric_yz);
+       Cvar_RegisterVariable(&v_isometric_zx);
+       Cvar_RegisterVariable(&v_isometric_zy);
+       Cvar_RegisterVariable(&v_isometric_zz);
+       Cvar_RegisterVariable(&v_isometric_tx);
+       Cvar_RegisterVariable(&v_isometric_ty);
+       Cvar_RegisterVariable(&v_isometric_tz);
+       Cvar_RegisterVariable(&v_isometric_rot_pitch);
+       Cvar_RegisterVariable(&v_isometric_rot_yaw);
+       Cvar_RegisterVariable(&v_isometric_rot_roll);
+       Cvar_RegisterVariable(&v_isometric_locked_orientation);
+
        Cvar_RegisterVariable (&v_idlescale);
        Cvar_RegisterVariable (&crosshair);