diff --git a/doc/040_cvarlist.md b/doc/040_cvarlist.md index 6467ff32..818a8ef8 100644 --- a/doc/040_cvarlist.md +++ b/doc/040_cvarlist.md @@ -153,7 +153,8 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable` * **r_gunfov**: The weapons are rendered with a custom field of view, independently of the global **fov**, so they are not distorted at high FOVs. A value of `75` should look identical to the old code at `fov - 90`, it defaults to `80` because that looks a bit better. + 90`, it defaults to `80` because that looks a bit better. Set to `-1` + for the same value as `fov`. * **horplus**: If set to 1 (the default) the horplus algorithm is used to calculate an optimal horizontal and vertical field of view, @@ -281,6 +282,12 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable` * **gl3_particle_square**: If set to `1`, particles are rendered as squares, like in the old software renderer or Quake 1. Default is `0`. +## Graphics (Software only) + +* **sw_gunzposition**: Z offset for the gun. In the original code this + was always `0`, which will draw the gun too near to the player if a + custom gun field of few is used. Defaults to `8`, which is more or + less optimal for the default gun field of view of 80. ## cvar operations diff --git a/src/client/refresh/gl1/gl1_mesh.c b/src/client/refresh/gl1/gl1_mesh.c index 65e902a6..91069521 100644 --- a/src/client/refresh/gl1/gl1_mesh.c +++ b/src/client/refresh/gl1/gl1_mesh.c @@ -664,22 +664,34 @@ R_DrawAliasModel(entity_t *e) if (currententity->flags & RF_WEAPONMODEL) { - extern void R_MYgluPerspective(GLdouble fovy, GLdouble aspect, - GLdouble zNear, GLdouble zFar); + extern void R_MYgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - if (gl_lefthand->value == 1.0F) - glScalef(-1, 1, 1); - R_MYgluPerspective(r_gunfov->value, // render weapon with a different FOV so it's not distorted at high view FOV - (float)r_newrefdef.width / r_newrefdef.height, - 4, 4096); + if (gl_lefthand->value == 1.0F) + { + glScalef(-1, 1, 1); + } + + float dist = (r_farsee->value == 0) ? 4096.0f : 8192.0f; + + if (r_gunfov->value < 0) + { + R_MYgluPerspective(r_newrefdef.fov_y, (float)r_newrefdef.width / r_newrefdef.height, 4, dist); + } + else + { + R_MYgluPerspective(r_gunfov->value, (float)r_newrefdef.width / r_newrefdef.height, 4, dist); + } + glMatrixMode(GL_MODELVIEW); if (gl_lefthand->value == 1.0F) + { glCullFace(GL_BACK); + } } glPushMatrix(); diff --git a/src/client/refresh/gl3/gl3_mesh.c b/src/client/refresh/gl3/gl3_mesh.c index 0fc1653a..8b60f776 100644 --- a/src/client/refresh/gl3/gl3_mesh.c +++ b/src/client/refresh/gl3/gl3_mesh.c @@ -816,7 +816,15 @@ GL3_DrawAliasModel(entity_t *entity) // render weapon with a different FOV (r_gunfov) so it's not distorted at high view FOV float screenaspect = (float)gl3_newrefdef.width / gl3_newrefdef.height; float dist = (r_farsee->value == 0) ? 4096.0f : 8192.0f; - gl3state.uni3DData.transProjMat4 = GL3_MYgluPerspective(r_gunfov->value, screenaspect, 4, dist); + + if (r_gunfov->value < 0) + { + gl3state.uni3DData.transProjMat4 = GL3_MYgluPerspective(gl3_newrefdef.fov_y, screenaspect, 4, dist); + } + else + { + gl3state.uni3DData.transProjMat4 = GL3_MYgluPerspective(r_gunfov->value, screenaspect, 4, dist); + } if(gl_lefthand->value == 1.0F) { diff --git a/src/client/refresh/soft/header/local.h b/src/client/refresh/soft/header/local.h index 8265cf85..b5c114fb 100644 --- a/src/client/refresh/soft/header/local.h +++ b/src/client/refresh/soft/header/local.h @@ -419,6 +419,7 @@ extern cvar_t *sw_mipscale; extern cvar_t *sw_stipplealpha; extern cvar_t *sw_surfcacheoverride; extern cvar_t *sw_waterwarp; +extern cvar_t *sw_gunzposition; extern cvar_t *r_fullbright; extern cvar_t *r_lefthand; diff --git a/src/client/refresh/soft/sw_alias.c b/src/client/refresh/soft/sw_alias.c index 5c411066..67a9ba1d 100644 --- a/src/client/refresh/soft/sw_alias.c +++ b/src/client/refresh/soft/sw_alias.c @@ -364,7 +364,7 @@ R_AliasSetUpTransform(const entity_t *currententity) { viewmatrix[0][3] = 0; viewmatrix[1][3] = 0; - viewmatrix[2][3] = 8; + viewmatrix[2][3] = sw_gunzposition->value; } else { @@ -723,9 +723,12 @@ R_AliasDrawModel(entity_t *currententity, const model_t *currentmodel) return; } - float gunfov = 2 * tan((float)r_gunfov->value / 360 * M_PI); - aliasxscale = ((float)r_refdef.vrect.width / gunfov) * r_aliasuvscale; - aliasyscale = aliasxscale; + if (r_gunfov->value >= 0) + { + float gunfov = 2 * tan((float)r_gunfov->value / 360 * M_PI); + aliasxscale = ((float)r_refdef.vrect.width / gunfov) * r_aliasuvscale; + aliasyscale = aliasxscale; + } if ( r_lefthand->value == 1.0F ) aliasxscale = -aliasxscale; diff --git a/src/client/refresh/soft/sw_main.c b/src/client/refresh/soft/sw_main.c index 77fd7777..cf6c6e96 100644 --- a/src/client/refresh/soft/sw_main.c +++ b/src/client/refresh/soft/sw_main.c @@ -146,6 +146,7 @@ static cvar_t *sw_overbrightbits; cvar_t *sw_custom_particles; cvar_t *sw_texture_filtering; cvar_t *sw_retexturing; +cvar_t *sw_gunzposition; static cvar_t *sw_partialrefresh; cvar_t *r_drawworld; @@ -372,6 +373,7 @@ R_RegisterVariables (void) sw_custom_particles = ri.Cvar_Get("sw_custom_particles", "0", CVAR_ARCHIVE); sw_texture_filtering = ri.Cvar_Get("sw_texture_filtering", "0", CVAR_ARCHIVE); sw_retexturing = ri.Cvar_Get("sw_retexturing", "0", CVAR_ARCHIVE); + sw_gunzposition = ri.Cvar_Get("sw_gunzposition", "8", CVAR_ARCHIVE); // On MacOS texture is cleaned up after render and code have to copy a whole // screen to texture, other platforms save previous texture content and can be