X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=gl_rmain.c;h=2ae129dcb7f26c8f5aea4075e3dfeb3de1a38a69;hb=c3edd749ac26c6322eafa8303e592df3c32ffd25;hp=120ee2e9082ae99c5a96dc5bea3fbc5e8f97b3c7;hpb=3b5d7c98e27e8bcbd432a045d2632559badeb21b;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index 120ee2e9..2ae129dc 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -76,6 +76,7 @@ cvar_t r_showcollisionbrushes_polygonoffset = {0, "r_showcollisionbrushes_polygo cvar_t r_showdisabledepthtest = {0, "r_showdisabledepthtest", "0", "disables depth testing on r_show* cvars, allowing you to see what hidden geometry the graphics card is processing"}; cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"}; cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"}; +cvar_t r_drawworld = {0, "r_drawworld","1", "draw world (most static stuff)"}; cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"}; cvar_t r_drawexteriormodel = {0, "r_drawexteriormodel","1", "draw your player model (e.g. in chase cam, reflections)"}; cvar_t r_cullentities_trace = {0, "r_cullentities_trace", "1", "probabistically cull invisible entities"}; @@ -675,7 +676,7 @@ static const char *builtinshaderstring = "#endif\n" "//uncomment these if you want to use them:\n" "uniform vec4 UserVec1;\n" -"// uniform vec4 UserVec2;\n" +"uniform vec4 UserVec2;\n" "// uniform vec4 UserVec3;\n" "// uniform vec4 UserVec4;\n" "// uniform float ClientTime;\n" @@ -693,44 +694,42 @@ static const char *builtinshaderstring = "#ifdef USEPOSTPROCESSING\n" "// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n" "// this code does a blur with the radius specified in the first component of r_glsl_postprocess_uservec1 and blends it using the second component\n" -" if (UserVec1.x > 100.0) {\n" -" // vec2 ts = textureSize(Texture_First, 0);\n" -" // vec2 px = vec2(1/ts.x, 1/ts.y);\n" -" vec2 px = PixelSize;\n" -" vec4 x1 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, px.y));\n" -" vec4 x2 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, 0.0));\n" -" vec4 x3 = texture2D(Texture_First, TexCoord1 + vec2(-px.x,-px.y));\n" -" vec4 x4 = texture2D(Texture_First, TexCoord1 + vec2( px.x, px.y));\n" -" vec4 x5 = texture2D(Texture_First, TexCoord1 + vec2( px.x, 0.0));\n" -" vec4 x6 = texture2D(Texture_First, TexCoord1 + vec2( px.x,-px.y));\n" -" vec4 y1 = texture2D(Texture_First, TexCoord1 + vec2( px.x,-px.y));\n" -" vec4 y2 = texture2D(Texture_First, TexCoord1 + vec2( 0.0,-px.y));\n" -" vec4 y3 = texture2D(Texture_First, TexCoord1 + vec2(-px.x,-px.y));\n" -" vec4 y4 = texture2D(Texture_First, TexCoord1 + vec2( px.x, px.y));\n" -" vec4 y5 = texture2D(Texture_First, TexCoord1 + vec2( 0.0, px.y));\n" -" vec4 y6 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, px.y));\n" -"" -" float px1 = -1.0 * (0.30*x1.r + 0.59*x1.g + 0.11*x1.b);\n" -" float px2 = -2.0 * (0.30*x2.r + 0.59*x2.g + 0.11*x2.b);\n" -" float px3 = -1.0 * (0.30*x3.r + 0.59*x3.g + 0.11*x3.b);\n" -" float px4 = 1.0 * (0.30*x4.r + 0.59*x4.g + 0.11*x4.b);\n" -" float px5 = 2.0 * (0.30*x5.r + 0.59*x5.g + 0.11*x5.b);\n" -" float px6 = 1.0 * (0.30*x6.r + 0.59*x6.g + 0.11*x6.b);\n" -" float py1 = -1.0 * (0.30*y1.r + 0.59*y1.g + 0.11*y1.b);\n" -" float py2 = -2.0 * (0.30*y2.r + 0.59*y2.g + 0.11*y2.b);\n" -" float py3 = -1.0 * (0.30*y3.r + 0.59*y3.g + 0.11*y3.b);\n" -" float py4 = 1.0 * (0.30*y4.r + 0.59*y4.g + 0.11*y4.b);\n" -" float py5 = 2.0 * (0.30*y5.r + 0.59*y5.g + 0.11*y5.b);\n" -" float py6 = 1.0 * (0.30*y6.r + 0.59*y6.g + 0.11*y6.b);\n" -" gl_FragColor = 0.25 * vec4(vec3(abs(px1 + px2 + px3 + px4 + px5 + px6)), 1) + 0.25 * vec4(vec3(abs(py1 + py2 + py3 + py4 + py5 + py6)), 1);\n" -" } else {\n" +" float sobel = 1.0;\n" +" // vec2 ts = textureSize(Texture_First, 0);\n" +" // vec2 px = vec2(1/ts.x, 1/ts.y);\n" +" vec2 px = PixelSize;\n" +" vec3 x1 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, px.y)).rgb;\n" +" vec3 x2 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, 0.0)).rgb;\n" +" vec3 x3 = texture2D(Texture_First, TexCoord1 + vec2(-px.x,-px.y)).rgb;\n" +" vec3 x4 = texture2D(Texture_First, TexCoord1 + vec2( px.x, px.y)).rgb;\n" +" vec3 x5 = texture2D(Texture_First, TexCoord1 + vec2( px.x, 0.0)).rgb;\n" +" vec3 x6 = texture2D(Texture_First, TexCoord1 + vec2( px.x,-px.y)).rgb;\n" +" vec3 y1 = texture2D(Texture_First, TexCoord1 + vec2( px.x,-px.y)).rgb;\n" +" vec3 y2 = texture2D(Texture_First, TexCoord1 + vec2( 0.0,-px.y)).rgb;\n" +" vec3 y3 = texture2D(Texture_First, TexCoord1 + vec2(-px.x,-px.y)).rgb;\n" +" vec3 y4 = texture2D(Texture_First, TexCoord1 + vec2( px.x, px.y)).rgb;\n" +" vec3 y5 = texture2D(Texture_First, TexCoord1 + vec2( 0.0, px.y)).rgb;\n" +" vec3 y6 = texture2D(Texture_First, TexCoord1 + vec2(-px.x, px.y)).rgb;\n" +" float px1 = -1.0 * dot(vec3(0.3, 0.59, 0.11), x1);\n" +" float px2 = -2.0 * dot(vec3(0.3, 0.59, 0.11), x2);\n" +" float px3 = -1.0 * dot(vec3(0.3, 0.59, 0.11), x3);\n" +" float px4 = 1.0 * dot(vec3(0.3, 0.59, 0.11), x4);\n" +" float px5 = 2.0 * dot(vec3(0.3, 0.59, 0.11), x5);\n" +" float px6 = 1.0 * dot(vec3(0.3, 0.59, 0.11), x6);\n" +" float py1 = -1.0 * dot(vec3(0.3, 0.59, 0.11), y1);\n" +" float py2 = -2.0 * dot(vec3(0.3, 0.59, 0.11), y2);\n" +" float py3 = -1.0 * dot(vec3(0.3, 0.59, 0.11), y3);\n" +" float py4 = 1.0 * dot(vec3(0.3, 0.59, 0.11), y4);\n" +" float py5 = 2.0 * dot(vec3(0.3, 0.59, 0.11), y5);\n" +" float py6 = 1.0 * dot(vec3(0.3, 0.59, 0.11), y6);\n" +" sobel = 0.25 * abs(px1 + px2 + px3 + px4 + px5 + px6) + 0.25 * abs(py1 + py2 + py3 + py4 + py5 + py6);\n" " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.987688, -0.156434)) * UserVec1.y;\n" " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.156434, -0.891007)) * UserVec1.y;\n" " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2( 0.891007, -0.453990)) * UserVec1.y;\n" " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2( 0.707107, 0.707107)) * UserVec1.y;\n" " gl_FragColor += texture2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*vec2(-0.453990, 0.891007)) * UserVec1.y;\n" -" gl_FragColor /= (1 + 5 * UserVec1.y);\n" -" }\n" +" gl_FragColor /= (1.0 + 5.0 * UserVec1.y);\n" +" gl_FragColor.rgb = gl_FragColor.rgb * (1.0 + UserVec2.x) + vec3(max(0.0, sobel - UserVec2.z))*UserVec2.y;\n" "#endif\n" "\n" "#ifdef USESATURATION\n" @@ -4930,7 +4929,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, case RENDERPATH_GL20: if (gl_mesh_separatearrays.integer) { - RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_ARRAY_VERTEXCOLOR | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist); + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist); R_Mesh_VertexPointer( 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset); R_Mesh_ColorPointer( 4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset); R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset); @@ -4941,7 +4940,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, } else { - RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist); + RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_VERTEXMESH_VERTEXCOLOR : 0) | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist); R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer); } R_SetupShader_SetPermutationGLSL(mode, permutation); @@ -5076,7 +5075,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, #ifdef SUPPORTCG if (gl_mesh_separatearrays.integer) { - RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_ARRAY_VERTEXCOLOR | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist); + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist); R_Mesh_VertexPointer( 3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset); R_Mesh_ColorPointer( 4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset); R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset); @@ -5087,7 +5086,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, } else { - RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist); + RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_VERTEXMESH_VERTEXCOLOR : 0) | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist); R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer); } R_SetupShader_SetPermutationCG(mode, permutation); @@ -6373,6 +6372,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_showdisabledepthtest); Cvar_RegisterVariable(&r_drawportals); Cvar_RegisterVariable(&r_drawentities); + Cvar_RegisterVariable(&r_drawworld); Cvar_RegisterVariable(&r_cullentities_trace); Cvar_RegisterVariable(&r_cullentities_trace_samples); Cvar_RegisterVariable(&r_cullentities_trace_tempentitysamples); @@ -10166,7 +10166,7 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const needsupdate |= BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR; break; case Q3DEFORM_WAVE: - batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS; + batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_TEXCOORD | BATCHNEED_NOGAPS; needsupdate |= BATCHNEED_VERTEXPOSITION | BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR; break; case Q3DEFORM_BULGE: @@ -10903,32 +10903,39 @@ static void RSurf_BindLightmapForBatch(void) } } -static void RSurf_BindReflectionForBatch(void) +static int RSurf_FindWaterPlaneForSurface(const msurface_t *surface) { - // pick the closest matching water plane and bind textures - int planeindex, vertexindex; + // pick the closest matching water plane + int planeindex, vertexindex, bestplaneindex = -1; float d, bestd; vec3_t vert; const float *v; - r_waterstate_waterplane_t *p, *bestp; + r_waterstate_waterplane_t *p; bestd = 0; - bestp = NULL; for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++) { if(p->camera_entity != rsurface.texture->camera_entity) continue; d = 0; + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, 1, &surface); for (vertexindex = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3;vertexindex < rsurface.batchnumvertices;vertexindex++, v += 3) { Matrix4x4_Transform(&rsurface.matrix, v, vert); d += fabs(PlaneDiff(vert, &p->plane)); } - if (bestd > d || !bestp) + if (bestd > d || bestplaneindex < 0) { bestd = d; - bestp = p; + bestplaneindex = planeindex; } } + return bestplaneindex; +} + +static void RSurf_BindReflectionForBatch(int planeindex) +{ + // pick the closest matching water plane and bind textures + r_waterstate_waterplane_t *bestp = planeindex >= 0 ? r_waterstate.waterplanes + planeindex : NULL; switch(vid.renderpath) { case RENDERPATH_CGGL: @@ -11259,33 +11266,55 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface GL_DepthMask(true); R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_DEFERREDGEOMETRY, texturenumsurfaces, texturesurfacelist); RSurf_DrawBatch(); + return; } - else if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA)) && !r_waterstate.renderingscene) - { - // render water or distortion background, then blend surface on top - GL_DepthMask(true); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BACKGROUND, texturenumsurfaces, texturesurfacelist); - RSurf_BindReflectionForBatch(); - if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) - RSurf_BindLightmapForBatch(); - RSurf_DrawBatch(); - GL_DepthMask(false); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist); - if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) - RSurf_BindLightmapForBatch(); - RSurf_DrawBatch(); - } - else + + // bind lightmap texture + + // water/refraction/reflection/camera surfaces have to be handled specially + if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA | MATERIALFLAG_REFLECTION)) && !r_waterstate.renderingscene) { - // render surface normally - GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)); - R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist); - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) - RSurf_BindReflectionForBatch(); - if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) - RSurf_BindLightmapForBatch(); - RSurf_DrawBatch(); + int start, end, startplaneindex; + for (start = 0;start < texturenumsurfaces;start = end) + { + startplaneindex = RSurf_FindWaterPlaneForSurface(texturesurfacelist[start]); + for (end = start + 1;end < texturenumsurfaces && startplaneindex == RSurf_FindWaterPlaneForSurface(texturesurfacelist[end]);end++) + ; + // now that we have a batch using the same planeindex, render it + if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA)) && !r_waterstate.renderingscene) + { + // render water or distortion background + GL_DepthMask(true); + R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BACKGROUND, end-start, texturesurfacelist + start); + RSurf_BindReflectionForBatch(startplaneindex); + if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) + RSurf_BindLightmapForBatch(); + RSurf_DrawBatch(); + // blend surface on top + GL_DepthMask(false); + R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start); + RSurf_DrawBatch(); + } + else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) && !r_waterstate.renderingscene) + { + // render surface with reflection texture as input + GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)); + R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start); + RSurf_BindReflectionForBatch(startplaneindex); + if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) + RSurf_BindLightmapForBatch(); + RSurf_DrawBatch(); + } + } + return; } + + // render surface batch normally + GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED)); + R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist); + if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) + RSurf_BindLightmapForBatch(); + RSurf_DrawBatch(); } static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth) @@ -12287,7 +12316,7 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS) continue; numtriangles = surface->num_triangles; - for (triangleindex = 0, e = model->surfmesh.data_element3i + 3*surface->num_firsttriangle;triangleindex < numtriangles;triangleindex++, e += 3) + for (triangleindex = 0, e = rsurface.modelelement3i + 3*surface->num_firsttriangle;triangleindex < numtriangles;triangleindex++, e += 3) { for (cornerindex = 0;cornerindex < 3;cornerindex++) {