X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=gl_rmain.c;h=a8467a3e26c0e3b1bc6f8db2ca4f77a040bf2fc2;hb=75b06d199054ffdac3fee96ca76d0028bb2eeb3a;hp=6b3dcf9d76379344d4b72bc69b001d5adbad23f9;hpb=c8d0a99b50d4ad8f40cff377385bcbbae57349d4;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index 6b3dcf9d..a8467a3e 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -29,11 +29,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. mempool_t *r_main_mempool; rtexturepool_t *r_main_texturepool; -static int r_frame = 0; ///< used only by R_GetCurrentTexture +static int r_textureframe = 0; ///< used only by R_GetCurrentTexture -qboolean r_loadnormalmap; -qboolean r_loadgloss; +static qboolean r_loadnormalmap; +static qboolean r_loadgloss; qboolean r_loadfog; +static qboolean r_loaddds; +static qboolean r_savedds; // // screen size info @@ -107,6 +109,9 @@ cvar_t gl_fogstart = {0, "gl_fogstart", "0", "nehahra fog start distance (for Ne cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra compatibility only)"}; cvar_t gl_skyclip = {0, "gl_skyclip", "4608", "nehahra farclip distance - the real fog end (for Nehahra compatibility only)"}; +cvar_t r_texture_dds_load = {CVAR_SAVE, "r_texture_dds_load", "0", "load compressed dds/filename.dds texture instead of filename.tga, if the file exists (requires driver support)"}; +cvar_t r_texture_dds_save = {CVAR_SAVE, "r_texture_dds_save", "0", "save compressed dds/filename.dds texture when filename.tga is loaded, so that it can be loaded instead next time"}; + cvar_t r_textureunits = {0, "r_textureunits", "32", "number of texture units to use in GL 1.1 and GL 1.3 rendering paths"}; static cvar_t gl_combine = {CVAR_READONLY, "gl_combine", "1", "indicates whether the OpenGL 1.3 rendering path is active"}; static cvar_t r_glsl = {CVAR_READONLY, "r_glsl", "1", "indicates whether the OpenGL 2.0 rendering path is active"}; @@ -127,7 +132,7 @@ cvar_t r_water_resolutionmultiplier = {CVAR_SAVE, "r_water_resolutionmultiplier" cvar_t r_water_refractdistort = {CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"}; cvar_t r_water_reflectdistort = {CVAR_SAVE, "r_water_reflectdistort", "0.01", "how much water reflections shimmer"}; -cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1", "enables animation smoothing on sprites"}; +cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "0", "enables animation smoothing on sprites"}; cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"}; cvar_t r_lerplightstyles = {CVAR_SAVE, "r_lerplightstyles", "0", "enable animation smoothing on flickering lights"}; cvar_t r_waterscroll = {CVAR_SAVE, "r_waterscroll", "1", "makes water scroll around, value controls how much"}; @@ -494,9 +499,9 @@ static const char *builtinshaderstring = "# extension GL_EXT_gpu_shader4 : enable\n" "#endif\n" "\n" -"#ifdef USESHADOWSAMPLER\n" -"# extension GL_ARB_shadow : enable\n" -"#endif\n" +"//#ifdef USESHADOWSAMPLER\n" +"//# extension GL_ARB_shadow : enable\n" +"//#endif\n" "\n" "//#ifdef __GLSL_CG_DATA_TYPES\n" "//# define myhalf half\n" @@ -2583,8 +2588,8 @@ const char *builtincgshaderstring = "\n" "# ifdef USECUBEFILTER\n" " float3 cubecolor = texCUBE(Texture_Cube, CubeVector).rgb;\n" -" gl_FragData0 *= cubecolor;\n" -" gl_FragData1 *= cubecolor;\n" +" gl_FragData0.rgb *= cubecolor;\n" +" gl_FragData1.rgb *= cubecolor;\n" "# endif\n" "}\n" "#endif // FRAGMENT_SHADER\n" @@ -3625,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 @@ -4092,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) @@ -4157,10 +4164,14 @@ void R_GLSL_DumpShader_f(void) { FS_Print(file, "/* The engine may define the following macros:\n"); FS_Print(file, "#define VERTEX_SHADER\n#define GEOMETRY_SHADER\n#define FRAGMENT_SHADER\n"); - for (i = 0;i < SHADERMODE_COUNT;i++) - FS_Print(file, glslshadermodeinfo[i].pretext); - for (i = 0;i < SHADERPERMUTATION_COUNT;i++) - FS_Print(file, shaderpermutationinfo[i].pretext); + for (i = 0;i < SHADERMODE_COUNT;i++) { + if (glslshadermodeinfo[i].pretext) + FS_Print(file, glslshadermodeinfo[i].pretext); + } + for (i = 0;i < SHADERPERMUTATION_COUNT;i++) { + if (shaderpermutationinfo[i].pretext) + FS_Print(file, shaderpermutationinfo[i].pretext); + } FS_Print(file, "*/\n"); FS_Print(file, builtinshaderstring); FS_Close(file); @@ -4295,13 +4306,6 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, unsigned int permutation = 0; unsigned int mode = 0; float m16f[16]; - // TODO: implement geometry-shader based shadow volumes someday - if (r_glsl_offsetmapping.integer) - { - permutation |= SHADERPERMUTATION_OFFSETMAPPING; - if (r_glsl_offsetmapping_reliefmapping.integer) - permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; - } if (rsurfacepass == RSURFPASS_BACKGROUND) { // distorted background @@ -4309,22 +4313,53 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, mode = SHADERMODE_WATER; else mode = SHADERMODE_REFRACTION; + R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset); + R_Mesh_TexCoordPointer(1, 3, rsurface.svector3f, rsurface.svector3f_bufferobject, rsurface.svector3f_bufferoffset); + R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset); + R_Mesh_TexCoordPointer(3, 3, rsurface.normal3f, rsurface.normal3f_bufferobject, rsurface.normal3f_bufferoffset); + R_Mesh_TexCoordPointer(4, 0, NULL, 0, 0); + R_Mesh_ColorPointer(NULL, 0, 0); + GL_AlphaTest(false); + GL_BlendFunc(GL_ONE, GL_ZERO); } else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY) { + if (r_glsl_offsetmapping.integer) + { + permutation |= SHADERPERMUTATION_OFFSETMAPPING; + if (r_glsl_offsetmapping_reliefmapping.integer) + permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; + } + if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) + permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; + if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) + permutation |= SHADERPERMUTATION_ALPHAKILL; // normalmap (deferred prepass), may use alpha test on diffuse mode = SHADERMODE_DEFERREDGEOMETRY; if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; + R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset); + R_Mesh_TexCoordPointer(1, 3, rsurface.svector3f, rsurface.svector3f_bufferobject, rsurface.svector3f_bufferoffset); + R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset); + R_Mesh_TexCoordPointer(3, 3, rsurface.normal3f, rsurface.normal3f_bufferobject, rsurface.normal3f_bufferoffset); + R_Mesh_TexCoordPointer(4, 0, NULL, 0, 0); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) + R_Mesh_ColorPointer(rsurface.modellightmapcolor4f, rsurface.modellightmapcolor4f_bufferobject, rsurface.modellightmapcolor4f_bufferoffset); + else + R_Mesh_ColorPointer(NULL, 0, 0); + GL_AlphaTest(false); + GL_BlendFunc(GL_ONE, GL_ZERO); + } + else if (rsurfacepass == RSURFPASS_RTLIGHT) + { if (r_glsl_offsetmapping.integer) { permutation |= SHADERPERMUTATION_OFFSETMAPPING; if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; } - } - else if (rsurfacepass == RSURFPASS_RTLIGHT) - { + if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) + permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; // light source mode = SHADERMODE_LIGHTSOURCE; if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) @@ -4334,7 +4369,11 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (diffusescale > 0) permutation |= SHADERPERMUTATION_DIFFUSE; if (specularscale > 0) + { permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; + if (r_shadow_glossexact.integer) + permutation |= SHADERPERMUTATION_EXACTSPECULARMATH; + } if (r_refdef.fogenabled) permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE; if (rsurface.texture->colormapping) @@ -4357,40 +4396,90 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, else if (r_shadow_shadowmappcf) permutation |= SHADERPERMUTATION_SHADOWMAPPCF; } + R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset); + if (true || permutation & (SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_OFFSETMAPPING)) + { + R_Mesh_TexCoordPointer(1, 3, rsurface.svector3f, rsurface.svector3f_bufferobject, rsurface.svector3f_bufferoffset); + R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset); + R_Mesh_TexCoordPointer(3, 3, rsurface.normal3f, rsurface.normal3f_bufferobject, rsurface.normal3f_bufferoffset); + } + else + { + R_Mesh_TexCoordPointer(1, 0, NULL, 0, 0); + R_Mesh_TexCoordPointer(2, 0, NULL, 0, 0); + R_Mesh_TexCoordPointer(3, 0, NULL, 0, 0); + } + //R_Mesh_TexCoordPointer(4, 0, NULL, 0, 0); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) + R_Mesh_ColorPointer(rsurface.modellightmapcolor4f, rsurface.modellightmapcolor4f_bufferobject, rsurface.modellightmapcolor4f_bufferoffset); + else + R_Mesh_ColorPointer(NULL, 0, 0); + GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); + GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); } else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) { + if (r_glsl_offsetmapping.integer) + { + permutation |= SHADERPERMUTATION_OFFSETMAPPING; + if (r_glsl_offsetmapping_reliefmapping.integer) + permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; + } + if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) + permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; // unshaded geometry (fullbright or ambient model lighting) mode = SHADERMODE_FLATCOLOR; ambientscale = diffusescale = specularscale = 0; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) - permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) permutation |= SHADERPERMUTATION_GLOW; if (r_refdef.fogenabled) permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE; if (rsurface.texture->colormapping) permutation |= SHADERPERMUTATION_COLORMAPPING; + if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) + permutation |= SHADERPERMUTATION_REFLECTION; + R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset); + if (true || permutation & (SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_OFFSETMAPPING)) + { + R_Mesh_TexCoordPointer(1, 3, rsurface.svector3f, rsurface.svector3f_bufferobject, rsurface.svector3f_bufferoffset); + R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset); + R_Mesh_TexCoordPointer(3, 3, rsurface.normal3f, rsurface.normal3f_bufferobject, rsurface.normal3f_bufferoffset); + } + else + { + R_Mesh_TexCoordPointer(1, 0, NULL, 0, 0); + R_Mesh_TexCoordPointer(2, 0, NULL, 0, 0); + R_Mesh_TexCoordPointer(3, 0, NULL, 0, 0); + } + R_Mesh_TexCoordPointer(4, 0, NULL, 0, 0); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) + R_Mesh_ColorPointer(rsurface.modellightmapcolor4f, rsurface.modellightmapcolor4f_bufferobject, rsurface.modellightmapcolor4f_bufferoffset); + else + R_Mesh_ColorPointer(NULL, 0, 0); + GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); + GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); + } + else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL) + { if (r_glsl_offsetmapping.integer) { permutation |= SHADERPERMUTATION_OFFSETMAPPING; if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) - permutation |= SHADERPERMUTATION_REFLECTION; - } - else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL) - { - // directional model lighting - mode = SHADERMODE_LIGHTDIRECTION; if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; + // directional model lighting + mode = SHADERMODE_LIGHTDIRECTION; if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) permutation |= SHADERPERMUTATION_GLOW; permutation |= SHADERPERMUTATION_DIFFUSE; if (specularscale > 0) + { permutation |= SHADERPERMUTATION_SPECULAR; + if (r_shadow_glossexact.integer) + permutation |= SHADERPERMUTATION_EXACTSPECULARMATH; + } if (r_refdef.fogenabled) permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE; if (rsurface.texture->colormapping) @@ -4399,13 +4488,36 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_REFLECTION; if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)) permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; + R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset); + if (true || permutation & (SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_OFFSETMAPPING)) + { + R_Mesh_TexCoordPointer(1, 3, rsurface.svector3f, rsurface.svector3f_bufferobject, rsurface.svector3f_bufferoffset); + R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset); + R_Mesh_TexCoordPointer(3, 3, rsurface.normal3f, rsurface.normal3f_bufferobject, rsurface.normal3f_bufferoffset); + } + else + { + R_Mesh_TexCoordPointer(1, 0, NULL, 0, 0); + R_Mesh_TexCoordPointer(2, 0, NULL, 0, 0); + R_Mesh_TexCoordPointer(3, 0, NULL, 0, 0); + } + R_Mesh_TexCoordPointer(4, 0, NULL, 0, 0); + R_Mesh_ColorPointer(NULL, 0, 0); + GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); + GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); } else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) { - // ambient model lighting - mode = SHADERMODE_LIGHTDIRECTION; + if (r_glsl_offsetmapping.integer) + { + permutation |= SHADERPERMUTATION_OFFSETMAPPING; + if (r_glsl_offsetmapping_reliefmapping.integer) + permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; + } if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; + // ambient model lighting + mode = SHADERMODE_LIGHTDIRECTION; if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) permutation |= SHADERPERMUTATION_GLOW; if (r_refdef.fogenabled) @@ -4416,10 +4528,45 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_REFLECTION; if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)) permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; + R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset); + if (true || permutation & (SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_OFFSETMAPPING)) + { + R_Mesh_TexCoordPointer(1, 3, rsurface.svector3f, rsurface.svector3f_bufferobject, rsurface.svector3f_bufferoffset); + R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset); + R_Mesh_TexCoordPointer(3, 3, rsurface.normal3f, rsurface.normal3f_bufferobject, rsurface.normal3f_bufferoffset); + } + else + { + R_Mesh_TexCoordPointer(1, 0, NULL, 0, 0); + R_Mesh_TexCoordPointer(2, 0, NULL, 0, 0); + R_Mesh_TexCoordPointer(3, 0, NULL, 0, 0); + } + R_Mesh_TexCoordPointer(4, 0, NULL, 0, 0); + R_Mesh_ColorPointer(NULL, 0, 0); + GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); + GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); } else { + if (r_glsl_offsetmapping.integer) + { + permutation |= SHADERPERMUTATION_OFFSETMAPPING; + if (r_glsl_offsetmapping_reliefmapping.integer) + permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; + } + if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) + permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; // lightmapped wall + if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) + permutation |= SHADERPERMUTATION_GLOW; + if (r_refdef.fogenabled) + permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE; + if (rsurface.texture->colormapping) + permutation |= SHADERPERMUTATION_COLORMAPPING; + if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) + permutation |= SHADERPERMUTATION_REFLECTION; + if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)) + permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping) { // deluxemapping (light direction texture) @@ -4429,7 +4576,16 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE; permutation |= SHADERPERMUTATION_DIFFUSE; if (specularscale > 0) + { permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; + if (r_shadow_glossexact.integer) + permutation |= SHADERPERMUTATION_EXACTSPECULARMATH; + } + R_Mesh_TexCoordPointer(4, 2, rsurface.modeltexcoordlightmap2f, rsurface.modeltexcoordlightmap2f_bufferobject, rsurface.modeltexcoordlightmap2f_bufferoffset); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) + R_Mesh_ColorPointer(rsurface.modellightmapcolor4f, rsurface.modellightmapcolor4f_bufferobject, rsurface.modellightmapcolor4f_bufferoffset); + else + R_Mesh_ColorPointer(NULL, 0, 0); } else if (r_glsl_deluxemapping.integer >= 2) { @@ -4437,36 +4593,50 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE; permutation |= SHADERPERMUTATION_DIFFUSE; if (specularscale > 0) + { permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; + if (r_shadow_glossexact.integer) + permutation |= SHADERPERMUTATION_EXACTSPECULARMATH; + } + R_Mesh_TexCoordPointer(4, 2, rsurface.modeltexcoordlightmap2f, rsurface.modeltexcoordlightmap2f_bufferobject, rsurface.modeltexcoordlightmap2f_bufferoffset); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) + R_Mesh_ColorPointer(rsurface.modellightmapcolor4f, rsurface.modellightmapcolor4f_bufferobject, rsurface.modellightmapcolor4f_bufferoffset); + else + R_Mesh_ColorPointer(NULL, 0, 0); } else if (rsurface.uselightmaptexture) { // ordinary lightmapping (q1bsp, q3bsp) mode = SHADERMODE_LIGHTMAP; + R_Mesh_TexCoordPointer(4, 2, rsurface.modeltexcoordlightmap2f, rsurface.modeltexcoordlightmap2f_bufferobject, rsurface.modeltexcoordlightmap2f_bufferoffset); + if (permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND) + R_Mesh_ColorPointer(rsurface.modellightmapcolor4f, rsurface.modellightmapcolor4f_bufferobject, rsurface.modellightmapcolor4f_bufferoffset); + else + R_Mesh_ColorPointer(NULL, 0, 0); } else { // ordinary vertex coloring (q3bsp) mode = SHADERMODE_VERTEXCOLOR; + R_Mesh_TexCoordPointer(4, 0, NULL, 0, 0); + R_Mesh_ColorPointer(rsurface.modellightmapcolor4f, rsurface.modellightmapcolor4f_bufferobject, rsurface.modellightmapcolor4f_bufferoffset); } - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) - permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; - if (rsurface.texture->glowtexture && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) - permutation |= SHADERPERMUTATION_GLOW; - if (r_refdef.fogenabled) - permutation |= r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE; - if (rsurface.texture->colormapping) - permutation |= SHADERPERMUTATION_COLORMAPPING; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) - permutation |= SHADERPERMUTATION_REFLECTION; - if (r_shadow_usingdeferredprepass && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)) - permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; + R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset); + if (true || permutation & (SHADERPERMUTATION_DIFFUSE | SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_OFFSETMAPPING)) + { + R_Mesh_TexCoordPointer(1, 3, rsurface.svector3f, rsurface.svector3f_bufferobject, rsurface.svector3f_bufferoffset); + R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset); + R_Mesh_TexCoordPointer(3, 3, rsurface.normal3f, rsurface.normal3f_bufferobject, rsurface.normal3f_bufferoffset); + } + else + { + R_Mesh_TexCoordPointer(1, 0, NULL, 0, 0); + R_Mesh_TexCoordPointer(2, 0, NULL, 0, 0); + R_Mesh_TexCoordPointer(3, 0, NULL, 0, 0); + } + GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0); + GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); } - if(permutation & SHADERPERMUTATION_SPECULAR) - if(r_shadow_glossexact.integer) - permutation |= SHADERPERMUTATION_EXACTSPECULARMATH; - if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) && r_shadow_usingdeferredprepass) - permutation |= SHADERPERMUTATION_ALPHAKILL; switch(vid.renderpath) { case RENDERPATH_GL20: @@ -4478,7 +4648,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]); if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, rsurface.colormod[0] * ambientscale, rsurface.colormod[1] * ambientscale, rsurface.colormod[2] * ambientscale); if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, rsurface.colormod[0] * diffusescale, rsurface.colormod[1] * diffusescale, rsurface.colormod[2] * diffusescale); - if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, specularscale, specularscale, specularscale); + if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale); // additive passes are only darkened by fog, not tinted if (r_glsl_permutation->loc_FogColor >= 0) @@ -4496,8 +4666,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, else if (mode == SHADERMODE_LIGHTDIRECTION) { if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * rsurface.colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * rsurface.colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * rsurface.colormod[2]); - if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity, r_refdef.lightmapintensity, r_refdef.lightmapintensity); - if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale); + if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity * rsurface.colormod[0], r_refdef.lightmapintensity * rsurface.colormod[1], r_refdef.lightmapintensity * rsurface.colormod[2]); + if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Diffuse, rsurface.colormod[0] * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * r_shadow_deferred_8bitrange.value); if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value); if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]); @@ -4507,7 +4677,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, r_refdef.scene.ambient * rsurface.colormod[0], r_refdef.scene.ambient * rsurface.colormod[1], r_refdef.scene.ambient * rsurface.colormod[2]); if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]); - if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale); + if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale); if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Diffuse, rsurface.colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value); if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value); } @@ -4528,7 +4698,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]); @@ -4604,7 +4773,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 @@ -4617,7 +4785,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_cg_permutation->fp_LightColor) cgGLSetParameter3f(r_cg_permutation->fp_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);CHECKCGERROR if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, rsurface.colormod[0] * ambientscale, rsurface.colormod[1] * ambientscale, rsurface.colormod[2] * ambientscale);CHECKCGERROR if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, rsurface.colormod[0] * diffusescale, rsurface.colormod[1] * diffusescale, rsurface.colormod[2] * diffusescale);CHECKCGERROR - if (r_cg_permutation->fp_Color_Specular) cgGLSetParameter3f(r_cg_permutation->fp_Color_Specular, specularscale, specularscale, specularscale);CHECKCGERROR + if (r_cg_permutation->fp_Color_Specular) cgGLSetParameter3f(r_cg_permutation->fp_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);CHECKCGERROR // additive passes are only darkened by fog, not tinted if (r_cg_permutation->fp_FogColor) cgGLSetParameter3f(r_cg_permutation->fp_FogColor, 0, 0, 0);CHECKCGERROR @@ -4634,8 +4802,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, else if (mode == SHADERMODE_LIGHTDIRECTION) { if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * rsurface.colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * rsurface.colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * rsurface.colormod[2]);CHECKCGERROR - if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, r_refdef.lightmapintensity, r_refdef.lightmapintensity, r_refdef.lightmapintensity);CHECKCGERROR - if (r_cg_permutation->fp_Color_Specular) cgGLSetParameter3f(r_cg_permutation->fp_Color_Specular, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale);CHECKCGERROR + if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, r_refdef.lightmapintensity * rsurface.colormod[0], r_refdef.lightmapintensity * rsurface.colormod[1], r_refdef.lightmapintensity * rsurface.colormod[2]);CHECKCGERROR + if (r_cg_permutation->fp_Color_Specular) cgGLSetParameter3f(r_cg_permutation->fp_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);CHECKCGERROR if (r_cg_permutation->fp_DeferredMod_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Diffuse, rsurface.colormod[0] * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * r_shadow_deferred_8bitrange.value);CHECKCGERROR if (r_cg_permutation->fp_DeferredMod_Specular) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);CHECKCGERROR if (r_cg_permutation->fp_LightColor) cgGLSetParameter3f(r_cg_permutation->fp_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);CHECKCGERROR @@ -4645,7 +4813,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, r_refdef.scene.ambient * rsurface.colormod[0], r_refdef.scene.ambient * rsurface.colormod[1], r_refdef.scene.ambient * rsurface.colormod[2]);CHECKCGERROR if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);CHECKCGERROR - if (r_cg_permutation->fp_Color_Specular) cgGLSetParameter3f(r_cg_permutation->fp_Color_Specular, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale, r_refdef.lightmapintensity * specularscale);CHECKCGERROR + if (r_cg_permutation->fp_Color_Specular) cgGLSetParameter3f(r_cg_permutation->fp_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);CHECKCGERROR if (r_cg_permutation->fp_DeferredMod_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Diffuse, rsurface.colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);CHECKCGERROR if (r_cg_permutation->fp_DeferredMod_Specular) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);CHECKCGERROR } @@ -4792,7 +4960,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); @@ -4816,7 +4983,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 @@ -5006,9 +5172,13 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole unsigned char *pixels; unsigned char *bumppixels; unsigned char *basepixels = NULL; - int basepixels_width; - int basepixels_height; + int basepixels_width = 0; + int basepixels_height = 0; skinframe_t *skinframe; + rtexture_t *ddsbase = NULL; + qboolean ddshasalpha = false; + float ddsavgcolor[4]; + char basename[MAX_QPATH]; if (cls.state == ca_dedicated) return NULL; @@ -5020,9 +5190,15 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole if (skinframe && skinframe->base) return skinframe; - basepixels = loadimagepixelsbgra(name, complain, true); - if (basepixels == NULL) - return NULL; + Image_StripImageExtension(name, basename, sizeof(basename)); + + // check for DDS texture file first + if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s.dds", basename), textureflags, &ddshasalpha, ddsavgcolor))) + { + basepixels = loadimagepixelsbgra(name, complain, true); + if (basepixels == NULL) + return NULL; + } if (developer_loading.integer) Con_Printf("loading skin \"%s\"\n", name); @@ -5032,50 +5208,75 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole skinframe = R_SkinFrame_Find(name, textureflags, 0, 0, 0, true); skinframe->stain = NULL; skinframe->merged = NULL; - skinframe->base = r_texture_notexture; + skinframe->base = NULL; skinframe->pants = NULL; skinframe->shirt = NULL; - skinframe->nmap = r_texture_blanknormalmap; + skinframe->nmap = NULL; skinframe->gloss = NULL; skinframe->glow = NULL; skinframe->fog = NULL; skinframe->hasalpha = false; - basepixels_width = image_width; - basepixels_height = image_height; - skinframe->base = R_LoadTexture2D (r_main_texturepool, skinframe->basename, basepixels_width, basepixels_height, basepixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL); - - if (textureflags & TEXF_ALPHA) + if (ddsbase) + { + skinframe->base = ddsbase; + skinframe->hasalpha = ddshasalpha; + VectorCopy(ddsavgcolor, skinframe->avgcolor); + if (r_loadfog && skinframe->hasalpha) + skinframe->fog = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_mask.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL); + //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]); + } + else { - for (j = 3;j < basepixels_width * basepixels_height * 4;j += 4) + basepixels_width = image_width; + basepixels_height = image_height; + skinframe->base = R_LoadTexture2D (r_main_texturepool, skinframe->basename, basepixels_width, basepixels_height, basepixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL); + if (textureflags & TEXF_ALPHA) { - if (basepixels[j] < 255) + for (j = 3;j < basepixels_width * basepixels_height * 4;j += 4) { - skinframe->hasalpha = true; - break; + if (basepixels[j] < 255) + { + skinframe->hasalpha = true; + break; + } } - } - if (r_loadfog && skinframe->hasalpha) - { - // has transparent pixels - pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4); - for (j = 0;j < image_width * image_height * 4;j += 4) + if (r_loadfog && skinframe->hasalpha) { - pixels[j+0] = 255; - pixels[j+1] = 255; - pixels[j+2] = 255; - pixels[j+3] = basepixels[j+3]; + // has transparent pixels + pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4); + for (j = 0;j < image_width * image_height * 4;j += 4) + { + pixels[j+0] = 255; + pixels[j+1] = 255; + pixels[j+2] = 255; + pixels[j+3] = basepixels[j+3]; + } + skinframe->fog = R_LoadTexture2D (r_main_texturepool, va("%s_mask", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL); + Mem_Free(pixels); } - skinframe->fog = R_LoadTexture2D (r_main_texturepool, va("%s_mask", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL); - Mem_Free(pixels); } + R_SKINFRAME_LOAD_AVERAGE_COLORS(basepixels_width * basepixels_height, basepixels[4 * pix + comp]); + //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]); + if (r_savedds && qglGetCompressedTexImageARB && skinframe->base) + R_SaveTextureDDSFile(skinframe->base, va("dds/%s.dds", skinframe->basename), true); + if (r_savedds && qglGetCompressedTexImageARB && skinframe->fog) + R_SaveTextureDDSFile(skinframe->fog, va("dds/%s_mask.dds", skinframe->basename), true); } - R_SKINFRAME_LOAD_AVERAGE_COLORS(basepixels_width * basepixels_height, basepixels[4 * pix + comp]); - //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]); + if (r_loaddds) + { + if (r_loadnormalmap) + skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_norm.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL); + skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_glow.dds", skinframe->basename), textureflags, NULL, NULL); + if (r_loadgloss) + skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_gloss.dds", skinframe->basename), textureflags, NULL, NULL); + skinframe->pants = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_pants.dds", skinframe->basename), textureflags, NULL, NULL); + skinframe->shirt = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_shirt.dds", skinframe->basename), textureflags, NULL, NULL); + } // _norm is the name used by tenebrae and has been adopted as standard - if (r_loadnormalmap) + if (r_loadnormalmap && skinframe->nmap == NULL) { if ((pixels = loadimagepixelsbgra(va("%s_norm", skinframe->basename), false, false)) != NULL) { @@ -5098,14 +5299,46 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); Mem_Free(pixels); } + if (r_savedds && qglGetCompressedTexImageARB && skinframe->nmap) + R_SaveTextureDDSFile(skinframe->nmap, va("dds/%s_norm.dds", skinframe->basename), true); } - // _luma is supported for tenebrae compatibility - // (I think it's a very stupid name, but oh well) + + // _luma is supported only for tenebrae compatibility // _glow is the preferred name - if ((pixels = loadimagepixelsbgra(va("%s_glow", skinframe->basename), false, false)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false))) {skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;} - if (r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false))) {skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;} - if ((pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false))) {skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;} - if ((pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false))) {skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL);Mem_Free(pixels);pixels = NULL;} + if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va("%s_glow", skinframe->basename), false, false)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false)))) + { + skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), NULL); + if (r_savedds && qglGetCompressedTexImageARB && skinframe->glow) + R_SaveTextureDDSFile(skinframe->glow, va("dds/%s_glow.dds", skinframe->basename), true); + Mem_Free(pixels);pixels = NULL; + } + + if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false))) + { + skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), NULL); + if (r_savedds && qglGetCompressedTexImageARB && skinframe->gloss) + R_SaveTextureDDSFile(skinframe->gloss, va("dds/%s_gloss.dds", skinframe->basename), true); + Mem_Free(pixels); + pixels = NULL; + } + + if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false))) + { + skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL); + if (r_savedds && qglGetCompressedTexImageARB && skinframe->pants) + R_SaveTextureDDSFile(skinframe->pants, va("dds/%s_pants.dds", skinframe->basename), true); + Mem_Free(pixels); + pixels = NULL; + } + + if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false))) + { + skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), NULL); + if (r_savedds && qglGetCompressedTexImageARB && skinframe->shirt) + R_SaveTextureDDSFile(skinframe->shirt, va("dds/%s_shirt.dds", skinframe->basename), true); + Mem_Free(pixels); + pixels = NULL; + } if (basepixels) Mem_Free(basepixels); @@ -5130,10 +5363,10 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co skinframe->stain = NULL; skinframe->merged = NULL; - skinframe->base = r_texture_notexture; + skinframe->base = NULL; skinframe->pants = NULL; skinframe->shirt = NULL; - skinframe->nmap = r_texture_blanknormalmap; + skinframe->nmap = NULL; skinframe->gloss = NULL; skinframe->glow = NULL; skinframe->fog = NULL; @@ -5198,10 +5431,10 @@ skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, i skinframe->stain = NULL; skinframe->merged = NULL; - skinframe->base = r_texture_notexture; + skinframe->base = NULL; skinframe->pants = NULL; skinframe->shirt = NULL; - skinframe->nmap = r_texture_blanknormalmap; + skinframe->nmap = NULL; skinframe->gloss = NULL; skinframe->glow = NULL; skinframe->fog = NULL; @@ -5318,10 +5551,10 @@ skinframe_t *R_SkinFrame_LoadInternal8bit(const char *name, int textureflags, co skinframe->stain = NULL; skinframe->merged = NULL; - skinframe->base = r_texture_notexture; + skinframe->base = NULL; skinframe->pants = NULL; skinframe->shirt = NULL; - skinframe->nmap = r_texture_blanknormalmap; + skinframe->nmap = NULL; skinframe->gloss = NULL; skinframe->glow = NULL; skinframe->fog = NULL; @@ -5365,10 +5598,10 @@ skinframe_t *R_SkinFrame_LoadMissing(void) skinframe = R_SkinFrame_Find("missing", TEXF_FORCENEAREST, 0, 0, 0, true); skinframe->stain = NULL; skinframe->merged = NULL; - skinframe->base = r_texture_notexture; + skinframe->base = NULL; skinframe->pants = NULL; skinframe->shirt = NULL; - skinframe->nmap = r_texture_blanknormalmap; + skinframe->nmap = NULL; skinframe->gloss = NULL; skinframe->glow = NULL; skinframe->fog = NULL; @@ -5446,6 +5679,9 @@ void gl_main_start(void) r_texture_fogattenuation = NULL; r_texture_gammaramps = NULL; + r_loaddds = vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc && r_texture_dds_load.integer; + r_savedds = vid.support.arb_texture_compression && vid.support.ext_texture_compression_s3tc && r_texture_dds_save.integer; + switch(vid.renderpath) { case RENDERPATH_GL20: @@ -5658,6 +5894,8 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_fog_exp2); Cvar_RegisterVariable(&r_drawfog); Cvar_RegisterVariable(&r_transparentdepthmasking); + Cvar_RegisterVariable(&r_texture_dds_load); + Cvar_RegisterVariable(&r_texture_dds_save); Cvar_RegisterVariable(&r_textureunits); Cvar_RegisterVariable(&gl_combine); Cvar_RegisterVariable(&r_glsl); @@ -5881,7 +6119,7 @@ static void *r_framedata_base; void R_FrameData_Reset(void) { - if (r_framedata_base); + if (r_framedata_base) Mem_Free(r_framedata_base); r_framedata_base = NULL; r_framedata_size = 0; @@ -5899,7 +6137,7 @@ void R_FrameData_NewFrame(void) if (r_framedata_size != wantedsize) { r_framedata_size = wantedsize; - if (r_framedata_base); + if (r_framedata_base) Mem_Free(r_framedata_base); r_framedata_base = Mem_Alloc(r_main_mempool, r_framedata_size); } @@ -6510,12 +6748,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; @@ -6766,24 +7006,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; @@ -6811,6 +7033,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; @@ -7121,7 +7362,6 @@ void R_HDR_RenderBloomTexture(void) r_refdef.view.width = oldwidth; r_refdef.view.height = oldheight; r_refdef.view.colorscale = oldcolorscale; - r_frame++; // used only by R_GetCurrentTexture R_ResetViewRendering3D(); @@ -7499,7 +7739,6 @@ void R_RenderView(void) { if (r_timereport_active) R_TimeReport("start"); - r_frame++; // used only by R_GetCurrentTexture rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity if (!r_drawentities.integer) @@ -7620,6 +7859,7 @@ extern qboolean r_shadow_usingdeferredprepass; void R_RenderScene(void) { r_refdef.stats.renders++; + r_textureframe++; // used only by R_GetCurrentTexture R_UpdateFogColor(); @@ -8328,9 +8568,9 @@ texture_t *R_GetCurrentTexture(texture_t *t) dp_model_t *model = ent->model; q3shaderinfo_layer_tcmod_t *tcmod; - if (t->update_lastrenderframe == r_frame && t->update_lastrenderentity == (void *)ent) + if (t->update_lastrenderframe == r_textureframe && t->update_lastrenderentity == (void *)ent) return t->currentframe; - t->update_lastrenderframe = r_frame; + t->update_lastrenderframe = r_textureframe; t->update_lastrenderentity = (void *)ent; // switch to an alternate material if this is a q1bsp animated material @@ -8441,9 +8681,13 @@ texture_t *R_GetCurrentTexture(texture_t *t) if (t->currentskinframe->qpixels) R_SkinFrame_GenerateTexturesFromQPixels(t->currentskinframe, t->colormapping); t->basetexture = (!t->colormapping && t->currentskinframe->merged) ? t->currentskinframe->merged : t->currentskinframe->base; + if (!t->basetexture) + t->basetexture = r_texture_notexture; t->pantstexture = t->colormapping ? t->currentskinframe->pants : NULL; t->shirttexture = t->colormapping ? t->currentskinframe->shirt : NULL; t->nmaptexture = t->currentskinframe->nmap; + if (!t->nmaptexture) + t->nmaptexture = r_texture_blanknormalmap; t->glosstexture = r_texture_black; t->glowtexture = t->currentskinframe->glow; t->fogtexture = t->currentskinframe->fog; @@ -8453,6 +8697,8 @@ texture_t *R_GetCurrentTexture(texture_t *t) t->backgroundnmaptexture = t->backgroundcurrentskinframe->nmap; t->backgroundglosstexture = r_texture_black; t->backgroundglowtexture = t->backgroundcurrentskinframe->glow; + if (!t->backgroundnmaptexture) + t->backgroundnmaptexture = r_texture_blanknormalmap; } else { @@ -10050,83 +10296,40 @@ extern rtexture_t *r_shadow_prepasslightingdiffusetexture; extern rtexture_t *r_shadow_prepasslightingspeculartexture; static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean prepass) { - qboolean reflect = (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION)) && !prepass; - qboolean refract = (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION)) && !prepass; - - if (r_waterstate.renderingscene && (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION))) - return; - - if ((rsurface.uselightmaptexture || (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)) - R_Mesh_ColorPointer(NULL, 0, 0); - else - R_Mesh_ColorPointer(rsurface.modellightmapcolor4f, rsurface.modellightmapcolor4f_bufferobject, rsurface.modellightmapcolor4f_bufferoffset); - - if (refract) + RSurf_PrepareVerticesForBatch(true, true, texturenumsurfaces, texturesurfacelist); + if (prepass) { - // render background - GL_BlendFunc(GL_ONE, GL_ZERO); + // render screenspace normalmap to texture GL_DepthMask(true); - GL_AlphaTest(false); - - GL_Color(1, 1, 1, 1); - R_Mesh_ColorPointer(NULL, 0, 0); - - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BACKGROUND); - RSurf_PrepareVerticesForBatch(true, true, texturenumsurfaces, texturesurfacelist); - R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset); - R_Mesh_TexCoordPointer(1, 3, rsurface.svector3f, rsurface.svector3f_bufferobject, rsurface.svector3f_bufferoffset); - R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset); - R_Mesh_TexCoordPointer(3, 3, rsurface.normal3f, rsurface.normal3f_bufferobject, rsurface.normal3f_bufferoffset); - R_Mesh_TexCoordPointer(4, 2, rsurface.modeltexcoordlightmap2f, rsurface.modeltexcoordlightmap2f_bufferobject, rsurface.modeltexcoordlightmap2f_bufferoffset); - RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist); + R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, prepass ? RSURFPASS_DEFERREDGEOMETRY : RSURFPASS_BASE); + RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); GL_LockArrays(0, 0); - - GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); - GL_DepthMask(false); - if ((rsurface.uselightmaptexture || (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)) - R_Mesh_ColorPointer(NULL, 0, 0); - else - R_Mesh_ColorPointer(rsurface.modellightmapcolor4f, rsurface.modellightmapcolor4f_bufferobject, rsurface.modellightmapcolor4f_bufferoffset); } - - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, prepass ? RSURFPASS_DEFERREDGEOMETRY : RSURFPASS_BASE); - - RSurf_PrepareVerticesForBatch(true, true, texturenumsurfaces, texturesurfacelist); - R_Mesh_TexCoordPointer(0, 2, rsurface.texcoordtexture2f, rsurface.texcoordtexture2f_bufferobject, rsurface.texcoordtexture2f_bufferoffset); - R_Mesh_TexCoordPointer(1, 3, rsurface.svector3f, rsurface.svector3f_bufferobject, rsurface.svector3f_bufferoffset); - R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset); - R_Mesh_TexCoordPointer(3, 3, rsurface.normal3f, rsurface.normal3f_bufferobject, rsurface.normal3f_bufferoffset); - if (!prepass) - R_Mesh_TexCoordPointer(4, 2, rsurface.modeltexcoordlightmap2f, rsurface.modeltexcoordlightmap2f_bufferobject, rsurface.modeltexcoordlightmap2f_bufferoffset); - - if (refract) + else if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION)) && !r_waterstate.renderingscene) { - GL_BlendFunc(GL_ONE, GL_ZERO); + // render water or distortion background, then blend surface on top GL_DepthMask(true); - GL_AlphaTest(false); + R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BACKGROUND); + RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist); + GL_LockArrays(0, 0); + GL_DepthMask(false); + R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, prepass ? RSURFPASS_DEFERREDGEOMETRY : RSURFPASS_BASE); + RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist); + GL_LockArrays(0, 0); } else { - GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2); + // render surface normally GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)); - GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0 && !r_shadow_usingdeferredprepass); - } - - if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) - { - if (refract || reflect) + R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, prepass ? RSURFPASS_DEFERREDGEOMETRY : RSURFPASS_BASE); + if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist); - else + else if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) RSurf_DrawBatch_WithLightmapSwitching(texturenumsurfaces, texturesurfacelist); - } - else - { - if (refract || reflect) - RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(texturenumsurfaces, texturesurfacelist); else RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); + GL_LockArrays(0, 0); } - GL_LockArrays(0, 0); } static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth) @@ -11745,31 +11948,19 @@ void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean dep r_surfacelist[numsurfacelist++] = surfaces + j; } // update lightmaps if needed - if (update) + if (model->brushq1.firstrender) + { + model->brushq1.firstrender = false; + for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++) + if (update[j]) + R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j); + } + else if (update) { - int updated = 0; for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++) - { if (r_refdef.viewcache.world_surfacevisible[j]) - { if (update[j]) - { - updated++; R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j); - } - } - } - if (updated) - { - int count = model->brushq3.num_mergedlightmaps; - for (i = 0;i < count;i++) - { - if (model->brushq3.data_deluxemaps[i]) - R_FlushTexture(model->brushq3.data_deluxemaps[i]); - if (model->brushq3.data_lightmaps[i]) - R_FlushTexture(model->brushq3.data_lightmaps[i]); - } - } } // don't do anything if there were no surfaces if (!numsurfacelist) @@ -11891,17 +12082,6 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr R_BuildLightMap(ent, surfaces + j); } } - if (updated) - { - int count = model->brushq3.num_mergedlightmaps; - for (i = 0;i < count;i++) - { - if (model->brushq3.data_deluxemaps[i]) - R_FlushTexture(model->brushq3.data_deluxemaps[i]); - if (model->brushq3.data_lightmaps[i]) - R_FlushTexture(model->brushq3.data_lightmaps[i]); - } - } } if (update) for (j = model->firstmodelsurface, endj = model->firstmodelsurface + model->nummodelsurfaces;j < endj;j++)