From: havoc Date: Wed, 30 Dec 2009 16:42:21 +0000 (+0000) Subject: fix water rendering bugs where the clipping plane was not being used X-Git-Tag: xonotic-v0.1.0preview~897 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=6758dd9c9766a9ea9ad03b95ac3f5968768be9fe fix water rendering bugs where the clipping plane was not being used git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9751 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/client.h b/client.h index 38cf7b84..525754b5 100644 --- a/client.h +++ b/client.h @@ -1520,7 +1520,6 @@ r_viewport_type_t; typedef struct r_viewport_s { - float m[16]; matrix4x4_t cameramatrix; // from entity (transforms from camera entity to world) matrix4x4_t viewmatrix; // actual matrix for rendering (transforms to viewspace) matrix4x4_t projectmatrix; // actual projection matrix (transforms from viewspace to screen) diff --git a/gl_backend.c b/gl_backend.c index bfcf1707..4cbcce2e 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -312,7 +312,7 @@ void R_Viewport_TransformToScreen(const r_viewport_t *v, const vec4_t in, vec4_t out[2] = v->z + (out[2] * iw + 1.0f) * v->depth * 0.5f; } -static void R_Viewport_ApplyNearClipPlane(r_viewport_t *v, float normalx, float normaly, float normalz, float dist) +static void R_Viewport_ApplyNearClipPlaneFloatGL(const r_viewport_t *v, float *m, float normalx, float normaly, float normalz, float dist) { float q[4]; float d; @@ -345,24 +345,25 @@ static void R_Viewport_ApplyNearClipPlane(r_viewport_t *v, float normalx, float // as (sgn(clipPlane.x), sgn(clipPlane.y), 1, 1) and // transform it into camera space by multiplying it // by the inverse of the projection matrix - q[0] = ((clipPlane[0] < 0.0f ? -1.0f : clipPlane[0] > 0.0f ? 1.0f : 0.0f) + v->m[8]) / v->m[0]; - q[1] = ((clipPlane[1] < 0.0f ? -1.0f : clipPlane[1] > 0.0f ? 1.0f : 0.0f) + v->m[9]) / v->m[5]; + q[0] = ((clipPlane[0] < 0.0f ? -1.0f : clipPlane[0] > 0.0f ? 1.0f : 0.0f) + m[8]) / m[0]; + q[1] = ((clipPlane[1] < 0.0f ? -1.0f : clipPlane[1] > 0.0f ? 1.0f : 0.0f) + m[9]) / m[5]; q[2] = -1.0f; - q[3] = (1.0f + v->m[10]) / v->m[14]; + q[3] = (1.0f + m[10]) / m[14]; // Calculate the scaled plane vector d = 2.0f / DotProduct4(clipPlane, q); // Replace the third row of the projection matrix - v->m[2] = clipPlane[0] * d; - v->m[6] = clipPlane[1] * d; - v->m[10] = clipPlane[2] * d + 1.0f; - v->m[14] = clipPlane[3] * d; + m[2] = clipPlane[0] * d; + m[6] = clipPlane[1] * d; + m[10] = clipPlane[2] * d + 1.0f; + m[14] = clipPlane[3] * d; } 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 nearclip, float farclip, const float *nearplane) { float left = x1, right = x2, bottom = y2, top = y1, zNear = nearclip, zFar = farclip; + float m[16]; memset(v, 0, sizeof(*v)); v->type = R_VIEWPORTTYPE_ORTHO; v->cameramatrix = *cameramatrix; @@ -372,21 +373,23 @@ void R_Viewport_InitOrtho(r_viewport_t *v, const matrix4x4_t *cameramatrix, int v->width = width; v->height = height; v->depth = 1; - v->m[0] = 2/(right - left); - v->m[5] = 2/(top - bottom); - v->m[10] = -2/(zFar - zNear); - v->m[12] = - (right + left)/(right - left); - v->m[13] = - (top + bottom)/(top - bottom); - v->m[14] = - (zFar + zNear)/(zFar - zNear); - v->m[15] = 1; + memset(m, 0, sizeof(m)); + m[0] = 2/(right - left); + m[5] = 2/(top - bottom); + m[10] = -2/(zFar - zNear); + m[12] = - (right + left)/(right - left); + m[13] = - (top + bottom)/(top - bottom); + m[14] = - (zFar + zNear)/(zFar - zNear); + m[15] = 1; v->screentodepth[0] = -farclip / (farclip - nearclip); v->screentodepth[1] = farclip * nearclip / (farclip - nearclip); Matrix4x4_Invert_Full(&v->viewmatrix, &v->cameramatrix); - Matrix4x4_FromArrayFloatGL(&v->projectmatrix, v->m); if (nearplane) - R_Viewport_ApplyNearClipPlane(v, nearplane[0], nearplane[1], nearplane[2], nearplane[3]); + R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]); + + Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m); #if 0 { @@ -402,6 +405,7 @@ void R_Viewport_InitOrtho(r_viewport_t *v, const matrix4x4_t *cameramatrix, int 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; + float m[16]; memset(v, 0, sizeof(*v)); if(v_flipped.integer) @@ -415,11 +419,12 @@ void R_Viewport_InitPerspective(r_viewport_t *v, const matrix4x4_t *cameramatrix v->width = width; v->height = height; v->depth = 1; - v->m[0] = 1.0 / frustumx; - v->m[5] = 1.0 / frustumy; - v->m[10] = -(farclip + nearclip) / (farclip - nearclip); - v->m[11] = -1; - v->m[14] = -2 * nearclip * farclip / (farclip - nearclip); + memset(m, 0, sizeof(m)); + m[0] = 1.0 / frustumx; + m[5] = 1.0 / frustumy; + m[10] = -(farclip + nearclip) / (farclip - nearclip); + m[11] = -1; + m[14] = -2 * nearclip * farclip / (farclip - nearclip); v->screentodepth[0] = -farclip / (farclip - nearclip); v->screentodepth[1] = farclip * nearclip / (farclip - nearclip); @@ -428,16 +433,17 @@ void R_Viewport_InitPerspective(r_viewport_t *v, const matrix4x4_t *cameramatrix Matrix4x4_ConcatRotate(&basematrix, 90, 0, 0, 1); Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix); - Matrix4x4_FromArrayFloatGL(&v->projectmatrix, v->m); - if (nearplane) - R_Viewport_ApplyNearClipPlane(v, nearplane[0], nearplane[1], nearplane[2], nearplane[3]); + R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]); + + Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m); } 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 nearclip, const float *nearplane) { matrix4x4_t tempmatrix, basematrix; const float nudge = 1.0 - 1.0 / (1<<23); + float m[16]; memset(v, 0, sizeof(*v)); if(v_flipped.integer) @@ -451,23 +457,24 @@ void R_Viewport_InitPerspectiveInfinite(r_viewport_t *v, const matrix4x4_t *came v->width = width; v->height = height; v->depth = 1; - v->m[ 0] = 1.0 / frustumx; - v->m[ 5] = 1.0 / frustumy; - v->m[10] = -nudge; - v->m[11] = -1; - v->m[14] = -2 * nearclip * nudge; - v->screentodepth[0] = (v->m[10] + 1) * 0.5 - 1; - v->screentodepth[1] = v->m[14] * -0.5; + memset(m, 0, sizeof(m)); + m[ 0] = 1.0 / frustumx; + m[ 5] = 1.0 / frustumy; + m[10] = -nudge; + m[11] = -1; + m[14] = -2 * nearclip * nudge; + v->screentodepth[0] = (m[10] + 1) * 0.5 - 1; + v->screentodepth[1] = m[14] * -0.5; 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); - Matrix4x4_FromArrayFloatGL(&v->projectmatrix, v->m); - if (nearplane) - R_Viewport_ApplyNearClipPlane(v, nearplane[0], nearplane[1], nearplane[2], nearplane[3]); + R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]); + + Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m); } float cubeviewmatrix[6][16] = @@ -554,29 +561,33 @@ float rectviewmatrix[6][16] = void R_Viewport_InitCubeSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, float nearclip, float farclip, const float *nearplane) { matrix4x4_t tempmatrix, basematrix; + float m[16]; memset(v, 0, sizeof(*v)); v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE; v->cameramatrix = *cameramatrix; v->width = size; v->height = size; v->depth = 1; - v->m[0] = v->m[5] = 1.0f; - v->m[10] = -(farclip + nearclip) / (farclip - nearclip); - v->m[11] = -1; - v->m[14] = -2 * nearclip * farclip / (farclip - nearclip); + memset(m, 0, sizeof(m)); + m[0] = m[5] = 1.0f; + m[10] = -(farclip + nearclip) / (farclip - nearclip); + m[11] = -1; + m[14] = -2 * nearclip * farclip / (farclip - nearclip); Matrix4x4_FromArrayFloatGL(&basematrix, cubeviewmatrix[side]); Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix); Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix); - Matrix4x4_FromArrayFloatGL(&v->projectmatrix, v->m); if (nearplane) - R_Viewport_ApplyNearClipPlane(v, nearplane[0], nearplane[1], nearplane[2], nearplane[3]); + R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]); + + Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m); } void R_Viewport_InitRectSideView(r_viewport_t *v, const matrix4x4_t *cameramatrix, int side, int size, int border, float nearclip, float farclip, const float *nearplane) { matrix4x4_t tempmatrix, basematrix; + float m[16]; memset(v, 0, sizeof(*v)); v->type = R_VIEWPORTTYPE_PERSPECTIVECUBESIDE; v->cameramatrix = *cameramatrix; @@ -585,22 +596,25 @@ void R_Viewport_InitRectSideView(r_viewport_t *v, const matrix4x4_t *cameramatri v->width = size; v->height = size; v->depth = 1; - v->m[0] = v->m[5] = 1.0f * ((float)size - border) / size; - v->m[10] = -(farclip + nearclip) / (farclip - nearclip); - v->m[11] = -1; - v->m[14] = -2 * nearclip * farclip / (farclip - nearclip); + memset(m, 0, sizeof(m)); + m[0] = m[5] = 1.0f * ((float)size - border) / size; + m[10] = -(farclip + nearclip) / (farclip - nearclip); + m[11] = -1; + m[14] = -2 * nearclip * farclip / (farclip - nearclip); Matrix4x4_FromArrayFloatGL(&basematrix, rectviewmatrix[side]); Matrix4x4_Invert_Simple(&tempmatrix, &v->cameramatrix); Matrix4x4_Concat(&v->viewmatrix, &basematrix, &tempmatrix); - Matrix4x4_FromArrayFloatGL(&v->projectmatrix, v->m); if (nearplane) - R_Viewport_ApplyNearClipPlane(v, nearplane[0], nearplane[1], nearplane[2], nearplane[3]); + R_Viewport_ApplyNearClipPlaneFloatGL(v, m, nearplane[0], nearplane[1], nearplane[2], nearplane[3]); + + Matrix4x4_FromArrayFloatGL(&v->projectmatrix, m); } void R_SetViewport(const r_viewport_t *v) { + float m[16]; gl_viewport = *v; CHECKGLERROR @@ -622,7 +636,8 @@ void R_SetViewport(const r_viewport_t *v) case RENDERPATH_GL11: // Load the projection matrix into OpenGL qglMatrixMode(GL_PROJECTION);CHECKGLERROR - qglLoadMatrixf(gl_viewport.m);CHECKGLERROR + Matrix4x4_ToArrayFloatGL(&gl_projectionmatrix, m); + qglLoadMatrixf(m);CHECKGLERROR qglMatrixMode(GL_MODELVIEW);CHECKGLERROR break; } diff --git a/gl_rmain.c b/gl_rmain.c index 15f71f4a..057941f7 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -3630,6 +3630,7 @@ void R_SetupShader_SetPermutationGLSL(unsigned int mode, unsigned int permutatio qglUseProgramObjectARB(r_glsl_permutation->program);CHECKGLERROR } if (r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f); + if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f); } #ifdef SUPPORTCG @@ -4097,6 +4098,7 @@ void R_SetupShader_SetPermutationCG(unsigned int mode, unsigned int permutation) } CHECKCGERROR if (r_cg_permutation->vp_ModelViewProjectionMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewProjectionMatrix, gl_modelviewprojection16f);CHECKCGERROR + if (r_cg_permutation->vp_ModelViewMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewMatrix, gl_modelview16f);CHECKCGERROR } void CG_BindTexture(CGparameter param, int texnum) @@ -4533,7 +4535,6 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin); if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower * ((permutation & SHADERPERMUTATION_EXACTSPECULARMATH) ? 0.25f : 1.0f)); } - if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f); if (r_glsl_permutation->loc_TexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_TexMatrix, 1, false, m16f);} if (r_glsl_permutation->loc_BackgroundTexMatrix >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_BackgroundTexMatrix, 1, false, m16f);} if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Glow, rsurface.glowmod[0], rsurface.glowmod[1], rsurface.glowmod[2]); @@ -4609,7 +4610,6 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_cg_permutation->vp_LightDir) cgGLSetParameter3f(r_cg_permutation->vp_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);CHECKCGERROR } } - if (r_cg_permutation->vp_ModelViewMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewMatrix, gl_modelviewprojection16f);CHECKCGERROR if (r_cg_permutation->vp_TexMatrix) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currenttexmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_TexMatrix, m16f);}CHECKCGERROR if (r_cg_permutation->vp_BackgroundTexMatrix) {Matrix4x4_ToArrayFloatGL(&rsurface.texture->currentbackgroundtexmatrix, m16f);cgGLSetMatrixParameterfc(r_cg_permutation->vp_BackgroundTexMatrix, m16f);}CHECKCGERROR if (r_cg_permutation->vp_EyePosition) cgGLSetParameter3f(r_cg_permutation->vp_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]);CHECKCGERROR @@ -4797,7 +4797,6 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) { case RENDERPATH_GL20: R_SetupShader_SetPermutationGLSL(mode, permutation); - if (r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewMatrix , 1, false, gl_modelview16f); if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB( r_glsl_permutation->loc_LightPosition , viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]); if (r_glsl_permutation->loc_ViewToLight >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ViewToLight , 1, false, viewtolight16f); if (r_glsl_permutation->loc_DeferredColor_Ambient >= 0) qglUniform3fARB( r_glsl_permutation->loc_DeferredColor_Ambient , lightcolorbase[0] * ambientscale * range, lightcolorbase[1] * ambientscale * range, lightcolorbase[2] * ambientscale * range); @@ -4821,7 +4820,6 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) case RENDERPATH_CGGL: #ifdef SUPPORTCG R_SetupShader_SetPermutationCG(mode, permutation); - if (r_cg_permutation->vp_ModelViewMatrix ) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewMatrix, gl_modelviewprojection16f);CHECKCGERROR if (r_cg_permutation->fp_LightPosition ) cgGLSetParameter3f(r_cg_permutation->fp_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]);CHECKCGERROR if (r_cg_permutation->fp_ViewToLight ) cgGLSetMatrixParameterfc(r_cg_permutation->fp_ViewToLight, viewtolight16f);CHECKCGERROR if (r_cg_permutation->fp_DeferredColor_Ambient ) cgGLSetParameter3f(r_cg_permutation->fp_DeferredColor_Ambient , lightcolorbase[0] * ambientscale * range, lightcolorbase[1] * ambientscale * range, lightcolorbase[2] * ambientscale * range);CHECKCGERROR @@ -6587,12 +6585,14 @@ void R_EntityMatrix(const matrix4x4_t *matrix) { case RENDERPATH_GL20: if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewProjectionMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewProjectionMatrix, 1, false, gl_modelviewprojection16f); + if (r_glsl_permutation && r_glsl_permutation->loc_ModelViewMatrix >= 0) qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelViewMatrix, 1, false, gl_modelview16f); qglLoadMatrixf(gl_modelview16f);CHECKGLERROR break; case RENDERPATH_CGGL: #ifdef SUPPORTCG CHECKCGERROR if (r_cg_permutation && r_cg_permutation->vp_ModelViewProjectionMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewProjectionMatrix, gl_modelviewprojection16f);CHECKCGERROR + if (r_cg_permutation && r_cg_permutation->vp_ModelViewMatrix) cgGLSetMatrixParameterfc(r_cg_permutation->vp_ModelViewMatrix, gl_modelview16f);CHECKCGERROR qglLoadMatrixf(gl_modelview16f);CHECKGLERROR #endif break; @@ -6843,24 +6843,6 @@ static void R_Water_ProcessPlanes(void) r_waterstate.renderingscene = true; for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++) { - // render the normal view scene and copy into texture - // (except that a clipping plane should be used to hide everything on one side of the water, and the viewer's weapon model should be omitted) - if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION)) - { - r_refdef.view = myview; - r_refdef.view.clipplane = p->plane; - VectorNegate(r_refdef.view.clipplane.normal, r_refdef.view.clipplane.normal); - r_refdef.view.clipplane.dist = -r_refdef.view.clipplane.dist; - PlaneClassify(&r_refdef.view.clipplane); - - R_ResetViewRendering3D(); - R_ClearScreen(r_refdef.fogenabled); - R_View_Update(); - R_RenderScene(); - - 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); - } - if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION)) { r_refdef.view = myview; @@ -6888,6 +6870,25 @@ static void R_Water_ProcessPlanes(void) 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); } + + // render the normal view scene and copy into texture + // (except that a clipping plane should be used to hide everything on one side of the water, and the viewer's weapon model should be omitted) + if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION)) + { + r_refdef.view = myview; + r_refdef.view.clipplane = p->plane; + VectorNegate(r_refdef.view.clipplane.normal, r_refdef.view.clipplane.normal); + r_refdef.view.clipplane.dist = -r_refdef.view.clipplane.dist; + PlaneClassify(&r_refdef.view.clipplane); + + R_ResetViewRendering3D(); + R_ClearScreen(r_refdef.fogenabled); + R_View_Update(); + R_RenderScene(); + + 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_waterstate.renderingscene = false; r_refdef.view = originalview;