From: divverent Date: Sat, 12 Mar 2011 20:46:27 +0000 (+0000) Subject: fix offset/reliefmapping by using the proper miplevel - NOTE: this makes use of a... X-Git-Tag: xonotic-v0.6.0~163^2~633 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=383102ae6545d24a9940f7f580d3c240e4a54ddd;hp=f081ed6f4bf3d6a4b49371f38cd9fdba8ada8e8f fix offset/reliefmapping by using the proper miplevel - NOTE: this makes use of a GLSL 1.30 function in offsetmapping, non-GLSL 1.30 drivers will have to degrade git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10913 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/gl_backend.c b/gl_backend.c index 26fe7c25..68067aff 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -2419,6 +2419,8 @@ unsigned int GL_Backend_CompileProgram(int vertexstrings_count, const char **ver qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD5, "Attrib_TexCoord5"); qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD6, "Attrib_TexCoord6"); qglBindAttribLocation(programobject, GLSLATTRIB_TEXCOORD7, "Attrib_TexCoord7"); + if(qglBindFragDataLocation) + qglBindFragDataLocation(programobject, 0, "dp_FragColor"); if (vertexstrings_count && !GL_Backend_CompileShader(programobject, GL_VERTEX_SHADER, "vertex", vertexstrings_count, vertexstrings_list)) goto cleanup; diff --git a/gl_rmain.c b/gl_rmain.c index 9d43f088..790dbca4 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -980,6 +980,15 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode strlcat(permutationname, modeinfo->vertexfilename, sizeof(permutationname)); + // the first pretext is which type of shader to compile as + // (later these will all be bound together as a program object) + if(qglBindFragDataLocation && (permutation & SHADERPERMUTATION_OFFSETMAPPING)) // we use textureGrad() which is glsl 1.30 + { + vertstrings_list[vertstrings_count++] = "#version 130\n"; + geomstrings_list[geomstrings_count++] = "#version 130\n"; + fragstrings_list[fragstrings_count++] = "#version 130\n"; + } + // the first pretext is which type of shader to compile as // (later these will all be bound together as a program object) vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n"; diff --git a/glquake.h b/glquake.h index 90ef1a7b..04c71f11 100644 --- a/glquake.h +++ b/glquake.h @@ -847,6 +847,7 @@ extern void (GLAPIENTRY *qglVertexAttribPointer)(GLuint index, GLint size, GLenu extern void (GLAPIENTRY *qglEnableVertexAttribArray)(GLuint index); extern void (GLAPIENTRY *qglDisableVertexAttribArray)(GLuint index); extern void (GLAPIENTRY *qglBindAttribLocation)(GLuint programObj, GLuint index, const GLchar *name); +extern void (GLAPIENTRY *qglBindFragDataLocation)(GLuint programObj, GLuint index, const GLchar *name); extern void (GLAPIENTRY *qglGetActiveAttrib)(GLuint programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *name); extern GLint (GLAPIENTRY *qglGetAttribLocation)(GLuint programObj, const GLchar *name); extern void (GLAPIENTRY *qglGetVertexAttribdv)(GLuint index, GLenum pname, GLdouble *params); diff --git a/shader_glsl.h b/shader_glsl.h index 5cfeef0f..a6fef691 100644 --- a/shader_glsl.h +++ b/shader_glsl.h @@ -9,6 +9,23 @@ "#define highp\n" "#endif\n" "\n" +"#if __VERSION__ >= 130\n" +"# ifdef VERTEX_SHADER\n" +"# define varying out\n" +"# define attribute in\n" +"# endif\n" +"# ifdef FRAGMENT_SHADER\n" +"out vec4 dp_FragColor;\n" +"# define gl_FragColor dp_FragColor\n" +"# define varying in\n" +"# define attribute in\n" +"# endif\n" +"# define texture1D texture\n" +"# define texture2D texture\n" +"# define texture3D texture\n" +"# define textureCube texture\n" +"#endif\n" +"\n" "#ifdef VERTEX_SHADER\n" "attribute vec4 Attrib_Position; // vertex\n" "attribute vec4 Attrib_Color; // color\n" @@ -565,7 +582,7 @@ "\n" "#ifdef USEOFFSETMAPPING\n" "uniform mediump float OffsetMapping_Scale;\n" -"vec2 OffsetMapping(vec2 TexCoord)\n" +"vec2 OffsetMapping(vec2 TexCoord, vec2 dPdx, vec2 dPdy)\n" "{\n" "#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n" " // 14 sample relief mapping: linear search and then binary search\n" @@ -577,20 +594,20 @@ " vec3 OffsetVector = vec3(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1), -1);\n" " vec3 RT = vec3(TexCoord, 1);\n" " OffsetVector *= 0.1;\n" -" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(texture2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) - 0.5);\n" -" RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.5 - 0.25);\n" -" RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.25 - 0.125);\n" -" RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.125 - 0.0625);\n" -" RT += OffsetVector * (step(texture2D(Texture_Normal, RT.xy).a, RT.z) * 0.0625 - 0.03125);\n" +" RT += OffsetVector * step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * (step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z) - 0.5);\n" +" RT += OffsetVector * (step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z) * 0.5 - 0.25);\n" +" RT += OffsetVector * (step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z) * 0.25 - 0.125);\n" +" RT += OffsetVector * (step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z) * 0.125 - 0.0625);\n" +" RT += OffsetVector * (step(textureGrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z) * 0.0625 - 0.03125);\n" " return RT.xy;\n" "#else\n" " // 2 sample offset mapping (only 2 samples because of ATI Radeon 9500-9800/X300 limits)\n" @@ -598,8 +615,8 @@ " //vec2 OffsetVector = vec2(normalize(EyeVector.xy) * OffsetMapping_Scale * vec2(-1, 1));\n" " vec2 OffsetVector = vec2(normalize(EyeVector).xy * OffsetMapping_Scale * vec2(-1, 1));\n" " OffsetVector *= 0.5;\n" -" TexCoord += OffsetVector * (1.0 - texture2D(Texture_Normal, TexCoord).a);\n" -" TexCoord += OffsetVector * (1.0 - texture2D(Texture_Normal, TexCoord).a);\n" +" TexCoord += OffsetVector * (1.0 - textureGrad(Texture_Normal, TexCoord, dPdx, dPdy).a);\n" +" TexCoord += OffsetVector * (1.0 - textureGrad(Texture_Normal, TexCoord, dPdx, dPdy).a);\n" " return TexCoord;\n" "#endif\n" "}\n" @@ -784,29 +801,32 @@ "{\n" "#ifdef USEOFFSETMAPPING\n" " // apply offsetmapping\n" -" vec2 TexCoord = OffsetMapping(TexCoordSurfaceLightmap.xy);\n" +" vec2 dPdx = dFdx(TexCoordSurfaceLightmap.xy);\n" +" vec2 dPdy = dFdy(TexCoordSurfaceLightmap.xy);\n" +" vec2 TexCoordOffset = OffsetMapping(TexCoordSurfaceLightmap.xy, dPdx, dPdy);\n" +"# define offsetMappedTexture2D(t) textureGrad(t, TexCoordOffset, dPdx, dPdy)\n" "#else\n" -"# define TexCoord (TexCoordSurfaceLightmap.xy)\n" +"# define offsetMappedTexture2D(t) texture2D(t, TexCoordSurfaceLightmap.xy)\n" "#endif\n" "\n" "#ifdef USEALPHAKILL\n" -" if (texture2D(Texture_Color, TexCoord).a < 0.5)\n" +" if (offsetMappedTexture2D(Texture_Color).a < 0.5)\n" " discard;\n" "#endif\n" "\n" "#ifdef USEVERTEXTEXTUREBLEND\n" -" float alpha = texture2D(Texture_Color, TexCoord).a;\n" +" float alpha = offsetMappedTexture2D(Texture_Color).a;\n" " float terrainblend = clamp(float(VertexColor.a) * alpha * 2.0 - 0.5, float(0.0), float(1.0));\n" " //float terrainblend = min(float(VertexColor.a) * alpha * 2.0, float(1.0));\n" " //float terrainblend = float(VertexColor.a) * alpha > 0.5;\n" "#endif\n" "\n" "#ifdef USEVERTEXTEXTUREBLEND\n" -" vec3 surfacenormal = mix(vec3(texture2D(Texture_SecondaryNormal, TexCoord2)), vec3(texture2D(Texture_Normal, TexCoord)), terrainblend) - vec3(0.5, 0.5, 0.5);\n" -" float a = mix(texture2D(Texture_SecondaryGloss, TexCoord2).a, texture2D(Texture_Gloss, TexCoord).a, terrainblend);\n" +" vec3 surfacenormal = mix(vec3(texture2D(Texture_SecondaryNormal, TexCoord2)), vec3(offsetMappedTexture2D(Texture_Normal)), terrainblend) - vec3(0.5, 0.5, 0.5);\n" +" float a = mix(texture2D(Texture_SecondaryGloss, TexCoord2).a, offsetMappedTexture2D(Texture_Gloss).a, terrainblend);\n" "#else\n" -" vec3 surfacenormal = vec3(texture2D(Texture_Normal, TexCoord)) - vec3(0.5, 0.5, 0.5);\n" -" float a = texture2D(Texture_Gloss, TexCoord).a;\n" +" vec3 surfacenormal = vec3(offsetMappedTexture2D(Texture_Normal)) - vec3(0.5, 0.5, 0.5);\n" +" float a = offsetMappedTexture2D(Texture_Gloss).a;\n" "#endif\n" "\n" " gl_FragColor = vec4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + vec3(0.5, 0.5, 0.5), a);\n" @@ -1026,20 +1046,23 @@ "{\n" "#ifdef USEOFFSETMAPPING\n" " // apply offsetmapping\n" -" vec2 TexCoord = OffsetMapping(TexCoordSurfaceLightmap.xy);\n" +" vec2 dPdx = dFdx(TexCoordSurfaceLightmap.xy);\n" +" vec2 dPdy = dFdy(TexCoordSurfaceLightmap.xy);\n" +" vec2 TexCoordOffset = OffsetMapping(TexCoordSurfaceLightmap.xy, dPdx, dPdy);\n" +"# define offsetMappedTexture2D(t) textureGrad(t, TexCoordOffset, dPdx, dPdy)\n" "#else\n" -"# define TexCoord (TexCoordSurfaceLightmap.xy)\n" +"# define offsetMappedTexture2D(t) texture2D(t, TexCoordSurfaceLightmap.xy)\n" "#endif\n" "\n" " // combine the diffuse textures (base, pants, shirt)\n" -" myhalf4 color = myhalf4(texture2D(Texture_Color, TexCoord));\n" +" myhalf4 color = myhalf4(offsetMappedTexture2D(Texture_Color));\n" "#ifdef USEALPHAKILL\n" " if (color.a < 0.5)\n" " discard;\n" "#endif\n" " color.a *= Alpha;\n" "#ifdef USECOLORMAPPING\n" -" color.rgb += myhalf3(texture2D(Texture_Pants, TexCoord)) * Color_Pants + myhalf3(texture2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n" +" color.rgb += myhalf3(offsetMappedTexture2D(Texture_Pants)) * Color_Pants + myhalf3(offsetMappedTexture2D(Texture_Shirt)) * Color_Shirt;\n" "#endif\n" "#ifdef USEVERTEXTEXTUREBLEND\n" " myhalf terrainblend = clamp(myhalf(VertexColor.a) * color.a * 2.0 - 0.5, myhalf(0.0), myhalf(1.0));\n" @@ -1052,18 +1075,18 @@ "\n" " // get the surface normal\n" "#ifdef USEVERTEXTEXTUREBLEND\n" -" myhalf3 surfacenormal = normalize(mix(myhalf3(texture2D(Texture_SecondaryNormal, TexCoord2)), myhalf3(texture2D(Texture_Normal, TexCoord)), terrainblend) - myhalf3(0.5, 0.5, 0.5));\n" +" myhalf3 surfacenormal = normalize(mix(myhalf3(texture2D(Texture_SecondaryNormal, TexCoord2)), myhalf3(offsetMappedTexture2D(Texture_Normal)), terrainblend) - myhalf3(0.5, 0.5, 0.5));\n" "#else\n" -" myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5, 0.5, 0.5));\n" +" myhalf3 surfacenormal = normalize(myhalf3(offsetMappedTexture2D(Texture_Normal)) - myhalf3(0.5, 0.5, 0.5));\n" "#endif\n" "\n" " // get the material colors\n" " myhalf3 diffusetex = color.rgb;\n" "#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n" "# ifdef USEVERTEXTEXTUREBLEND\n" -" myhalf4 glosstex = mix(myhalf4(texture2D(Texture_SecondaryGloss, TexCoord2)), myhalf4(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n" +" myhalf4 glosstex = mix(myhalf4(texture2D(Texture_SecondaryGloss, TexCoord2)), myhalf4(offsetMappedTexture2D(Texture_Gloss)), terrainblend);\n" "# else\n" -" myhalf4 glosstex = myhalf4(texture2D(Texture_Gloss, TexCoord));\n" +" myhalf4 glosstex = myhalf4(offsetMappedTexture2D(Texture_Gloss));\n" "# endif\n" "#endif\n" "\n" @@ -1071,7 +1094,7 @@ " vec3 TangentReflectVector = reflect(-EyeVector, surfacenormal);\n" " vec3 ModelReflectVector = TangentReflectVector.x * VectorS + TangentReflectVector.y * VectorT + TangentReflectVector.z * VectorR;\n" " vec3 ReflectCubeTexCoord = vec3(ModelToReflectCube * vec4(ModelReflectVector, 0));\n" -" diffusetex += myhalf3(texture2D(Texture_ReflectMask, TexCoord)) * myhalf3(textureCube(Texture_ReflectCube, ReflectCubeTexCoord));\n" +" diffusetex += myhalf3(offsetMappedTexture2D(Texture_ReflectMask)) * myhalf3(textureCube(Texture_ReflectCube, ReflectCubeTexCoord));\n" "#endif\n" "\n" "\n" @@ -1204,9 +1227,9 @@ "\n" "#ifdef USEGLOW\n" "#ifdef USEVERTEXTEXTUREBLEND\n" -" color.rgb += mix(myhalf3(texture2D(Texture_SecondaryGlow, TexCoord2)), myhalf3(texture2D(Texture_Glow, TexCoord)), terrainblend) * Color_Glow;\n" +" color.rgb += mix(myhalf3(texture2D(Texture_SecondaryGlow, TexCoord2)), myhalf3(offsetMappedTexture2D(Texture_Glow)), terrainblend) * Color_Glow;\n" "#else\n" -" color.rgb += myhalf3(texture2D(Texture_Glow, TexCoord)) * Color_Glow;\n" +" color.rgb += myhalf3(offsetMappedTexture2D(Texture_Glow)) * Color_Glow;\n" "#endif\n" "#endif\n" "\n" @@ -1217,9 +1240,9 @@ " // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n" "#ifdef USEREFLECTION\n" " 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 + normalize(myhalf3(offsetMappedTexture2D(Texture_Normal)) - myhalf3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n" " vec2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW.zw + ScreenCenterRefractReflect.zw;\n" -" vec2 ScreenTexCoord = SafeScreenTexCoord + vec3(normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5))).xy * DistortScaleRefractReflect.zw;\n" +" vec2 ScreenTexCoord = SafeScreenTexCoord + vec3(normalize(myhalf3(offsetMappedTexture2D(Texture_Normal)) - myhalf3(0.5))).xy * DistortScaleRefractReflect.zw;\n" " // FIXME temporary hack to detect the case that the reflection\n" " // gets blackened at edges due to leaving the area that contains actual\n" " // content.\n" diff --git a/shader_hlsl.h b/shader_hlsl.h index 19bf6b82..41aa34e2 100644 --- a/shader_hlsl.h +++ b/shader_hlsl.h @@ -495,7 +495,7 @@ "#endif\n" "\n" "#ifdef USEOFFSETMAPPING\n" -"float2 OffsetMapping(float2 TexCoord, float OffsetMapping_Scale, float3 EyeVector, sampler Texture_Normal)\n" +"float2 OffsetMapping(float2 TexCoord, float OffsetMapping_Scale, float3 EyeVector, sampler Texture_Normal, float2 dPdx, float2 dPdy)\n" "{\n" "#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n" " // 14 sample relief mapping: linear search and then binary search\n" @@ -507,20 +507,20 @@ " float3 OffsetVector = float3(normalize(EyeVector).xy * OffsetMapping_Scale * float2(-1, 1), -1);\n" " float3 RT = float3(TexCoord, 1);\n" " OffsetVector *= 0.1;\n" -" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n" -" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) - 0.5);\n" -" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.5 - 0.25);\n" -" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.25 - 0.125);\n" -" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.125 - 0.0625);\n" -" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.0625 - 0.03125);\n" +" RT += OffsetVector * step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z);\n" +" RT += OffsetVector * (step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z) - 0.5);\n" +" RT += OffsetVector * (step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z) * 0.5 - 0.25);\n" +" RT += OffsetVector * (step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z) * 0.25 - 0.125);\n" +" RT += OffsetVector * (step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z) * 0.125 - 0.0625);\n" +" RT += OffsetVector * (step(tex2Dgrad(Texture_Normal, RT.xy, dPdx, dPdy).a, RT.z) * 0.0625 - 0.03125);\n" " return RT.xy;\n" "#else\n" " // 2 sample offset mapping (only 2 samples because of ATI Radeon 9500-9800/X300 limits)\n" @@ -528,8 +528,8 @@ " //float2 OffsetVector = float2(normalize(EyeVector.xy) * OffsetMapping_Scale * float2(-1, 1));\n" " float2 OffsetVector = float2(normalize(EyeVector).xy * OffsetMapping_Scale * float2(-1, 1));\n" " OffsetVector *= 0.5;\n" -" TexCoord += OffsetVector * (1.0 - tex2D(Texture_Normal, TexCoord).a);\n" -" TexCoord += OffsetVector * (1.0 - tex2D(Texture_Normal, TexCoord).a);\n" +" TexCoord += OffsetVector * (1.0 - tex2Dgrad(Texture_Normal, TexCoord, dPdx, dPdy).a);\n" +" TexCoord += OffsetVector * (1.0 - tex2Dgrad(Texture_Normal, TexCoord, dPdx, dPdy).a);\n" " return TexCoord;\n" "#endif\n" "}\n" @@ -756,28 +756,32 @@ " float2 TexCoord = TexCoordBoth.xy;\n" "#ifdef USEOFFSETMAPPING\n" " // apply offsetmapping\n" -" float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_Scale, EyeVector, Texture_Normal);\n" -"#define TexCoord TexCoordOffset\n" +" float2 dPdx = ddx(TexCoord);\n" +" float2 dPdy = ddy(TexCoord);\n" +" float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_Scale, EyeVector, Texture_Normal, dPdx, dPdy);\n" +"# define offsetMappedTexture2D(t) tex2Dgrad(t, TexCoordOffset, dPdx, dPdy)\n" +"#else\n" +"# define offsetMappedTexture2D(t) tex2D(t, TexCoord)\n" "#endif\n" "\n" "#ifdef USEALPHAKILL\n" -" if (tex2D(Texture_Color, TexCoord).a < 0.5)\n" +" if (offsetMappedTexture2D(Texture_Color).a < 0.5)\n" " discard;\n" "#endif\n" "\n" "#ifdef USEVERTEXTEXTUREBLEND\n" -" float alpha = tex2D(Texture_Color, TexCoord).a;\n" +" float alpha = offsetMappedTexture2D(Texture_Color).a;\n" " float terrainblend = clamp(float(gl_FrontColor.a) * alpha * 2.0 - 0.5, float(0.0), float(1.0));\n" " //float terrainblend = min(float(gl_FrontColor.a) * alpha * 2.0, float(1.0));\n" " //float terrainblend = float(gl_FrontColor.a) * alpha > 0.5;\n" "#endif\n" "\n" "#ifdef USEVERTEXTEXTUREBLEND\n" -" float3 surfacenormal = lerp(tex2D(Texture_SecondaryNormal, TexCoord2).rgb, tex2D(Texture_Normal, TexCoord).rgb, terrainblend) - float3(0.5, 0.5, 0.5);\n" -" float a = lerp(tex2D(Texture_SecondaryGloss, TexCoord2).a, tex2D(Texture_Gloss, TexCoord).a, terrainblend);\n" +" float3 surfacenormal = lerp(tex2D(Texture_SecondaryNormal, TexCoord2).rgb, offsetMappedTexture2D(Texture_Normal).rgb, terrainblend) - float3(0.5, 0.5, 0.5);\n" +" float a = lerp(tex2D(Texture_SecondaryGloss, TexCoord2).a, offsetMappedTexture2D(Texture_Gloss).a, terrainblend);\n" "#else\n" -" float3 surfacenormal = tex2D(Texture_Normal, TexCoord).rgb - float3(0.5, 0.5, 0.5);\n" -" float a = tex2D(Texture_Gloss, TexCoord).a;\n" +" float3 surfacenormal = offsetMappedTexture2D(Texture_Normal).rgb - float3(0.5, 0.5, 0.5);\n" +" float a = offsetMappedTexture2D(Texture_Gloss).a;\n" "#endif\n" "\n" "#ifdef HLSL\n" @@ -1233,19 +1237,23 @@ "#endif\n" "#ifdef USEOFFSETMAPPING\n" " // apply offsetmapping\n" -" float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_Scale, EyeVector, Texture_Normal);\n" -"#define TexCoord TexCoordOffset\n" +" float2 dPdx = ddx(TexCoord);\n" +" float2 dPdy = ddy(TexCoord);\n" +" float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_Scale, EyeVector, Texture_Normal, dPdx, dPdy);\n" +"# define offsetMappedTexture2D(t) tex2Dgrad(t, TexCoordOffset, dPdx, dPdy)\n" +"#else\n" +"# define offsetMappedTexture2D(t) tex2D(t, TexCoord)\n" "#endif\n" "\n" " // combine the diffuse textures (base, pants, shirt)\n" -" half4 color = half4(tex2D(Texture_Color, TexCoord));\n" +" half4 color = half4(offsetMappedTexture2D(Texture_Color));\n" "#ifdef USEALPHAKILL\n" " if (color.a < 0.5)\n" " discard;\n" "#endif\n" " color.a *= Alpha;\n" "#ifdef USECOLORMAPPING\n" -" color.rgb += half3(tex2D(Texture_Pants, TexCoord).rgb) * Color_Pants + half3(tex2D(Texture_Shirt, TexCoord).rgb) * Color_Shirt;\n" +" color.rgb += half3(offsetMappedTexture2D(Texture_Pants).rgb) * Color_Pants + half3(offsetMappedTexture2D(Texture_Shirt).rgb) * Color_Shirt;\n" "#endif\n" "#ifdef USEVERTEXTEXTUREBLEND\n" " half terrainblend = clamp(half(gl_FrontColor.a) * color.a * 2.0 - 0.5, half(0.0), half(1.0));\n" @@ -1258,18 +1266,18 @@ "\n" " // get the surface normal\n" "#ifdef USEVERTEXTEXTUREBLEND\n" -" half3 surfacenormal = normalize(half3(lerp(tex2D(Texture_SecondaryNormal, TexCoord2).rgb, tex2D(Texture_Normal, TexCoord).rgb, terrainblend)) - half3(0.5, 0.5, 0.5));\n" +" half3 surfacenormal = normalize(half3(lerp(tex2D(Texture_SecondaryNormal, TexCoord2).rgb, offsetMappedTexture2D(Texture_Normal).rgb, terrainblend)) - half3(0.5, 0.5, 0.5));\n" "#else\n" -" half3 surfacenormal = half3(normalize(half3(tex2D(Texture_Normal, TexCoord).rgb) - half3(0.5, 0.5, 0.5)));\n" +" half3 surfacenormal = half3(normalize(half3(offsetMappedTexture2D(Texture_Normal).rgb) - half3(0.5, 0.5, 0.5)));\n" "#endif\n" "\n" " // get the material colors\n" " half3 diffusetex = color.rgb;\n" "#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n" "# ifdef USEVERTEXTEXTUREBLEND\n" -" half4 glosstex = half4(lerp(tex2D(Texture_SecondaryGloss, TexCoord2), tex2D(Texture_Gloss, TexCoord), terrainblend));\n" +" half4 glosstex = half4(lerp(tex2D(Texture_SecondaryGloss, TexCoord2), offsetMappedTexture2D(Texture_Gloss), terrainblend));\n" "# else\n" -" half4 glosstex = half4(tex2D(Texture_Gloss, TexCoord));\n" +" half4 glosstex = half4(offsetMappedTexture2D(Texture_Gloss));\n" "# endif\n" "#endif\n" "\n" @@ -1277,7 +1285,7 @@ " float3 TangentReflectVector = reflect(-EyeVector, surfacenormal);\n" " float3 ModelReflectVector = TangentReflectVector.x * VectorS + TangentReflectVector.y * VectorT + TangentReflectVector.z * VectorR;\n" " float3 ReflectCubeTexCoord = mul(ModelToReflectCube, float4(ModelReflectVector, 0)).xyz;\n" -" diffusetex += half3(tex2D(Texture_ReflectMask, TexCoord).rgb) * half3(texCUBE(Texture_ReflectCube, ReflectCubeTexCoord).rgb);\n" +" diffusetex += half3(offsetMappedTexture2D(Texture_ReflectMask).rgb) * half3(texCUBE(Texture_ReflectCube, ReflectCubeTexCoord).rgb);\n" "#endif\n" "\n" "\n" @@ -1435,9 +1443,9 @@ "\n" "#ifdef USEGLOW\n" "#ifdef USEVERTEXTEXTUREBLEND\n" -" color.rgb += half3(lerp(tex2D(Texture_SecondaryGlow, TexCoord2).rgb, tex2D(Texture_Glow, TexCoord).rgb, terrainblend)) * Color_Glow;\n" +" color.rgb += half3(lerp(tex2D(Texture_SecondaryGlow, TexCoord2).rgb, offsetMappedTexture2D(Texture_Glow).rgb, terrainblend)) * Color_Glow;\n" "#else\n" -" color.rgb += half3(tex2D(Texture_Glow, TexCoord).rgb) * Color_Glow;\n" +" color.rgb += half3(offsetMappedTexture2D(Texture_Glow).rgb) * Color_Glow;\n" "#endif\n" "#endif\n" "\n" @@ -1448,9 +1456,9 @@ " // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n" "#ifdef USEREFLECTION\n" " float4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n" -" //float4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(half3(tex2D(Texture_Normal, TexCoord).rgb) - half3(0.5,0.5,0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n" +" //float4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(half3(offsetMappedTexture2D(Texture_Normal).rgb) - half3(0.5,0.5,0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n" " float2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW.zw + ScreenCenterRefractReflect.zw;\n" -" float2 ScreenTexCoord = SafeScreenTexCoord + float3(normalize(half3(tex2D(Texture_Normal, TexCoord).rgb) - half3(0.5,0.5,0.5))).xy * DistortScaleRefractReflect.zw;\n" +" float2 ScreenTexCoord = SafeScreenTexCoord + float3(normalize(half3(offsetMappedTexture2D(Texture_Normal).rgb) - half3(0.5,0.5,0.5))).xy * DistortScaleRefractReflect.zw;\n" " // FIXME temporary hack to detect the case that the reflection\n" " // gets blackened at edges due to leaving the area that contains actual\n" " // content.\n" diff --git a/vid_sdl.c b/vid_sdl.c index 73448881..bb7d13f0 100644 --- a/vid_sdl.c +++ b/vid_sdl.c @@ -1211,6 +1211,7 @@ void wrapglAttachShader(GLuint containerObj, GLuint obj) {glAttachShader(contain void wrapglBegin(GLenum mode) {Con_Printf("glBegin(mode)\n");} //void wrapglBeginQuery(GLenum target, GLuint qid) {glBeginQuery(target, qid);} void wrapglBindAttribLocation(GLuint programObj, GLuint index, const GLchar *name) {glBindAttribLocation(programObj, index, name);} +void wrapglBindFragDataLocation(GLuint programObj, GLuint index, const GLchar *name) {glBindFragDataLocation(programObj, index, name);} void wrapglBindBuffer(GLenum target, GLuint buffer) {glBindBuffer(target, buffer);} void wrapglBindFramebuffer(GLenum target, GLuint framebuffer) {glBindFramebuffer(target, framebuffer);} void wrapglBindRenderbuffer(GLenum target, GLuint renderbuffer) {glBindRenderbuffer(target, renderbuffer);} @@ -1432,6 +1433,7 @@ void GLES_Init(void) qglBegin = wrapglBegin; // qglBeginQueryARB = wrapglBeginQuery; qglBindAttribLocation = wrapglBindAttribLocation; + qglBindFragDataLocation = wrapglBindFragDataLocation; qglBindBufferARB = wrapglBindBuffer; qglBindFramebufferEXT = wrapglBindFramebuffer; qglBindRenderbufferEXT = wrapglBindRenderbuffer; diff --git a/vid_shared.c b/vid_shared.c index 8eda95e5..43d5e698 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -335,6 +335,7 @@ void (GLAPIENTRY *qglVertexAttribPointer)(GLuint index, GLint size, GLenum type, void (GLAPIENTRY *qglEnableVertexAttribArray)(GLuint index); void (GLAPIENTRY *qglDisableVertexAttribArray)(GLuint index); void (GLAPIENTRY *qglBindAttribLocation)(GLuint programObj, GLuint index, const GLchar *name); +void (GLAPIENTRY *qglBindFragDataLocation)(GLuint programObj, GLuint index, const GLchar *name); void (GLAPIENTRY *qglGetActiveAttrib)(GLuint programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLchar *name); GLint (GLAPIENTRY *qglGetAttribLocation)(GLuint programObj, const GLchar *name); void (GLAPIENTRY *qglGetVertexAttribdv)(GLuint index, GLenum pname, GLdouble *params); @@ -726,6 +727,12 @@ static dllfunction_t gl20shaderfuncs[] = {NULL, NULL} }; +static dllfunction_t glsl130funcs[] = +{ + {"glBindFragDataLocation", (void **) &qglBindFragDataLocation}, + {NULL, NULL} +}; + static dllfunction_t vbofuncs[] = { {"glBindBufferARB" , (void **) &qglBindBufferARB}, @@ -828,6 +835,9 @@ void VID_CheckExtensions(void) Sys_Error("OpenGL 1.1.0 functions not found"); vid.support.gl20shaders = GL_CheckExtension("2.0", gl20shaderfuncs, "-noshaders", false); + // this one is purely optional, needed for GLSL 1.3 support (#version 130), so we don't even check the return value of GL_CheckExtension + GL_CheckExtension("2.0", glsl130funcs, "-noglsl130", false); + CHECKGLERROR Con_DPrint("Checking OpenGL extensions...\n");