size = smax*tmax;
size3 = size*3;
+ r_refdef.stats.lightmapupdatepixels += size;
+ r_refdef.stats.lightmapupdates++;
+
if (cl.buildlightmapmemorysize < size*sizeof(int[3]))
{
cl.buildlightmapmemorysize = size*sizeof(int[3]);
// add all the lightmaps
if (lightmap)
for (maps = 0;maps < MAXLIGHTMAPS && surface->lightmapinfo->styles[maps] != 255;maps++, lightmap += size3)
- for (scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[maps]], i = 0;i < size3;i++)
+ for (scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[maps]], i = 0;i < size3;i++)
bl[i] += lightmap[i] * scale;
}
// scaling, and remaps the 0-65536 (2x overbright) to 0-256, it will
// be doubled during rendering to achieve 2x overbright
// (0 = 0.0, 128 = 1.0, 256 = 2.0)
- if (model->brushq1.lightmaprgba)
+ for (i = 0;i < size;i++, bl += 3, stain += 3, out += 4)
{
- for (i = 0;i < size;i++)
- {
- l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
- l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
- l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
- *out++ = 255;
- }
- }
- else
- {
- for (i = 0;i < size;i++)
- {
- l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
- l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
- l = (*bl++ * *stain++) >> 16;*out++ = min(l, 255);
- }
+ l = (bl[0] * stain[0]) >> 16;out[2] = min(l, 255);
+ l = (bl[1] * stain[1]) >> 16;out[1] = min(l, 255);
+ l = (bl[2] * stain[2]) >> 16;out[0] = min(l, 255);
+ out[3] = 255;
}
R_UpdateTexture(surface->lightmaptexture, templight, surface->lightmapinfo->lightmaporigin[0], surface->lightmapinfo->lightmaporigin[1], smax, tmax);
{
for (maps = 0;maps < MAXLIGHTMAPS && surface->lightmapinfo->styles[maps] != 255;maps++, lightmap += size3, normalmap += size3)
{
- for (scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[maps]], i = 0;i < size;i++)
+ for (scale = r_refdef.scene.lightstylevalue[surface->lightmapinfo->styles[maps]], i = 0;i < size;i++)
{
// add the normalmap with weighting proportional to the style's lightmap intensity
l = (int)(VectorLength(lightmap + i*3) * scale);
bl = intblocklights;
out = templight;
// we simply renormalize the weighted normals to get a valid deluxemap
- if (model->brushq1.lightmaprgba)
- {
- for (i = 0;i < size;i++, bl += 3)
- {
- VectorCopy(bl, n);
- VectorNormalize(n);
- l = (int)(n[0] * 128 + 128);*out++ = bound(0, l, 255);
- l = (int)(n[1] * 128 + 128);*out++ = bound(0, l, 255);
- l = (int)(n[2] * 128 + 128);*out++ = bound(0, l, 255);
- *out++ = 255;
- }
- }
- else
+ for (i = 0;i < size;i++, bl += 3, out += 4)
{
- for (i = 0;i < size;i++, bl += 3)
- {
- VectorCopy(bl, n);
- VectorNormalize(n);
- l = (int)(n[0] * 128 + 128);*out++ = bound(0, l, 255);
- l = (int)(n[1] * 128 + 128);*out++ = bound(0, l, 255);
- l = (int)(n[2] * 128 + 128);*out++ = bound(0, l, 255);
- }
+ VectorCopy(bl, n);
+ VectorNormalize(n);
+ l = (int)(n[0] * 128 + 128);out[2] = bound(0, l, 255);
+ l = (int)(n[1] * 128 + 128);out[1] = bound(0, l, 255);
+ l = (int)(n[2] * 128 + 128);out[0] = bound(0, l, 255);
+ out[3] = 255;
}
R_UpdateTexture(surface->deluxemaptexture, templight, surface->lightmapinfo->lightmaporigin[0], surface->lightmapinfo->lightmaporigin[1], smax, tmax);
}
entity_render_t *ent;
model_t *model;
vec3_t org;
- if (r_refdef.worldmodel == NULL || !r_refdef.worldmodel->brush.data_nodes || !r_refdef.worldmodel->brushq1.lightdata)
+ if (r_refdef.scene.worldmodel == NULL || !r_refdef.scene.worldmodel->brush.data_nodes || !r_refdef.scene.worldmodel->brushq1.lightdata)
return;
fcolor[0] = cr1;
fcolor[1] = cg1;
fcolor[6] = cb2 - cb1;
fcolor[7] = (ca2 - ca1) * (1.0f / 64.0f);
- R_StainNode(r_refdef.worldmodel->brush.data_nodes + r_refdef.worldmodel->brushq1.hulls[0].firstclipnode, r_refdef.worldmodel, origin, radius, fcolor);
+ R_StainNode(r_refdef.scene.worldmodel->brush.data_nodes + r_refdef.scene.worldmodel->brushq1.hulls[0].firstclipnode, r_refdef.scene.worldmodel, origin, radius, fcolor);
// look for embedded bmodels
for (n = 0;n < cl.num_brushmodel_entities;n++)
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
GL_DepthMask(false);
GL_DepthRange(0, 1);
+ GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
GL_DepthTest(true);
GL_CullFace(GL_NONE);
R_Mesh_Matrix(&identitymatrix);
R_Mesh_ResetTextureState();
i = surfacelist[0];
- GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f) * r_view.colorscale,
- ((i & 0x0038) >> 3) * (1.0f / 7.0f) * r_view.colorscale,
- ((i & 0x01C0) >> 6) * (1.0f / 7.0f) * r_view.colorscale,
+ GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f) * r_refdef.view.colorscale,
+ ((i & 0x0038) >> 3) * (1.0f / 7.0f) * r_refdef.view.colorscale,
+ ((i & 0x01C0) >> 6) * (1.0f / 7.0f) * r_refdef.view.colorscale,
0.125f);
for (i = 0, v = vertex3f;i < numpoints;i++, v += 3)
VectorCopy(portal->points[i].position, v);
int i, leafnum;
mportal_t *portal;
float center[3], f;
- model_t *model = r_refdef.worldmodel;
+ model_t *model = r_refdef.scene.worldmodel;
if (model == NULL)
return;
- for (leafnum = 0;leafnum < r_refdef.worldmodel->brush.num_leafs;leafnum++)
+ for (leafnum = 0;leafnum < r_refdef.scene.worldmodel->brush.num_leafs;leafnum++)
{
- if (r_viewcache.world_leafvisible[leafnum])
+ if (r_refdef.viewcache.world_leafvisible[leafnum])
{
//for (portalnum = 0, portal = model->brush.data_portals;portalnum < model->brush.num_portals;portalnum++, portal++)
- for (portal = r_refdef.worldmodel->brush.data_leafs[leafnum].portals;portal;portal = portal->next)
+ for (portal = r_refdef.scene.worldmodel->brush.data_leafs[leafnum].portals;portal;portal = portal->next)
{
if (portal->numpoints <= POLYGONELEMENTS_MAXPOINTS)
if (!R_CullBox(portal->mins, portal->maxs))
}
}
-void R_View_WorldVisibility(void)
+void R_View_WorldVisibility(qboolean forcenovis)
{
int i, j, *mark;
mleaf_t *leaf;
mleaf_t *viewleaf;
- model_t *model = r_refdef.worldmodel;
+ model_t *model = r_refdef.scene.worldmodel;
if (!model)
return;
+ if (r_refdef.view.usecustompvs)
+ {
+ // clear the visible surface and leaf flags arrays
+ memset(r_refdef.viewcache.world_surfacevisible, 0, model->num_surfaces);
+ memset(r_refdef.viewcache.world_leafvisible, 0, model->brush.num_leafs);
+ r_refdef.viewcache.world_novis = false;
+
+ // simply cull each marked leaf to the frustum (view pyramid)
+ for (j = 0, leaf = model->brush.data_leafs;j < model->brush.num_leafs;j++, leaf++)
+ {
+ // if leaf is in current pvs and on the screen, mark its surfaces
+ if (CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
+ {
+ r_refdef.stats.world_leafs++;
+ r_refdef.viewcache.world_leafvisible[j] = true;
+ if (leaf->numleafsurfaces)
+ for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++)
+ r_refdef.viewcache.world_surfacevisible[*mark] = true;
+ }
+ }
+ return;
+ }
+
// if possible find the leaf the view origin is in
- viewleaf = model->brush.PointInLeaf ? model->brush.PointInLeaf(model, r_view.origin) : NULL;
+ viewleaf = model->brush.PointInLeaf ? model->brush.PointInLeaf(model, r_refdef.view.origin) : NULL;
// if possible fetch the visible cluster bits
if (!r_lockpvs.integer && model->brush.FatPVS)
- model->brush.FatPVS(model, r_view.origin, 2, r_viewcache.world_pvsbits, sizeof(r_viewcache.world_pvsbits));
+ model->brush.FatPVS(model, r_refdef.view.origin, 2, r_refdef.viewcache.world_pvsbits, sizeof(r_refdef.viewcache.world_pvsbits), false);
if (!r_lockvisibility.integer)
{
// clear the visible surface and leaf flags arrays
- memset(r_viewcache.world_surfacevisible, 0, model->num_surfaces);
- memset(r_viewcache.world_leafvisible, 0, model->brush.num_leafs);
+ memset(r_refdef.viewcache.world_surfacevisible, 0, model->num_surfaces);
+ memset(r_refdef.viewcache.world_leafvisible, 0, model->brush.num_leafs);
- r_viewcache.world_novis = false;
+ r_refdef.viewcache.world_novis = false;
// if floating around in the void (no pvs data available, and no
// portals available), simply use all on-screen leafs.
- if (!viewleaf || viewleaf->clusterindex < 0)
+ if (!viewleaf || viewleaf->clusterindex < 0 || forcenovis)
{
// no visibility method: (used when floating around in the void)
// simply cull each leaf to the frustum (view pyramid)
// similar to quake's RecursiveWorldNode but without cache misses
- r_viewcache.world_novis = true;
+ r_refdef.viewcache.world_novis = true;
for (j = 0, leaf = model->brush.data_leafs;j < model->brush.num_leafs;j++, leaf++)
{
// if leaf is in current pvs and on the screen, mark its surfaces
if (!R_CullBox(leaf->mins, leaf->maxs))
{
r_refdef.stats.world_leafs++;
- r_viewcache.world_leafvisible[j] = true;
+ r_refdef.viewcache.world_leafvisible[j] = true;
if (leaf->numleafsurfaces)
for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++)
- r_viewcache.world_surfacevisible[*mark] = true;
+ r_refdef.viewcache.world_surfacevisible[*mark] = true;
}
}
}
for (j = 0, leaf = model->brush.data_leafs;j < model->brush.num_leafs;j++, leaf++)
{
// if leaf is in current pvs and on the screen, mark its surfaces
- if (CHECKPVSBIT(r_viewcache.world_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
+ if (CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
{
r_refdef.stats.world_leafs++;
- r_viewcache.world_leafvisible[j] = true;
+ r_refdef.viewcache.world_leafvisible[j] = true;
if (leaf->numleafsurfaces)
for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++)
- r_viewcache.world_surfacevisible[*mark] = true;
+ r_refdef.viewcache.world_surfacevisible[*mark] = true;
}
}
}
while (leafstackpos)
{
leaf = leafstack[--leafstackpos];
- if (r_viewcache.world_leafvisible[leaf - model->brush.data_leafs])
+ if (r_refdef.viewcache.world_leafvisible[leaf - model->brush.data_leafs])
continue;
r_refdef.stats.world_leafs++;
- r_viewcache.world_leafvisible[leaf - model->brush.data_leafs] = true;
+ r_refdef.viewcache.world_leafvisible[leaf - model->brush.data_leafs] = true;
// mark any surfaces bounding this leaf
if (leaf->numleafsurfaces)
for (i = 0, mark = leaf->firstleafsurface;i < leaf->numleafsurfaces;i++, mark++)
- r_viewcache.world_surfacevisible[*mark] = true;
+ r_refdef.viewcache.world_surfacevisible[*mark] = true;
// follow portals into other leafs
// the checks are:
// if viewer is behind portal (portal faces outward into the scene)
for (p = leaf->portals;p;p = p->next)
{
r_refdef.stats.world_portals++;
- if (DotProduct(r_view.origin, p->plane.normal) < (p->plane.dist + 1)
- && !r_viewcache.world_leafvisible[p->past - model->brush.data_leafs]
- && CHECKPVSBIT(r_viewcache.world_pvsbits, p->past->clusterindex)
+ if (DotProduct(r_refdef.view.origin, p->plane.normal) < (p->plane.dist + 1)
+ && !r_refdef.viewcache.world_leafvisible[p->past - model->brush.data_leafs]
+ && CHECKPVSBIT(r_refdef.viewcache.world_pvsbits, p->past->clusterindex)
&& !R_CullBox(p->mins, p->maxs)
&& leafstackpos < (int)(sizeof(leafstack) / sizeof(leafstack[0])))
leafstack[leafstackpos++] = p->past;
{
if (ent->model == NULL)
return;
- if (ent == r_refdef.worldentity)
- R_DrawWorldSurfaces(true, true, false);
+ if (ent == r_refdef.scene.worldentity)
+ R_DrawWorldSurfaces(true, true, false, false, false);
+ else
+ R_DrawModelSurfaces(ent, true, true, false, false, false);
+}
+
+void R_Q1BSP_DrawAddWaterPlanes(entity_render_t *ent)
+{
+ model_t *model = ent->model;
+ if (model == NULL)
+ return;
+ if (ent == r_refdef.scene.worldentity)
+ R_DrawWorldSurfaces(false, false, false, true, false);
else
- R_DrawModelSurfaces(ent, true, true, false);
+ R_DrawModelSurfaces(ent, false, false, false, true, false);
}
void R_Q1BSP_Draw(entity_render_t *ent)
model_t *model = ent->model;
if (model == NULL)
return;
- if (ent == r_refdef.worldentity)
- R_DrawWorldSurfaces(false, true, false);
+ if (ent == r_refdef.scene.worldentity)
+ R_DrawWorldSurfaces(false, true, false, false, false);
else
- R_DrawModelSurfaces(ent, false, true, false);
+ R_DrawModelSurfaces(ent, false, true, false, false, false);
}
void R_Q1BSP_DrawDepth(entity_render_t *ent)
model_t *model = ent->model;
if (model == NULL)
return;
- if (ent == r_refdef.worldentity)
- R_DrawWorldSurfaces(false, false, true);
+ if (ent == r_refdef.scene.worldentity)
+ R_DrawWorldSurfaces(false, false, true, false, false);
else
- R_DrawModelSurfaces(ent, false, false, true);
+ R_DrawModelSurfaces(ent, false, false, true, false, false);
+}
+
+void R_Q1BSP_DrawDebug(entity_render_t *ent)
+{
+ if (ent->model == NULL)
+ return;
+ if (ent == r_refdef.scene.worldentity)
+ R_DrawWorldSurfaces(false, false, false, false, true);
+ else
+ R_DrawModelSurfaces(ent, false, false, false, false, true);
}
typedef struct r_q1bsp_getlightinfo_s
r_shadow_compilingrtlight->static_meshchain_shadow = Mod_ShadowMesh_Finish(r_main_mempool, r_shadow_compilingrtlight->static_meshchain_shadow, false, false, true);
}
+extern cvar_t r_polygonoffset_submodel_factor;
+extern cvar_t r_polygonoffset_submodel_offset;
void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativelightdirection, float lightradius, int modelnumsurfaces, const int *modelsurfacelist, const vec3_t lightmins, const vec3_t lightmaxs)
{
model_t *model = ent->model;
if (!BoxesOverlap(model->normalmins, model->normalmaxs, lightmins, lightmaxs))
return;
R_UpdateAllTextureInfo(ent);
+ if (ent->model->brush.submodel)
+ GL_PolygonOffset(r_refdef.shadowpolygonfactor + r_polygonoffset_submodel_factor.value, r_refdef.shadowpolygonoffset + r_polygonoffset_submodel_offset.value);
if (model->brush.shadowmesh)
{
R_Shadow_PrepareShadowMark(model->brush.shadowmesh->numtriangles);
}
R_Shadow_VolumeFromList(model->surfmesh.num_vertices, model->surfmesh.num_triangles, rsurface.vertex3f, model->surfmesh.data_element3i, model->surfmesh.data_neighbor3i, relativelightorigin, relativelightdirection, projectdistance, numshadowmark, shadowmarklist);
}
+ if (ent->model->brush.submodel)
+ GL_PolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset);
}
#define BATCHSIZE 1024
R_Shadow_RenderMode_End();
}
-#define RSURF_MAX_BATCHSURFACES 1024
+#define RSURF_MAX_BATCHSURFACES 8192
void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surfacelist, const unsigned char *trispvs)
{
model_t *model = ent->model;
msurface_t *surface;
- int i, k, l, m, mend, endsurface, batchnumsurfaces, batchnumtriangles, batchfirstvertex, batchlastvertex;
+ int i, k, kend, l, m, mend, endsurface, batchnumsurfaces, batchnumtriangles, batchfirstvertex, batchlastvertex, batchfirsttriangle;
qboolean usebufferobject, culltriangles;
const int *element3i;
msurface_t *batchsurfacelist[RSURF_MAX_BATCHSURFACES];
int batchelements[BATCHSIZE*3];
texture_t *tex;
CHECKGLERROR
- RSurf_ActiveModelEntity(ent, true, true);
R_UpdateAllTextureInfo(ent);
- CHECKGLERROR
culltriangles = r_shadow_culltriangles.integer && !(ent->flags & RENDER_NOSELFSHADOW);
element3i = rsurface.modelelement3i;
// this is a double loop because non-visible surface skipping has to be
{
batchnumsurfaces = 0;
endsurface = min(i + RSURF_MAX_BATCHSURFACES, numsurfaces);
- if (ent == r_refdef.worldentity)
+ if (ent == r_refdef.scene.worldentity)
{
for (;i < endsurface;i++)
- if (r_viewcache.world_surfacevisible[surfacelist[i]])
+ if (r_refdef.viewcache.world_surfacevisible[surfacelist[i]])
batchsurfacelist[batchnumsurfaces++] = model->data_surfaces + surfacelist[i];
}
else
}
if (!batchnumsurfaces)
continue;
- for (k = 0;k < batchnumsurfaces;k = l)
+ for (k = 0;k < batchnumsurfaces;k = kend)
{
surface = batchsurfacelist[k];
tex = surface->texture;
rsurface.texture = tex->currentframe;
+ // gather surfaces into a batch range
+ for (kend = k;kend < batchnumsurfaces && tex == batchsurfacelist[kend]->texture;kend++)
+ ;
+ // now figure out what to do with this particular range of surfaces
if (rsurface.texture->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_WATER))
{
if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
{
vec3_t tempcenter, center;
- for (l = k;l < batchnumsurfaces && tex == batchsurfacelist[l]->texture;l++)
+ for (l = k;l < kend;l++)
{
surface = batchsurfacelist[l];
tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f;
tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f;
tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f;
Matrix4x4_Transform(&rsurface.matrix, tempcenter, center);
- R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_view.origin : center, R_Q1BSP_DrawLight_TransparentCallback, ent, surface - rsurface.modelsurfaces, rsurface.rtlight);
+ R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_refdef.view.origin : center, R_Q1BSP_DrawLight_TransparentCallback, ent, surface - rsurface.modelsurfaces, rsurface.rtlight);
}
}
else
// use the bufferobject if all triangles are accepted
usebufferobject = true;
batchnumtriangles = 0;
- // note: this only accepts consecutive surfaces because
- // non-consecutive surfaces often have extreme vertex
- // ranges (due to large numbers of surfaces omitted
- // between them)
- surface = batchsurfacelist[k];
- for (l = k;l < batchnumsurfaces && surface == batchsurfacelist[l] && tex == surface->texture;l++, surface++)
+ batchfirsttriangle = surface->num_firsttriangle;
+ for (l = k;l < kend;l++)
{
+ surface = batchsurfacelist[l];
RSurf_PrepareVerticesForBatch(true, true, 1, &surface);
for (m = surface->num_firsttriangle, mend = m + surface->num_triangles;m < mend;m++)
{
- if (culltriangles)
+ if (trispvs)
{
- if (trispvs)
+ if (!CHECKPVSBIT(trispvs, m))
{
- if (!CHECKPVSBIT(trispvs, m))
- {
- usebufferobject = false;
- continue;
- }
+ usebufferobject = false;
+ continue;
}
- else
+ }
+ else if (culltriangles)
+ {
+ if (r_shadow_frontsidecasting.integer && !PointInfrontOfTriangle(rsurface.entitylightorigin, rsurface.vertex3f + element3i[m*3+0]*3, rsurface.vertex3f + element3i[m*3+1]*3, rsurface.vertex3f + element3i[m*3+2]*3))
{
- if (r_shadow_frontsidecasting.integer && !PointInfrontOfTriangle(rsurface.entitylightorigin, rsurface.vertex3f + element3i[m*3+0]*3, rsurface.vertex3f + element3i[m*3+1]*3, rsurface.vertex3f + element3i[m*3+2]*3))
- {
- usebufferobject = false;
- continue;
- }
+ usebufferobject = false;
+ continue;
}
}
- batchelements[batchnumtriangles*3+0] = element3i[m*3+0];
- batchelements[batchnumtriangles*3+1] = element3i[m*3+1];
- batchelements[batchnumtriangles*3+2] = element3i[m*3+2];
- batchnumtriangles++;
- r_refdef.stats.lights_lighttriangles++;
if (batchnumtriangles >= BATCHSIZE)
{
+ r_refdef.stats.lights_lighttriangles += batchnumtriangles;
Mod_VertexRangeFromElements(batchnumtriangles*3, batchelements, &batchfirstvertex, &batchlastvertex);
- R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, 0, 0);
+ if (usebufferobject && batchnumtriangles >= 100)
+ R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, ent->model->surfmesh.ebo, sizeof(int[3]) * batchfirsttriangle);
+ else
+ R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, 0, 0);
+ usebufferobject = true;
batchnumtriangles = 0;
- usebufferobject = false;
+ batchfirsttriangle = m;
}
+ batchelements[batchnumtriangles*3+0] = element3i[m*3+0];
+ batchelements[batchnumtriangles*3+1] = element3i[m*3+1];
+ batchelements[batchnumtriangles*3+2] = element3i[m*3+2];
+ batchnumtriangles++;
}
- r_refdef.stats.lights_lighttriangles += batchsurfacelist[l]->num_triangles;
}
if (batchnumtriangles > 0)
{
+ r_refdef.stats.lights_lighttriangles += batchnumtriangles;
Mod_VertexRangeFromElements(batchnumtriangles*3, batchelements, &batchfirstvertex, &batchlastvertex);
- if (usebufferobject)
- R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, ent->model->surfmesh.ebo, sizeof(int[3]) * batchsurfacelist[k]->num_firsttriangle);
+ if (usebufferobject && batchnumtriangles >= 100)
+ R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, ent->model->surfmesh.ebo, sizeof(int[3]) * batchfirsttriangle);
else
R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, 0, 0);
}
}
}
- else
- {
- // skip ahead to the next texture
- for (l = k;l < batchnumsurfaces && tex == batchsurfacelist[l]->texture;l++)
- ;
- }
}
}
}
int i;
const char *r, *newt;
skinframe_t *skinframe;
- m = r_refdef.worldmodel;
+ if (!r_refdef.scene.worldmodel)
+ {
+ Con_Printf("There is no worldmodel\n");
+ return;
+ }
+ m = r_refdef.scene.worldmodel;
if(Cmd_Argc() < 2)
{
newt = r;
for(i=0,t=m->data_textures;i<m->num_textures;i++,t++)
{
- if(t->width && !strcasecmp(t->name, r))
+ if(/*t->width && !strcasecmp(t->name, r)*/ matchpattern( t->name, r, true ) )
{
- if ((skinframe = R_SkinFrame_LoadExternal((char*)newt, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, true)))
+ if ((skinframe = R_SkinFrame_LoadExternal(newt, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, true)))
{
- t->skinframes[0] = skinframe;
+// t->skinframes[0] = skinframe;
+ t->currentskinframe = skinframe;
+ t->currentskinframe = skinframe;
Con_Printf("%s replaced with %s\n", r, newt);
- return;
}
else
{
model_t *m;
texture_t *t;
int i;
- m = r_refdef.worldmodel;
+ if (!r_refdef.scene.worldmodel)
+ {
+ Con_Printf("There is no worldmodel\n");
+ return;
+ }
+ m = r_refdef.scene.worldmodel;
Con_Print("Worldmodel textures :\n");
for(i=0,t=m->data_textures;i<m->num_textures;i++,t++)