X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=gl_rmain.c;h=c2f6ad2f2c84a21b986045961c8805a8ea696f13;hb=682c13beba95014c89c25f8ebec398a32a831d83;hp=d80a304df2de2045192befbcaff3818a8cc35c70;hpb=0102c169b8d91364b969e57fca8d9533025648a7;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index d80a304d..c2f6ad2f 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -720,7 +720,7 @@ static const char *builtinshaderstring = " vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n" " //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n" " vec4 ScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect + vec2(normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5))).xyxy * DistortScaleRefractReflect;\n" -" float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 5.0) * ReflectFactor + ReflectOffset;\n" +" float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * ReflectFactor + ReflectOffset;\n" " gl_FragColor = mix(texture2D(Texture_Refraction, ScreenTexCoord.xy) * RefractColor, texture2D(Texture_Reflection, ScreenTexCoord.zw) * ReflectColor, Fresnel);\n" "}\n" "\n" @@ -767,9 +767,9 @@ static const char *builtinshaderstring = "#ifdef USEDIFFUSE\n" " // get the surface normal and the gloss color\n" "# ifdef USEVERTEXTEXTUREBLEND\n" -" myhalf3 surfacenormal = normalize(mix(myhalf3(texture2D(Texture_SecondaryNormal, TexCoord)), myhalf3(texture2D(Texture_Normal, TexCoord)), terrainblend)) - myhalf3(0.5));\n" +" myhalf3 surfacenormal = normalize(mix(myhalf3(texture2D(Texture_SecondaryNormal, TexCoord)), myhalf3(texture2D(Texture_Normal, TexCoord)), terrainblend) - myhalf3(0.5, 0.5, 0.5));\n" "# ifdef USESPECULAR\n" -" myhalf3 glosscolor = mix(myhalf3(texture2D(Texture_SecondaryGloss, TexCoord), myhalf3(texture2D(Texture_Gloss, TexCoord)), TexCoord), terrainblend);\n" +" myhalf3 glosscolor = mix(myhalf3(texture2D(Texture_SecondaryGloss, TexCoord)), myhalf3(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n" "# endif\n" "# else\n" " myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5));\n" @@ -958,13 +958,13 @@ shadermodeinfo_t; typedef enum shaderpermutation_e { - SHADERPERMUTATION_VERTEXTEXTUREBLEND = 1<<0, // indicates this is a two-layer material blend based on vertex alpha (q3bsp) - SHADERPERMUTATION_COLORMAPPING = 1<<1, // indicates this is a colormapped skin - SHADERPERMUTATION_CONTRASTBOOST = 1<<2, // r_glsl_contrastboost boosts the contrast at low color levels (similar to gamma) - SHADERPERMUTATION_FOG = 1<<3, // tint the color by fog color or black if using additive blend mode - SHADERPERMUTATION_CUBEFILTER = 1<<4, // (lightsource) use cubemap light filter - SHADERPERMUTATION_GLOW = 1<<5, // (lightmap) blend in an additive glow texture - SHADERPERMUTATION_DIFFUSE = 1<<6, // (lightsource) whether to use directional shading + SHADERPERMUTATION_DIFFUSE = 1<<0, // (lightsource) whether to use directional shading + SHADERPERMUTATION_VERTEXTEXTUREBLEND = 1<<1, // indicates this is a two-layer material blend based on vertex alpha (q3bsp) + SHADERPERMUTATION_COLORMAPPING = 1<<2, // indicates this is a colormapped skin + SHADERPERMUTATION_CONTRASTBOOST = 1<<3, // r_glsl_contrastboost boosts the contrast at low color levels (similar to gamma) + SHADERPERMUTATION_FOG = 1<<4, // tint the color by fog color or black if using additive blend mode + SHADERPERMUTATION_CUBEFILTER = 1<<5, // (lightsource) use cubemap light filter + SHADERPERMUTATION_GLOW = 1<<6, // (lightmap) blend in an additive glow texture SHADERPERMUTATION_SPECULAR = 1<<7, // (lightsource or deluxemapping) render specular effects SHADERPERMUTATION_REFLECTION = 1<<8, // normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface SHADERPERMUTATION_OFFSETMAPPING = 1<<9, // adjust texcoords to roughly simulate a displacement mapped surface @@ -977,13 +977,13 @@ shaderpermutation_t; // NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES! shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] = { + {"#define USEDIFFUSE\n", " diffuse"}, {"#define USEVERTEXTEXTUREBLEND\n", " vertextextureblend"}, {"#define USECOLORMAPPING\n", " colormapping"}, {"#define USECONTRASTBOOST\n", " contrastboost"}, {"#define USEFOG\n", " fog"}, {"#define USECUBEFILTER\n", " cubefilter"}, {"#define USEGLOW\n", " glow"}, - {"#define USEDIFFUSE\n", " diffuse"}, {"#define USESPECULAR\n", " specular"}, {"#define USEREFLECTION\n", " reflection"}, {"#define USEOFFSETMAPPING\n", " offsetmapping"}, @@ -1281,7 +1281,7 @@ void R_GLSL_DumpShader_f(void) FS_Print(file, "// #define VERTEX_SHADER\n// #define GEOMETRY_SHADER\n// #define FRAGMENT_SHADER\n"); for (i = 0;i < SHADERMODE_COUNT;i++) FS_Printf(file, "// %s", shadermodeinfo[i].pretext); - for (i = 0;i < SHADERPERMUTATION_LIMIT;i++) + for (i = 0;i < SHADERPERMUTATION_COUNT;i++) FS_Printf(file, "// %s", shaderpermutationinfo[i].pretext); FS_Print(file, "\n"); FS_Print(file, builtinshaderstring); @@ -2407,10 +2407,10 @@ static void R_View_SetFrustum(void) { int i; double slopex, slopey; + vec3_t forward, left, up, origin; - // break apart the view matrix into vectors for various purposes - Matrix4x4_ToVectors(&r_refdef.view.matrix, r_refdef.view.forward, r_refdef.view.left, r_refdef.view.up, r_refdef.view.origin); - VectorNegate(r_refdef.view.left, r_refdef.view.right); + // we can't trust r_refdef.view.forward and friends in reflected scenes + Matrix4x4_ToVectors(&r_refdef.view.matrix, forward, left, up, origin); #if 0 r_refdef.view.frustum[0].normal[0] = 0 - 1.0 / r_refdef.view.frustum_x; @@ -2478,11 +2478,11 @@ static void R_View_SetFrustum(void) { slopex = 1.0 / r_refdef.view.frustum_x; slopey = 1.0 / r_refdef.view.frustum_y; - VectorMA(r_refdef.view.forward, -slopex, r_refdef.view.left, r_refdef.view.frustum[0].normal); - VectorMA(r_refdef.view.forward, slopex, r_refdef.view.left, r_refdef.view.frustum[1].normal); - VectorMA(r_refdef.view.forward, -slopey, r_refdef.view.up , r_refdef.view.frustum[2].normal); - VectorMA(r_refdef.view.forward, slopey, r_refdef.view.up , r_refdef.view.frustum[3].normal); - VectorCopy(r_refdef.view.forward, r_refdef.view.frustum[4].normal); + VectorMA(forward, -slopex, left, r_refdef.view.frustum[0].normal); + VectorMA(forward, slopex, left, r_refdef.view.frustum[1].normal); + VectorMA(forward, -slopey, up , r_refdef.view.frustum[2].normal); + VectorMA(forward, slopey, up , r_refdef.view.frustum[3].normal); + VectorCopy(forward, r_refdef.view.frustum[4].normal); // Leaving those out was a mistake, those were in the old code, and they // fix a reproducable bug in this one: frustum culling got fucked up when viewmatrix was an identity matrix @@ -2493,10 +2493,10 @@ static void R_View_SetFrustum(void) VectorNormalize(r_refdef.view.frustum[3].normal); // calculate frustum corners, which are used to calculate deformed frustum planes for shadow caster culling - VectorMAMAMAM(1, r_refdef.view.origin, 1024, r_refdef.view.forward, -1024 * slopex, r_refdef.view.left, -1024 * slopey, r_refdef.view.up, r_refdef.view.frustumcorner[0]); - VectorMAMAMAM(1, r_refdef.view.origin, 1024, r_refdef.view.forward, 1024 * slopex, r_refdef.view.left, -1024 * slopey, r_refdef.view.up, r_refdef.view.frustumcorner[1]); - VectorMAMAMAM(1, r_refdef.view.origin, 1024, r_refdef.view.forward, -1024 * slopex, r_refdef.view.left, 1024 * slopey, r_refdef.view.up, r_refdef.view.frustumcorner[2]); - VectorMAMAMAM(1, r_refdef.view.origin, 1024, r_refdef.view.forward, 1024 * slopex, r_refdef.view.left, 1024 * slopey, r_refdef.view.up, r_refdef.view.frustumcorner[3]); + VectorMAMAMAM(1, r_refdef.view.origin, 1024, forward, -1024 * slopex, left, -1024 * slopey, up, r_refdef.view.frustumcorner[0]); + VectorMAMAMAM(1, r_refdef.view.origin, 1024, forward, 1024 * slopex, left, -1024 * slopey, up, r_refdef.view.frustumcorner[1]); + VectorMAMAMAM(1, r_refdef.view.origin, 1024, forward, -1024 * slopex, left, 1024 * slopey, up, r_refdef.view.frustumcorner[2]); + VectorMAMAMAM(1, r_refdef.view.origin, 1024, forward, 1024 * slopex, left, 1024 * slopey, up, r_refdef.view.frustumcorner[3]); r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[0].normal); r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, r_refdef.view.frustum[1].normal); @@ -2506,11 +2506,11 @@ static void R_View_SetFrustum(void) } else { - VectorScale(r_refdef.view.left, -r_refdef.view.ortho_x, r_refdef.view.frustum[0].normal); - VectorScale(r_refdef.view.left, r_refdef.view.ortho_x, r_refdef.view.frustum[1].normal); - VectorScale(r_refdef.view.up, -r_refdef.view.ortho_y, r_refdef.view.frustum[2].normal); - VectorScale(r_refdef.view.up, r_refdef.view.ortho_y, r_refdef.view.frustum[3].normal); - VectorCopy(r_refdef.view.forward, r_refdef.view.frustum[4].normal); + 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; @@ -2533,27 +2533,27 @@ static void R_View_SetFrustum(void) // Quake2 has it disabled as well. // rotate R_VIEWFORWARD right by FOV_X/2 degrees - //RotatePointAroundVector( r_refdef.view.frustum[0].normal, r_refdef.view.up, r_refdef.view.forward, -(90 - r_refdef.fov_x / 2)); + //RotatePointAroundVector( r_refdef.view.frustum[0].normal, up, forward, -(90 - r_refdef.fov_x / 2)); //r_refdef.view.frustum[0].dist = DotProduct (r_refdef.view.origin, frustum[0].normal); //PlaneClassify(&frustum[0]); // rotate R_VIEWFORWARD left by FOV_X/2 degrees - //RotatePointAroundVector( r_refdef.view.frustum[1].normal, r_refdef.view.up, r_refdef.view.forward, (90 - r_refdef.fov_x / 2)); + //RotatePointAroundVector( r_refdef.view.frustum[1].normal, up, forward, (90 - r_refdef.fov_x / 2)); //r_refdef.view.frustum[1].dist = DotProduct (r_refdef.view.origin, frustum[1].normal); //PlaneClassify(&frustum[1]); // rotate R_VIEWFORWARD up by FOV_X/2 degrees - //RotatePointAroundVector( r_refdef.view.frustum[2].normal, r_refdef.view.left, r_refdef.view.forward, -(90 - r_refdef.fov_y / 2)); + //RotatePointAroundVector( r_refdef.view.frustum[2].normal, left, forward, -(90 - r_refdef.fov_y / 2)); //r_refdef.view.frustum[2].dist = DotProduct (r_refdef.view.origin, frustum[2].normal); //PlaneClassify(&frustum[2]); // rotate R_VIEWFORWARD down by FOV_X/2 degrees - //RotatePointAroundVector( r_refdef.view.frustum[3].normal, r_refdef.view.left, r_refdef.view.forward, (90 - r_refdef.fov_y / 2)); + //RotatePointAroundVector( r_refdef.view.frustum[3].normal, left, forward, (90 - r_refdef.fov_y / 2)); //r_refdef.view.frustum[3].dist = DotProduct (r_refdef.view.origin, frustum[3].normal); //PlaneClassify(&frustum[3]); // nearclip plane - //VectorCopy(r_refdef.view.forward, r_refdef.view.frustum[4].normal); + //VectorCopy(forward, r_refdef.view.frustum[4].normal); //r_refdef.view.frustum[4].dist = DotProduct (r_refdef.view.origin, frustum[4].normal) + r_nearclip.value; //PlaneClassify(&frustum[4]); } @@ -2565,7 +2565,7 @@ void R_View_Update(void) R_View_UpdateEntityVisible(); } -void R_SetupView(void) +void R_SetupView(qboolean allowwaterclippingplane) { if (!r_refdef.view.useperspective) GL_SetupView_Mode_Ortho(-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); @@ -2576,7 +2576,7 @@ void R_SetupView(void) GL_SetupView_Orientation_FromEntity(&r_refdef.view.matrix); - if (r_refdef.view.useclipplane) + if (r_refdef.view.useclipplane && allowwaterclippingplane) { // LordHavoc: couldn't figure out how to make this approach the vec_t dist = r_refdef.view.clipplane.dist - r_water_clippingplanebias.value; @@ -2631,7 +2631,7 @@ void R_ResetViewRendering3D(void) // GL is weird because it's bottom to top, r_refdef.view.y is top to bottom qglViewport(r_refdef.view.x, vid.height - (r_refdef.view.y + r_refdef.view.height), r_refdef.view.width, r_refdef.view.height);CHECKGLERROR - R_SetupView(); + R_SetupView(true); GL_Scissor(r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.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); @@ -2895,6 +2895,8 @@ static void R_Water_ProcessPlanes(void) { // render reflected scene and copy into texture Matrix4x4_Reflect(&r_refdef.view.matrix, p->plane.normal[0], p->plane.normal[1], p->plane.normal[2], p->plane.dist, -2); + // update the r_refdef.view.origin because otherwise the sky renders at the wrong location (amongst other problems) + Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, r_refdef.view.origin); r_refdef.view.clipplane = p->plane; // reverse the cullface settings for this render r_refdef.view.cullface_front = GL_FRONT; @@ -3423,6 +3425,14 @@ void R_RenderView(void) r_refdef.view.colorscale = r_hdr_scenebrightness.value; + // break apart the view matrix into vectors for various purposes + // it is important that this occurs outside the RenderScene function because that can be called from reflection renders, where the vectors come out wrong + // however the r_refdef.view.origin IS updated in RenderScene intentionally - otherwise the sky renders at the wrong origin, etc + Matrix4x4_ToVectors(&r_refdef.view.matrix, r_refdef.view.forward, r_refdef.view.left, r_refdef.view.up, r_refdef.view.origin); + VectorNegate(r_refdef.view.left, r_refdef.view.right); + // make an inverted copy of the view matrix for tracking sprites + Matrix4x4_Invert_Simple(&r_refdef.view.inverse_matrix, &r_refdef.view.matrix); + R_Shadow_UpdateWorldLightSelection(); R_Bloom_StartFrame(); @@ -3468,7 +3478,8 @@ static void R_DrawLocs(void); static void R_DrawEntityBBoxes(void); void R_RenderScene(qboolean addwaterplanes) { - Matrix4x4_Invert_Simple(&r_refdef.view.inverse_matrix, &r_refdef.view.matrix); + r_refdef.stats.renders++; + R_UpdateFogColor(); if (addwaterplanes) @@ -3922,6 +3933,7 @@ void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_ } else GL_CullFace(r_refdef.view.cullface_back); + GL_CullFace(GL_NONE); GL_DepthMask(false); GL_DepthRange(0, depthshort ? 0.0625 : 1); @@ -4194,14 +4206,16 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) t->currentmaterialflags |= MATERIALFLAG_SHORTDEPTHRANGE; if (ent->flags & RENDER_VIEWMODEL) t->currentmaterialflags |= MATERIALFLAG_SHORTDEPTHRANGE; - if (t->backgroundnumskinframes && !(t->currentmaterialflags & MATERIALFLAG_BLENDED)) + if (t->backgroundnumskinframes) t->currentmaterialflags |= MATERIALFLAG_VERTEXTEXTUREBLEND; - if (t->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST)) - t->currentmaterialflags |= MATERIALFLAG_SORTTRANSPARENT; - if (t->currentmaterialflags & (MATERIALFLAG_REFRACTION | MATERIALFLAG_WATER)) - t->currentmaterialflags &= ~MATERIALFLAG_SORTTRANSPARENT; + if (t->currentmaterialflags & MATERIALFLAG_BLENDED) + { + if (t->currentmaterialflags & (MATERIALFLAG_REFRACTION | MATERIALFLAG_WATERSHADER)) + t->currentmaterialflags &= ~MATERIALFLAG_BLENDED; + } + else + t->currentmaterialflags &= ~(MATERIALFLAG_REFRACTION | MATERIALFLAG_WATERSHADER); - // make sure that the waterscroll matrix is used on water surfaces when // there is no tcmod if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0) t->currenttexmatrix = r_waterscrollmatrix; @@ -5552,7 +5566,7 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, msurfa static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, msurface_t **texturesurfacelist) { // transparent sky would be ridiculous - if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SORTTRANSPARENT)) + if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) return; if (rsurface.mode != RSURFMODE_SKY) { @@ -5565,7 +5579,10 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, msurface_t **te if (skyrendernow) { skyrendernow = false; + // we have to force off the water clipping plane while rendering sky + R_SetupView(false); R_Sky(); + R_SetupView(true); // restore entity matrix R_Mesh_Matrix(&rsurface.matrix); } @@ -6140,7 +6157,7 @@ void R_QueueSurfaceList(entity_render_t *ent, int numsurfaces, msurface_t **surf ; continue; } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_SORTTRANSPARENT) + if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) { // transparent surfaces get pushed off into the transparent queue const msurface_t *surface = surfacelist[i];