X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=gl_rsurf.c;h=ab54df99bf29bfec11faa197882500c30484f6b5;hb=5d39354b42e1e601bb632b2e96631fad6c410b58;hp=f739601c0f88b5763bc1a47dfa5b76eb4eb532af;hpb=f556b7cd95cce4e56b37f93baeab190fbb97519e;p=xonotic%2Fdarkplaces.git diff --git a/gl_rsurf.c b/gl_rsurf.c index f739601c..ab54df99 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -28,7 +28,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cvar_t r_ambient = {0, "r_ambient", "0"}; cvar_t r_drawportals = {0, "r_drawportals", "0"}; cvar_t r_testvis = {0, "r_testvis", "0"}; -cvar_t r_detailtextures = {CVAR_SAVE, "r_detailtextures", "1"}; cvar_t r_surfaceworldnode = {0, "r_surfaceworldnode", "0"}; cvar_t r_drawcollisionbrushes_polygonfactor = {0, "r_drawcollisionbrushes_polygonfactor", "-1"}; cvar_t r_drawcollisionbrushes_polygonoffset = {0, "r_drawcollisionbrushes_polygonoffset", "0"}; @@ -489,6 +488,7 @@ void R_Q1BSP_Draw(entity_render_t *ent) model_t *model = ent->model; msurface_t *surface; q3mbrush_t *brush; + R_Mesh_Matrix(&ent->matrix); GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); GL_DepthMask(false); GL_DepthTest(true); @@ -656,6 +656,29 @@ void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, floa *outnumsurfacespointer = info.outnumsurfaces; } +void R_Q1BSP_CompileShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist) +{ + model_t *model = ent->model; + msurface_t *surface; + int surfacelistindex; + float projectdistance = lightradius + model->radius*2 + r_shadow_projectdistance.value; + texture_t *texture; + r_shadow_compilingrtlight->static_meshchain_shadow = Mod_ShadowMesh_Begin(r_shadow_mempool, 32768, 32768, NULL, NULL, NULL, false, false, true); + R_Shadow_PrepareShadowMark(model->brush.shadowmesh->numtriangles); + for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) + { + surface = model->data_surfaces + surfacelist[surfacelistindex]; + texture = surface->texture; + if ((texture->basematerialflags & (MATERIALFLAG_NODRAW | MATERIALFLAG_TRANSPARENT | MATERIALFLAG_WALL)) != MATERIALFLAG_WALL) + continue; + if (texture->textureflags & (Q3TEXTUREFLAG_TWOSIDED | Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) + continue; + R_Shadow_MarkVolumeFromBox(surface->num_firstshadowmeshtriangle, surface->num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, relativelightorigin, r_shadow_compilingrtlight->cullmins, r_shadow_compilingrtlight->cullmaxs, surface->mins, surface->maxs); + } + R_Shadow_VolumeFromList(model->brush.shadowmesh->numverts, model->brush.shadowmesh->numtriangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, model->brush.shadowmesh->neighbor3i, relativelightorigin, lightradius + model->radius + projectdistance, numshadowmark, shadowmarklist); + r_shadow_compilingrtlight->static_meshchain_shadow = Mod_ShadowMesh_Finish(r_shadow_mempool, r_shadow_compilingrtlight->static_meshchain_shadow, false, false); +} + extern float *rsurface_vertex3f; extern float *rsurface_svector3f; extern float *rsurface_tvector3f; @@ -667,7 +690,7 @@ void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, model_t *model = ent->model; msurface_t *surface; int surfacelistindex; - float projectdistance = lightradius + model->radius + r_shadow_projectdistance.value; + float projectdistance = lightradius + model->radius*2 + r_shadow_projectdistance.value; vec3_t modelorg; texture_t *texture; // check the box in modelspace, it was already checked in worldspace @@ -675,42 +698,25 @@ void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, return; if (r_drawcollisionbrushes.integer >= 2) return; - if (!r_shadow_compilingrtlight) - R_UpdateAllTextureInfo(ent); + R_UpdateAllTextureInfo(ent); if (model->brush.shadowmesh) { R_Shadow_PrepareShadowMark(model->brush.shadowmesh->numtriangles); - if (r_shadow_compilingrtlight) - { - for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) - { - surface = model->data_surfaces + surfacelist[surfacelistindex]; - texture = surface->texture; - if ((texture->basematerialflags & (MATERIALFLAG_NODRAW | MATERIALFLAG_TRANSPARENT | MATERIALFLAG_WALL)) != MATERIALFLAG_WALL) - continue; - if (texture->textureflags & (Q3TEXTUREFLAG_TWOSIDED | Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) - continue; - R_Shadow_MarkVolumeFromBox(surface->num_firstshadowmeshtriangle, surface->num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, relativelightorigin, lightmins, lightmaxs, surface->mins, surface->maxs); - } - } - else + for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) { - for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) - { - surface = model->data_surfaces + surfacelist[surfacelistindex]; - texture = surface->texture->currentframe; - if ((texture->currentmaterialflags & (MATERIALFLAG_NODRAW | MATERIALFLAG_TRANSPARENT | MATERIALFLAG_WALL)) != MATERIALFLAG_WALL) - continue; - if (texture->textureflags & (Q3TEXTUREFLAG_TWOSIDED | Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) - continue; - R_Shadow_MarkVolumeFromBox(surface->num_firstshadowmeshtriangle, surface->num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, relativelightorigin, lightmins, lightmaxs, surface->mins, surface->maxs); - } + surface = model->data_surfaces + surfacelist[surfacelistindex]; + texture = surface->texture->currentframe; + if ((texture->currentmaterialflags & (MATERIALFLAG_NODRAW | MATERIALFLAG_TRANSPARENT | MATERIALFLAG_WALL)) != MATERIALFLAG_WALL) + continue; + if (texture->textureflags & (Q3TEXTUREFLAG_TWOSIDED | Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) + continue; + R_Shadow_MarkVolumeFromBox(surface->num_firstshadowmeshtriangle, surface->num_triangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, relativelightorigin, lightmins, lightmaxs, surface->mins, surface->maxs); } R_Shadow_VolumeFromList(model->brush.shadowmesh->numverts, model->brush.shadowmesh->numtriangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, model->brush.shadowmesh->neighbor3i, relativelightorigin, lightradius + model->radius + projectdistance, numshadowmark, shadowmarklist); } else { - projectdistance = lightradius + ent->model->radius; + projectdistance = lightradius + ent->model->radius*2; Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg); for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) { @@ -728,97 +734,115 @@ void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, } } -void R_Q1BSP_DrawLight(entity_render_t *ent, float *lightcolor, int numsurfaces, const int *surfacelist) +#define RSURF_MAX_BATCHSURFACES 1024 + +void R_Q1BSP_DrawLight(entity_render_t *ent, float *lightcolorbase, int numsurfaces, const int *surfacelist) { model_t *model = ent->model; msurface_t *surface; texture_t *texture; - int surfacelistindex; + int surfacelistindex, batchnumsurfaces; + msurface_t *batchsurfacelist[RSURF_MAX_BATCHSURFACES]; vec3_t modelorg; + texture_t *tex; + vec3_t lightcolorpants, lightcolorshirt; + rtexture_t *basetexture = NULL; + rtexture_t *glosstexture = NULL; + float specularscale = 0; + qboolean skip; if (r_drawcollisionbrushes.integer >= 2) return; - if (r_shadow_compilingrtlight) + R_UpdateAllTextureInfo(ent); + Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg); + tex = NULL; + texture = NULL; + skip = false; + batchnumsurfaces = 0; + for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) { - // if compiling an rtlight, capture the meshes - int tri; - int *e; - float *lightmins, *lightmaxs, *v[3], *vertex3f; - for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) + if ((ent == r_refdef.worldentity && !r_worldsurfacevisible[surfacelist[surfacelistindex]])) + continue; + surface = model->data_surfaces + surfacelist[surfacelistindex]; + if (tex != surface->texture) { - surface = model->data_surfaces + surfacelist[surfacelistindex]; - texture = surface->texture; - if ((texture->basematerialflags & (MATERIALFLAG_WALL | MATERIALFLAG_TRANSPARENT)) != MATERIALFLAG_WALL || !surface->num_triangles) - continue; - e = surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle; - vertex3f = surface->groupmesh->data_vertex3f; - lightmins = r_shadow_compilingrtlight->cullmins; - lightmaxs = r_shadow_compilingrtlight->cullmaxs; - for (tri = 0;tri < surface->num_triangles;tri++, e += 3) + if (batchnumsurfaces > 0) { - v[0] = vertex3f + e[0] * 3; - v[1] = vertex3f + e[1] * 3; - v[2] = vertex3f + e[2] * 3; - if (PointInfrontOfTriangle(r_shadow_compilingrtlight->shadoworigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2]))) - Mod_ShadowMesh_AddMesh(r_shadow_mempool, r_shadow_compilingrtlight->static_meshchain_light, surface->texture->skin.base, surface->texture->skin.gloss, surface->texture->skin.nmap, surface->groupmesh->data_vertex3f, surface->groupmesh->data_svector3f, surface->groupmesh->data_tvector3f, surface->groupmesh->data_normal3f, surface->groupmesh->data_texcoordtexture2f, 1, e); + R_Shadow_RenderSurfacesLighting(ent, texture, batchnumsurfaces, batchsurfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, modelorg); + batchnumsurfaces = 0; } - } - } - else - { - R_UpdateAllTextureInfo(ent); - Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg); - for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++) - { - if (ent == r_refdef.worldentity && !r_worldsurfacevisible[surfacelist[surfacelistindex]]) - continue; - surface = model->data_surfaces + surfacelist[surfacelistindex]; + tex = surface->texture; texture = surface->texture->currentframe; // FIXME: transparent surfaces need to be lit later - if ((texture->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_TRANSPARENT)) != MATERIALFLAG_WALL || !surface->num_triangles) + skip = (texture->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_TRANSPARENT)) != MATERIALFLAG_WALL; + if (skip) continue; if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) qglDisable(GL_CULL_FACE); - RSurf_SetVertexPointer(ent, texture, surface, modelorg); - if (!rsurface_svector3f) + else + qglEnable(GL_CULL_FACE); + glosstexture = r_texture_black; + specularscale = 0; + if (texture->skin.gloss) + { + if (r_shadow_gloss.integer >= 1 && r_shadow_glossintensity.value > 0 && r_shadow_rtlight->specularscale > 0) + { + glosstexture = texture->skin.gloss; + specularscale = r_shadow_rtlight->specularscale * r_shadow_glossintensity.value; + } + } + else { - rsurface_svector3f = varray_svector3f; - rsurface_tvector3f = varray_tvector3f; - rsurface_normal3f = varray_normal3f; - Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f); + if (r_shadow_gloss.integer >= 2 && r_shadow_gloss2intensity.value > 0 && r_shadow_glossintensity.value > 0 && r_shadow_rtlight->specularscale > 0) + { + glosstexture = r_texture_white; + specularscale = r_shadow_rtlight->specularscale * r_shadow_gloss2intensity.value; + } } + VectorClear(lightcolorpants); + VectorClear(lightcolorshirt); if (ent->colormap >= 0) { - vec3_t lightcolorpants, lightcolorshirt; // 128-224 are backwards ranges int b = (ent->colormap & 0xF) << 4;b += (b >= 128 && b < 224) ? 4 : 12; - if (texture->skin.pants && b >= 224) + if (texture->skin.pants && b < 224) { qbyte *bcolor = (qbyte *) (&palette_complete[b]); - lightcolorpants[0] = lightcolor[0] * bcolor[0] * (1.0f / 255.0f); - lightcolorpants[1] = lightcolor[1] * bcolor[1] * (1.0f / 255.0f); - lightcolorpants[2] = lightcolor[2] * bcolor[2] * (1.0f / 255.0f); + lightcolorpants[0] = lightcolorbase[0] * bcolor[0] * (1.0f / 255.0f); + lightcolorpants[1] = lightcolorbase[1] * bcolor[1] * (1.0f / 255.0f); + lightcolorpants[2] = lightcolorbase[2] * bcolor[2] * (1.0f / 255.0f); } - else - VectorClear(lightcolorpants); // 128-224 are backwards ranges b = (ent->colormap & 0xF0);b += (b >= 128 && b < 224) ? 4 : 12; - if (texture->skin.shirt && b >= 224) + if (texture->skin.shirt && b < 224) { qbyte *bcolor = (qbyte *) (&palette_complete[b]); - lightcolorshirt[0] = lightcolor[0] * bcolor[0] * (1.0f / 255.0f); - lightcolorshirt[1] = lightcolor[1] * bcolor[1] * (1.0f / 255.0f); - lightcolorshirt[2] = lightcolor[2] * bcolor[2] * (1.0f / 255.0f); + lightcolorshirt[0] = lightcolorbase[0] * bcolor[0] * (1.0f / 255.0f); + lightcolorshirt[1] = lightcolorbase[1] * bcolor[1] * (1.0f / 255.0f); + lightcolorshirt[2] = lightcolorbase[2] * bcolor[2] * (1.0f / 255.0f); } - else - VectorClear(lightcolorshirt); - R_Shadow_RenderLighting(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle), rsurface_vertex3f, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f, surface->groupmesh->data_texcoordtexture2f, lightcolor, lightcolorpants, lightcolorshirt, texture->skin.base, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, texture->skin.gloss); + basetexture = texture->skin.base; } else - R_Shadow_RenderLighting(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle), rsurface_vertex3f, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f, surface->groupmesh->data_texcoordtexture2f, lightcolor, vec3_origin, vec3_origin, texture->skin.merged ? texture->skin.merged : texture->skin.base, NULL, NULL, texture->skin.nmap, texture->skin.gloss); - if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) - qglEnable(GL_CULL_FACE); + basetexture = texture->skin.merged ? texture->skin.merged : texture->skin.base; + if ((r_shadow_rtlight->ambientscale + r_shadow_rtlight->diffusescale) * (VectorLength2(lightcolorbase) + VectorLength2(lightcolorpants) + VectorLength2(lightcolorshirt)) + specularscale * VectorLength2(lightcolorbase) < (1.0f / 1048576.0f)) + skip = true; } + if (!skip && surface->num_triangles) + { + if (batchnumsurfaces == RSURF_MAX_BATCHSURFACES) + { + R_Shadow_RenderSurfacesLighting(ent, texture, batchnumsurfaces, batchsurfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, modelorg); + batchnumsurfaces = 0; + } + batchsurfacelist[batchnumsurfaces++] = surface; + } + } + if (batchnumsurfaces > 0) + { + R_Shadow_RenderSurfacesLighting(ent, texture, batchnumsurfaces, batchsurfacelist, lightcolorbase, lightcolorpants, lightcolorshirt, basetexture, texture->skin.pants, texture->skin.shirt, texture->skin.nmap, glosstexture, specularscale, modelorg); + batchnumsurfaces = 0; } + qglEnable(GL_CULL_FACE); } #if 0 @@ -841,7 +865,6 @@ void GL_Surf_Init(void) Cvar_RegisterVariable(&r_ambient); Cvar_RegisterVariable(&r_drawportals); Cvar_RegisterVariable(&r_testvis); - Cvar_RegisterVariable(&r_detailtextures); Cvar_RegisterVariable(&r_surfaceworldnode); Cvar_RegisterVariable(&r_drawcollisionbrushes_polygonfactor); Cvar_RegisterVariable(&r_drawcollisionbrushes_polygonoffset);