r_refdef.view.z = 0;
}
- 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
- }
+ // 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,
vec3_t frustumcorner[4];
// if turned off it renders an ortho view
int useperspective;
+ // allows visibility culling based on the view origin (e.g. pvs and R_CanSeeBox)
+ // this is turned off by:
+ // r_trippy
+ // !r_refdef.view.useperspective
+ // (sometimes) r_refdef.view.useclipplane
+ int usevieworiginculling;
float ortho_x, ortho_y;
// screen area to render in
#endif
}
+void R_Viewport_InitOrtho3D(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float nearclip, float farclip, const float *nearplane)
+{
+ matrix4x4_t tempmatrix, basematrix;
+ float m[16];
+ memset(v, 0, sizeof(*v));
+
+ v->type = R_VIEWPORTTYPE_PERSPECTIVE;
+ v->cameramatrix = *cameramatrix;
+ v->x = x;
+ v->y = y;
+ v->z = 0;
+ v->width = width;
+ v->height = height;
+ v->depth = 1;
+ memset(m, 0, sizeof(m));
+ m[0] = 1.0 / frustumx;
+ m[5] = 1.0 / frustumy;
+ m[10] = -2 / (farclip - nearclip);
+ m[14] = -(farclip + nearclip) / (farclip - nearclip);
+ m[15] = 1;
+ v->screentodepth[0] = -farclip / (farclip - nearclip);
+ v->screentodepth[1] = farclip * nearclip / (farclip - nearclip);
+
+ Matrix4x4_Invert_Full(&tempmatrix, &v->cameramatrix);
+ Matrix4x4_CreateRotate(&basematrix, -90, 1, 0, 0);
+ Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1);
+ Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix);
+
+ if (nearplane)
+ R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]);
+
+ if(v_flipped.integer)
+ {
+ m[0] = -m[0];
+ m[4] = -m[4];
+ m[8] = -m[8];
+ m[12] = -m[12];
+ }
+
+ Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m);
+}
+
void R_Viewport_InitPerspective(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float nearclip, float farclip, const float *nearplane)
{
matrix4x4_t tempmatrix, basematrix;
void R_Viewport_TransformToScreen(const r_viewport_t *v, const vec4_t in, vec4_t out);
qboolean R_ScissorForBBox(const float *mins, const float *maxs, int *scissor);
void R_Viewport_InitOrtho(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float x1, float y1, float x2, float y2, float zNear, float zFar, const float *nearplane);
+void R_Viewport_InitOrtho3D(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float nearclip, float farclip, const float *nearplane);
void R_Viewport_InitPerspective(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float zNear, float zFar, const float *nearplane);
void R_Viewport_InitPerspectiveInfinite(r_viewport_t *v, const matrix4x4_t *cameramatrix, int x, int y, int width, int height, float frustumx, float frustumy, float zNear, const float *nearplane);
void R_Viewport_InitCubeSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, float nearclip, float farclip, const float *nearplane);
return true;
// view origin is not used for culling in portal/reflection/refraction renders or isometric views
- if (r_refdef.view.useclipplane || !r_refdef.view.useperspective || r_trippy.integer)
+ if (!r_refdef.view.usevieworiginculling)
return true;
if (!r_cullentities_trace_entityocclusion.integer && (!model || !model->brush.TraceLineOfSight))
}
else
{
- 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);
+ VectorScale(left, -1.0f, r_refdef.view.frustum[0].normal);
+ VectorScale(left, 1.0f, r_refdef.view.frustum[1].normal);
+ VectorScale(up, -1.0f, r_refdef.view.frustum[2].normal);
+ VectorScale(up, 1.0f, r_refdef.view.frustum[3].normal);
+ VectorScale(forward, -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.frustum[4].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[4].normal) - r_refdef.farclip;
}
r_refdef.view.numfrustumplanes = 5;
{
R_Main_ResizeViewCache();
R_View_SetFrustum(myscissor);
- R_View_WorldVisibility(r_refdef.view.useclipplane);
+ R_View_WorldVisibility(!r_refdef.view.usevieworiginculling);
R_View_UpdateEntityVisible();
}
{
R_Main_ResizeViewCache();
R_View_SetFrustum(NULL);
- R_View_WorldVisibility(r_refdef.view.useclipplane);
+ R_View_WorldVisibility(!r_refdef.view.usevieworiginculling);
R_View_UpdateEntityVisible();
}
rtheight = viewfbo ? R_TextureHeight(viewdepthtexture ? viewdepthtexture : viewcolortexture) : vid.height;
if (!r_refdef.view.useperspective)
- 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);
+ R_Viewport_InitOrtho3D(&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.farclip, r_refdef.farclip, customclipplane);
else if (vid.stencil && r_useinfinitefarclip.integer)
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_refdef.view.clipplane = p->plane;
+ // reflected view origin may be in solid, so don't cull with it
+ r_refdef.view.usevieworiginculling = false;
// reverse the cullface settings for this render
r_refdef.view.cullface_front = GL_FRONT;
r_refdef.view.cullface_back = GL_BACK;
// camera needs no clipplane
r_refdef.view.useclipplane = false;
+ // TODO: is the camera origin always valid? if so we don't need to clear this
+ r_refdef.view.usevieworiginculling = false;
PlaneClassify(&r_refdef.view.clipplane);
return;
}
+ r_refdef.view.usevieworiginculling = !r_trippy.value && r_refdef.view.useperspective;
if (v_isometric.integer && r_refdef.view.ismain)
V_MakeViewIsometric();
// 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 || !r_refdef.view.useperspective)
+ if (!viewleaf || viewleaf->clusterindex < 0 || forcenovis || !r_refdef.view.usevieworiginculling)
{
// no visibility method: (used when floating around in the void)
// simply cull each leaf to the frustum (view pyramid)
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_xx = {0, "v_isometric_xx", "1", "camera matrix"};
+cvar_t v_isometric_xy = {0, "v_isometric_xy", "0", "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_yx = {0, "v_isometric_yx", "0", "camera matrix"};
+cvar_t v_isometric_yy = {0, "v_isometric_yy", "1", "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_tx = {0, "v_isometric_tx", "0", "camera position (player-relative)"};
+cvar_t v_isometric_ty = {0, "v_isometric_ty", "0", "camera position (player-relative)"};
+cvar_t v_isometric_tz = {0, "v_isometric_tz", "0", "camera position (player-relative)"};
+cvar_t v_isometric_rot_pitch = {0, "v_isometric_rot_pitch", "60", "camera rotation"};
+cvar_t v_isometric_rot_yaw = {0, "v_isometric_rot_yaw", "135", "camera rotation"};
+cvar_t v_isometric_rot_roll = {0, "v_isometric_rot_roll", "0", "camera rotation"};
+cvar_t v_isometric_relx = {0, "v_isometric_relx", "0", "camera position*forward"};
+cvar_t v_isometric_rely = {0, "v_isometric_rely", "0", "camera position*left"};
+cvar_t v_isometric_relz = {0, "v_isometric_relz", "0", "camera position*up"};
+cvar_t v_isometric_flipcullface = {0, "v_isometric_flipcullface", "0", "flips the backface culling"};
cvar_t v_isometric_locked_orientation = {0, "v_isometric_locked_orientation", "1", "camera rotation is fixed"};
+cvar_t v_isometric_usevieworiginculling = {0, "v_isometric_usevieworiginculling", "0", "check visibility to the player location (can look pretty weird)"};
cvar_t crosshair = {CVAR_SAVE, "crosshair", "0", "selects crosshair to use (0 is none)"};
matrix4x4_t relative;
matrix4x4_t modifiedview;
matrix4x4_t modify;
+ vec3_t forward, left, up, org;
float t[4][4];
+
+ r_refdef.view.useperspective = false;
+ r_refdef.view.usevieworiginculling = !r_trippy.value && v_isometric_usevieworiginculling.integer;
+ 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
+
t[0][0] = v_isometric_xx.value;
t[0][1] = v_isometric_xy.value;
t[0][2] = v_isometric_xz.value;
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);
+ Matrix4x4_ToVectors(&r_refdef.view.matrix, forward, left, up, org);
+ VectorMAMAMAM(1.0f, org, v_isometric_relx.value, forward, v_isometric_rely.value, left, v_isometric_relz.value, up, org);
+ Matrix4x4_FromVectors(&r_refdef.view.matrix, forward, left, up, org);
+
+ if (v_isometric_flipcullface.integer)
+ {
+ int a = r_refdef.view.cullface_front;
+ r_refdef.view.cullface_front = r_refdef.view.cullface_back;
+ r_refdef.view.cullface_back = a;
+ }
}
Cvar_RegisterVariable(&v_isometric_rot_pitch);
Cvar_RegisterVariable(&v_isometric_rot_yaw);
Cvar_RegisterVariable(&v_isometric_rot_roll);
+ Cvar_RegisterVariable(&v_isometric_relx);
+ Cvar_RegisterVariable(&v_isometric_rely);
+ Cvar_RegisterVariable(&v_isometric_relz);
+ Cvar_RegisterVariable(&v_isometric_flipcullface);
Cvar_RegisterVariable(&v_isometric_locked_orientation);
+ Cvar_RegisterVariable(&v_isometric_usevieworiginculling);
Cvar_RegisterVariable (&v_idlescale);
Cvar_RegisterVariable (&crosshair);