From d3a4a802a78582b211f2eadb3d383bb9c2e1bbb1 Mon Sep 17 00:00:00 2001 From: havoc Date: Mon, 14 May 2007 10:28:00 +0000 Subject: [PATCH] restored the old lightmap batching code that I removed when adding the lightmap merging, this helps a lot on maps that don't fit in one 1024x1024 lightmap git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7273 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 156 ++++++++++++++++++++++++++++++++++++++++++----------- render.h | 3 +- 2 files changed, 127 insertions(+), 32 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 110fdf95..26783594 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -886,10 +886,10 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl // lightmapped wall shaderfilename = "glsl/default.glsl"; permutation = SHADERPERMUTATION_USES_VERTEXSHADER | SHADERPERMUTATION_USES_FRAGMENTSHADER; - if (r_glsl_deluxemapping.integer >= 1 && rsurface_lightmaptexture && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping) + if (r_glsl_deluxemapping.integer >= 1 && rsurface_uselightmaptexture && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping) { // deluxemapping (light direction texture) - if (rsurface_lightmaptexture && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping && r_refdef.worldmodel->brushq3.deluxemapping_modelspace) + if (rsurface_uselightmaptexture && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping && r_refdef.worldmodel->brushq3.deluxemapping_modelspace) permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE; else permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE; @@ -3386,8 +3386,7 @@ qboolean rsurface_generatedvertex; const entity_render_t *rsurface_entity; const model_t *rsurface_model; texture_t *rsurface_texture; -rtexture_t *rsurface_lightmaptexture; -rtexture_t *rsurface_deluxemaptexture; +qboolean rsurface_uselightmaptexture; rsurfmode_t rsurface_mode; int rsurface_lightmode; // 0 = lightmap or fullbright, 1 = color array from q3bsp, 2 = vertex shaded model @@ -3400,8 +3399,7 @@ void RSurf_CleanUp(void) } GL_AlphaTest(false); rsurface_mode = RSURFMODE_NONE; - rsurface_lightmaptexture = NULL; - rsurface_deluxemaptexture = NULL; + rsurface_uselightmaptexture = false; rsurface_texture = NULL; } @@ -3691,6 +3689,112 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel } } +static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurface_t **texturesurfacelist, int lightmaptexunit, int deluxemaptexunit) +{ + int i; + int j; + const msurface_t *surface = texturesurfacelist[0]; + const msurface_t *surface2; + int firstvertex; + int endvertex; + int numvertices; + int numtriangles; + // TODO: lock all array ranges before render, rather than on each surface + if (texturenumsurfaces == 1) + { + R_Mesh_TexBind(lightmaptexunit, R_GetTexture(surface->lightmaptexture)); + if (deluxemaptexunit >= 0) + R_Mesh_TexBind(deluxemaptexunit, R_GetTexture(surface->deluxemaptexture)); + GL_LockArrays(surface->num_firstvertex, surface->num_vertices); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle)); + } + else if (r_batchmode.integer == 2) + { + #define MAXBATCHTRIANGLES 4096 + int batchtriangles = 0; + int batchelements[MAXBATCHTRIANGLES*3]; + for (i = 0;i < texturenumsurfaces;i = j) + { + surface = texturesurfacelist[i]; + R_Mesh_TexBind(lightmaptexunit, R_GetTexture(surface->lightmaptexture)); + if (deluxemaptexunit >= 0) + R_Mesh_TexBind(deluxemaptexunit, R_GetTexture(surface->deluxemaptexture)); + j = i + 1; + if (surface->num_triangles > MAXBATCHTRIANGLES) + { + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle)); + continue; + } + memcpy(batchelements, rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle, surface->num_triangles * sizeof(int[3])); + batchtriangles = surface->num_triangles; + firstvertex = surface->num_firstvertex; + endvertex = surface->num_firstvertex + surface->num_vertices; + for (;j < texturenumsurfaces;j++) + { + surface2 = texturesurfacelist[j]; + if (surface2->lightmaptexture != surface->lightmaptexture || batchtriangles + surface2->num_triangles > MAXBATCHTRIANGLES) + break; + memcpy(batchelements + batchtriangles * 3, rsurface_model->surfmesh.data_element3i + 3 * surface2->num_firsttriangle, surface2->num_triangles * sizeof(int[3])); + batchtriangles += surface2->num_triangles; + firstvertex = min(firstvertex, surface2->num_firstvertex); + endvertex = max(endvertex, surface2->num_firstvertex + surface2->num_vertices); + } + surface2 = texturesurfacelist[j-1]; + numvertices = endvertex - firstvertex; + R_Mesh_Draw(firstvertex, numvertices, batchtriangles, batchelements, 0, 0); + } + } + else if (r_batchmode.integer == 1) + { +#if 0 + Con_Printf("%s batch sizes ignoring lightmap:", rsurface_texture->name); + for (i = 0;i < texturenumsurfaces;i = j) + { + surface = texturesurfacelist[i]; + for (j = i + 1, surface2 = surface + 1;j < texturenumsurfaces;j++, surface2++) + if (texturesurfacelist[j] != surface2) + break; + Con_Printf(" %i", j - i); + } + Con_Printf("\n"); + Con_Printf("%s batch sizes honoring lightmap:", rsurface_texture->name); +#endif + for (i = 0;i < texturenumsurfaces;i = j) + { + surface = texturesurfacelist[i]; + R_Mesh_TexBind(lightmaptexunit, R_GetTexture(surface->lightmaptexture)); + if (deluxemaptexunit >= 0) + R_Mesh_TexBind(deluxemaptexunit, R_GetTexture(surface->deluxemaptexture)); + for (j = i + 1, surface2 = surface + 1;j < texturenumsurfaces;j++, surface2++) + if (texturesurfacelist[j] != surface2 || texturesurfacelist[j]->lightmaptexture != surface->lightmaptexture) + break; +#if 0 + Con_Printf(" %i", j - i); +#endif + surface2 = texturesurfacelist[j-1]; + numvertices = surface2->num_firstvertex + surface2->num_vertices - surface->num_firstvertex; + numtriangles = surface2->num_firsttriangle + surface2->num_triangles - surface->num_firsttriangle; + GL_LockArrays(surface->num_firstvertex, numvertices); + R_Mesh_Draw(surface->num_firstvertex, numvertices, numtriangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle)); + } +#if 0 + Con_Printf("\n"); +#endif + } + else + { + for (i = 0;i < texturenumsurfaces;i++) + { + surface = texturesurfacelist[i]; + R_Mesh_TexBind(lightmaptexunit, R_GetTexture(surface->lightmaptexture)); + if (deluxemaptexunit >= 0) + R_Mesh_TexBind(deluxemaptexunit, R_GetTexture(surface->deluxemaptexture)); + GL_LockArrays(surface->num_firstvertex, surface->num_vertices); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle)); + } + } +} + static void RSurf_DrawBatch_ShowSurfaces(int texturenumsurfaces, msurface_t **texturesurfacelist) { int j; @@ -3796,8 +3900,7 @@ static void RSurf_DrawBatch_GL11_Lightmap(int texturenumsurfaces, msurface_t **t if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(texturenumsurfaces, texturesurfacelist, r, g, b, a); R_Mesh_ColorPointer(rsurface_lightmapcolor4f, rsurface_lightmapcolor4f_bufferobject, rsurface_lightmapcolor4f_bufferoffset); GL_Color(r, g, b, a); - R_Mesh_TexBind(0, R_GetTexture(rsurface_lightmaptexture)); - RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); + RSurf_DrawBatch_WithLightmapSwitching(texturenumsurfaces, texturesurfacelist, 0, -1); } static void RSurf_DrawBatch_GL11_Unlit(int texturenumsurfaces, msurface_t **texturesurfacelist, float r, float g, float b, float a, qboolean applycolor, qboolean applyfog) @@ -4039,11 +4142,11 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, msurface_t **t R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap)); R_Mesh_ColorPointer(NULL, 0, 0); } - else if (rsurface_lightmaptexture) + else if (rsurface_uselightmaptexture) { - R_Mesh_TexBind(7, R_GetTexture(rsurface_lightmaptexture)); + R_Mesh_TexBind(7, R_GetTexture(texturesurfacelist[0]->lightmaptexture)); if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) - R_Mesh_TexBind(8, R_GetTexture(rsurface_deluxemaptexture)); + R_Mesh_TexBind(8, R_GetTexture(texturesurfacelist[0]->deluxemaptexture)); R_Mesh_ColorPointer(NULL, 0, 0); } else @@ -4054,13 +4157,10 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, msurface_t **t R_Mesh_ColorPointer(rsurface_model->surfmesh.data_lightmapcolor4f, rsurface_model->surfmesh.vbo, rsurface_model->surfmesh.vbooffset_lightmapcolor4f); } - if (rsurface_lightmaptexture && !(rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) - { - R_Mesh_TexBind(7, R_GetTexture(rsurface_lightmaptexture)); - if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) - R_Mesh_TexBind(8, R_GetTexture(rsurface_deluxemaptexture)); - } - RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); + if (rsurface_uselightmaptexture && !(rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) + RSurf_DrawBatch_WithLightmapSwitching(texturenumsurfaces, texturesurfacelist, 7, r_glsl_permutation->loc_Texture_Deluxemap >= 0 ? 8 : -1); + else + RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); if (rsurface_texture->backgroundnumskinframes && !(rsurface_texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)) { } @@ -4130,7 +4230,7 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, msurface_t **t R_Mesh_TextureState(&m); if (rsurface_lightmode == 2) RSurf_DrawBatch_GL11_VertexShade(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog); - else if (rsurface_lightmaptexture) + else if (rsurface_uselightmaptexture) RSurf_DrawBatch_GL11_Lightmap(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog); else RSurf_DrawBatch_GL11_VertexColor(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog); @@ -4231,7 +4331,7 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, msurface_t **t R_Mesh_TextureState(&m); if (rsurface_lightmode == 2) RSurf_DrawBatch_GL11_VertexShade(texturenumsurfaces, texturesurfacelist, 1, 1, 1, 1, false, false); - else if (rsurface_lightmaptexture) + else if (rsurface_uselightmaptexture) RSurf_DrawBatch_GL11_Lightmap(texturenumsurfaces, texturesurfacelist, 1, 1, 1, 1, false, false); else RSurf_DrawBatch_GL11_VertexColor(texturenumsurfaces, texturesurfacelist, 1, 1, 1, 1, false, false); @@ -4429,8 +4529,7 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const texture = surface->texture; R_UpdateTextureInfo(ent, texture); rsurface_texture = texture->currentframe; - rsurface_lightmaptexture = surface->lightmaptexture; - rsurface_deluxemaptexture = surface->deluxemaptexture; + rsurface_uselightmaptexture = surface->lightmaptexture != NULL; // scan ahead until we find a different texture endsurface = min(i + 1024, numsurfaces); texturenumsurfaces = 0; @@ -4438,7 +4537,7 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const for (;j < endsurface;j++) { surface = rsurface_model->data_surfaces + surfacelist[j]; - if (texture != surface->texture || rsurface_lightmaptexture != surface->lightmaptexture) + if (texture != surface->texture || rsurface_uselightmaptexture != (surface->lightmaptexture != NULL)) break; texturesurfacelist[texturenumsurfaces++] = surface; } @@ -4464,8 +4563,7 @@ void R_QueueSurfaceList(int numsurfaces, msurface_t **surfacelist, int flagsmask // use skin 1 instead) texture = surfacelist[i]->texture; rsurface_texture = texture->currentframe; - rsurface_lightmaptexture = surfacelist[i]->lightmaptexture; - rsurface_deluxemaptexture = surfacelist[i]->deluxemaptexture; + rsurface_uselightmaptexture = surfacelist[i]->lightmaptexture != NULL; if (!(rsurface_texture->currentmaterialflags & flagsmask)) { // if this texture is not the kind we want, skip ahead to the next one @@ -4488,7 +4586,7 @@ void R_QueueSurfaceList(int numsurfaces, msurface_t **surfacelist, int flagsmask else { // simply scan ahead until we find a different texture or lightmap state - for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface_lightmaptexture == surfacelist[j]->lightmaptexture;j++) + for (;j < numsurfaces && texture == surfacelist[j]->texture && rsurface_uselightmaptexture == (surfacelist[j]->lightmaptexture != NULL);j++) ; // render the range of surfaces R_DrawTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly); @@ -4715,8 +4813,7 @@ void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean dep flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL); f = 0; t = NULL; - rsurface_lightmaptexture = NULL; - rsurface_deluxemaptexture = NULL; + rsurface_uselightmaptexture = false; rsurface_texture = NULL; numsurfacelist = 0; j = model->firstmodelsurface; @@ -4802,8 +4899,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL); f = 0; t = NULL; - rsurface_lightmaptexture = NULL; - rsurface_deluxemaptexture = NULL; + rsurface_uselightmaptexture = false; rsurface_texture = NULL; numsurfacelist = 0; surface = model->data_surfaces + model->firstmodelsurface; diff --git a/render.h b/render.h index 0f0cfc31..3f7f1b34 100644 --- a/render.h +++ b/render.h @@ -246,8 +246,7 @@ extern qboolean rsurface_generatedvertex; extern const entity_render_t *rsurface_entity; extern const model_t *rsurface_model; extern texture_t *rsurface_texture; -extern rtexture_t *rsurface_lightmaptexture; -extern rtexture_t *rsurface_deluxemaptexture; +extern qboolean rsurface_uselightmaptexture; extern rsurfmode_t rsurface_mode; void RSurf_ActiveWorldEntity(void); -- 2.39.2