#include "csprogs.h"
#include "cl_video.h"
#include "dpsoftrast.h"
+#include "cl_collision.h"
#ifdef SUPPORTD3D
#include <d3d9.h>
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"};
+cvar_t r_cullentities_trace_entityocclusion = { 0, "r_cullentities_trace_entityocclusion", "1", "check for occluding entities such as doors, not just world hull" };
cvar_t r_cullentities_trace_samples = {0, "r_cullentities_trace_samples", "2", "number of samples to test for entity culling (in addition to center sample)"};
cvar_t r_cullentities_trace_tempentitysamples = {0, "r_cullentities_trace_tempentitysamples", "-1", "number of samples to test for entity culling of temp entities (including all CSQC entities), -1 disables trace culling on these entities to prevent flicker (pvs still applies)"};
cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"};
cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
+cvar_t r_cullentities_trace_eyejitter = {0, "r_cullentities_trace_eyejitter", "16", "randomly offset rays from the eye by this much to reduce the odds of flickering"};
cvar_t r_sortentities = {0, "r_sortentities", "0", "sort entities before drawing (might be faster)"};
cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
geomstrings_list[geomstrings_count++] = "#define GLSL130\n";
fragstrings_list[fragstrings_count++] = "#define GLSL130\n";
}
+ // if we can do #version 120, we should (this adds the invariant keyword)
+ else if(vid.support.glshaderversion >= 120)
+ {
+ vertstrings_list[vertstrings_count++] = "#version 120\n";
+ geomstrings_list[geomstrings_count++] = "#version 120\n";
+ fragstrings_list[fragstrings_count++] = "#version 120\n";
+ vertstrings_list[vertstrings_count++] = "#define GLSL120\n";
+ geomstrings_list[geomstrings_count++] = "#define GLSL120\n";
+ fragstrings_list[fragstrings_count++] = "#define GLSL120\n";
+ }
+ // GLES also adds several things from GLSL120
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GLES2:
+ vertstrings_list[vertstrings_count++] = "#define GLES\n";
+ geomstrings_list[geomstrings_count++] = "#define GLES\n";
+ fragstrings_list[fragstrings_count++] = "#define GLES\n";
+ break;
+ default:
+ break;
+ }
// the first pretext is which type of shader to compile as
// (later these will all be bound together as a program object)
Cvar_RegisterVariable(&r_draw2d);
Cvar_RegisterVariable(&r_drawworld);
Cvar_RegisterVariable(&r_cullentities_trace);
+ Cvar_RegisterVariable(&r_cullentities_trace_entityocclusion);
Cvar_RegisterVariable(&r_cullentities_trace_samples);
Cvar_RegisterVariable(&r_cullentities_trace_tempentitysamples);
Cvar_RegisterVariable(&r_cullentities_trace_enlarge);
Cvar_RegisterVariable(&r_cullentities_trace_delay);
+ Cvar_RegisterVariable(&r_cullentities_trace_eyejitter);
Cvar_RegisterVariable(&r_sortentities);
Cvar_RegisterVariable(&r_drawviewmodel);
Cvar_RegisterVariable(&r_drawexteriormodel);
while (!r_framedata_mem || r_framedata_mem->current + size > r_framedata_mem->size)
{
// emergency - we ran out of space, allocate more memory
- newvalue = bound(0.25f, r_framedatasize.value * 2.0f, 256.0f);
+ // note: this has no upper-bound, we'll fail to allocate memory eventually and just die
+ newvalue = r_framedatasize.value * 2.0f;
+ // upper bound based on architecture - if we try to allocate more than this we could overflow, better to loop until we error out on allocation failure
+ if (sizeof(size_t) >= 8)
+ newvalue = bound(0.25f, newvalue, (float)(1ll << 42));
+ else
+ newvalue = bound(0.25f, newvalue, (float)(1 << 10));
// this might not be a growing it, but we'll allocate another buffer every time
Cvar_SetValueQuick(&r_framedatasize, newvalue);
R_FrameData_Resize(true);
}
}
-#define MAX_LINEOFSIGHTTRACES 64
-
-static qboolean R_CanSeeBox(int numsamples, vec_t enlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs)
+qboolean R_CanSeeBox(int numsamples, vec_t eyejitter, vec_t entboxenlarge, vec3_t eye, vec3_t entboxmins, vec3_t entboxmaxs)
{
int i;
+ vec3_t eyemins, eyemaxs;
vec3_t boxmins, boxmaxs;
vec3_t start;
vec3_t end;
dp_model_t *model = r_refdef.scene.worldmodel;
+ static vec3_t positions[] = {
+ { 0.5f, 0.5f, 0.5f },
+ { 0.0f, 0.0f, 0.0f },
+ { 0.0f, 0.0f, 1.0f },
+ { 0.0f, 1.0f, 0.0f },
+ { 0.0f, 1.0f, 1.0f },
+ { 1.0f, 0.0f, 0.0f },
+ { 1.0f, 0.0f, 1.0f },
+ { 1.0f, 1.0f, 0.0f },
+ { 1.0f, 1.0f, 1.0f },
+ };
+
+ // sample count can be set to -1 to skip this logic, for flicker-prone objects
+ if (numsamples < 0)
+ return true;
+
+ // view origin is not used for culling in portal/reflection/refraction renders or isometric views
+ if (r_refdef.view.useclipplane || !r_refdef.view.useperspective || r_trippy.integer)
+ return true;
- if (!model || !model->brush.TraceLineOfSight)
+ if (!r_cullentities_trace_entityocclusion.integer && (!model || !model->brush.TraceLineOfSight))
return true;
+ // expand the eye box a little
+ eyemins[0] = eye[0] - eyejitter;
+ eyemaxs[0] = eye[0] + eyejitter;
+ eyemins[1] = eye[1] - eyejitter;
+ eyemaxs[1] = eye[1] + eyejitter;
+ eyemins[2] = eye[2] - eyejitter;
+ eyemaxs[2] = eye[2] + eyejitter;
// expand the box a little
- boxmins[0] = (enlarge+1) * entboxmins[0] - enlarge * entboxmaxs[0];
- boxmaxs[0] = (enlarge+1) * entboxmaxs[0] - enlarge * entboxmins[0];
- boxmins[1] = (enlarge+1) * entboxmins[1] - enlarge * entboxmaxs[1];
- boxmaxs[1] = (enlarge+1) * entboxmaxs[1] - enlarge * entboxmins[1];
- boxmins[2] = (enlarge+1) * entboxmins[2] - enlarge * entboxmaxs[2];
- boxmaxs[2] = (enlarge+1) * entboxmaxs[2] - enlarge * entboxmins[2];
-
- // return true if eye is inside enlarged box
- if (BoxesOverlap(boxmins, boxmaxs, eye, eye))
+ boxmins[0] = (entboxenlarge + 1) * entboxmins[0] - entboxenlarge * entboxmaxs[0];
+ boxmaxs[0] = (entboxenlarge + 1) * entboxmaxs[0] - entboxenlarge * entboxmins[0];
+ boxmins[1] = (entboxenlarge + 1) * entboxmins[1] - entboxenlarge * entboxmaxs[1];
+ boxmaxs[1] = (entboxenlarge + 1) * entboxmaxs[1] - entboxenlarge * entboxmins[1];
+ boxmins[2] = (entboxenlarge + 1) * entboxmins[2] - entboxenlarge * entboxmaxs[2];
+ boxmaxs[2] = (entboxenlarge + 1) * entboxmaxs[2] - entboxenlarge * entboxmins[2];
+
+ // return true if eye overlaps enlarged box
+ if (BoxesOverlap(boxmins, boxmaxs, eyemins, eyemaxs))
return true;
- // try center
- VectorCopy(eye, start);
- VectorMAM(0.5f, boxmins, 0.5f, boxmaxs, end);
- if (model->brush.TraceLineOfSight(model, start, end))
+ // try specific positions in the box first - note that these can be cached
+ if (r_cullentities_trace_entityocclusion.integer)
+ {
+ for (i = 0; i < sizeof(positions) / sizeof(positions[0]); i++)
+ {
+ VectorCopy(eye, start);
+ end[0] = boxmins[0] + (boxmaxs[0] - boxmins[0]) * positions[i][0];
+ end[1] = boxmins[1] + (boxmaxs[1] - boxmins[1]) * positions[i][1];
+ end[2] = boxmins[2] + (boxmaxs[2] - boxmins[2]) * positions[i][2];
+ //trace_t trace = CL_TraceLine(start, end, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID, SUPERCONTENTS_SKY, 0.0f, true, false, NULL, true, true);
+ trace_t trace = CL_Cache_TraceLineSurfaces(start, end, MOVE_NORMAL, SUPERCONTENTS_SOLID, 0, MATERIALFLAGMASK_TRANSLUCENT);
+ // not picky - if the trace ended anywhere in the box we're good
+ if (BoxesOverlap(trace.endpos, trace.endpos, boxmins, boxmaxs))
+ return true;
+ }
+ }
+ else if (model->brush.TraceLineOfSight(model, start, end, boxmins, boxmaxs))
return true;
// try various random positions
- for (i = 0;i < numsamples;i++)
+ for (i = 0; i < numsamples; i++)
{
+ VectorSet(start, lhrandom(eyemins[0], eyemaxs[0]), lhrandom(eyemins[1], eyemaxs[1]), lhrandom(eyemins[2], eyemaxs[2]));
VectorSet(end, lhrandom(boxmins[0], boxmaxs[0]), lhrandom(boxmins[1], boxmaxs[1]), lhrandom(boxmins[2], boxmaxs[2]));
- if (model->brush.TraceLineOfSight(model, start, end))
+ if (r_cullentities_trace_entityocclusion.integer)
+ {
+ trace_t trace = CL_Cache_TraceLineSurfaces(start, end, MOVE_NORMAL, SUPERCONTENTS_SOLID, 0, MATERIALFLAGMASK_TRANSLUCENT);
+ // not picky - if the trace ended anywhere in the box we're good
+ if (BoxesOverlap(trace.endpos, trace.endpos, boxmins, boxmaxs))
+ return true;
+ }
+ else if (model->brush.TraceLineOfSight(model, start, end, boxmins, boxmaxs))
return true;
}
r_refdef.viewcache.entityvisible[i] = true;
}
}
- if(r_cullentities_trace.integer && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.TraceLineOfSight && !r_refdef.view.useclipplane && !r_trippy.integer)
- // sorry, this check doesn't work for portal/reflection/refraction renders as the view origin is not useful for culling
+ if (r_cullentities_trace.integer)
{
for (i = 0;i < r_refdef.scene.numentities;i++)
{
if (!r_refdef.viewcache.entityvisible[i])
continue;
ent = r_refdef.scene.entities[i];
- if(!(ent->flags & (RENDER_VIEWMODEL | RENDER_WORLDOBJECT | RENDER_NODEPTHTEST)) && !(ent->model && (ent->model->name[0] == '*')))
+ if (!(ent->flags & (RENDER_VIEWMODEL | RENDER_WORLDOBJECT | RENDER_NODEPTHTEST)) && !(ent->model && (ent->model->name[0] == '*')))
{
- samples = ent->entitynumber ? r_cullentities_trace_samples.integer : r_cullentities_trace_tempentitysamples.integer;
- if (samples < 0)
- continue; // temp entities do pvs only
- if(R_CanSeeBox(samples, r_cullentities_trace_enlarge.value, r_refdef.view.origin, ent->mins, ent->maxs))
+ samples = ent->last_trace_visibility == 0 ? r_cullentities_trace_tempentitysamples.integer : r_cullentities_trace_samples.integer;
+ if (R_CanSeeBox(samples, r_cullentities_trace_eyejitter.value, r_cullentities_trace_enlarge.value, r_refdef.view.origin, ent->mins, ent->maxs))
ent->last_trace_visibility = realtime;
- if(ent->last_trace_visibility < realtime - r_cullentities_trace_delay.value)
+ if (ent->last_trace_visibility < realtime - r_cullentities_trace_delay.value)
r_refdef.viewcache.entityvisible[i] = 0;
}
}
r_fb.bloomindex = 0;
R_Mesh_SetRenderTargets(r_fb.bloomfbo[r_fb.bloomindex], NULL, r_fb.bloomtexture[r_fb.bloomindex], NULL, NULL, NULL);
R_SetViewport(&r_fb.bloomviewport);
+ GL_CullFace(GL_NONE);
GL_DepthTest(false);
GL_BlendFunc(GL_ONE, GL_ZERO);
GL_Color(colorscale, colorscale, colorscale, 1);
if (strcmp(r_qwskincache[i].name, cl.scores[i].qw_skin))
R_LoadQWSkin(&r_qwskincache[i], cl.scores[i].qw_skin);
t->currentskinframe = r_qwskincache[i].skinframe;
- if (t->currentskinframe == NULL)
- t->currentskinframe = t->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->skinframerate, t->numskinframes)];
+ if (t->materialshaderpass && t->currentskinframe == NULL)
+ t->currentskinframe = t->materialshaderpass->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->materialshaderpass->framerate, t->materialshaderpass->numframes)];
}
- else if (t->numskinframes >= 2)
- t->currentskinframe = t->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->skinframerate, t->numskinframes)];
- if (t->backgroundnumskinframes >= 2)
- t->backgroundcurrentskinframe = t->backgroundskinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->backgroundskinframerate, t->backgroundnumskinframes)];
+ else if (t->materialshaderpass && t->materialshaderpass->numframes >= 2)
+ t->currentskinframe = t->materialshaderpass->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->materialshaderpass->framerate, t->materialshaderpass->numframes)];
+ if (t->backgroundshaderpass && t->backgroundshaderpass->numframes >= 2)
+ t->backgroundcurrentskinframe = t->backgroundshaderpass->skinframes[LoopingFrameNumberFromDouble(rsurface.shadertime * t->backgroundshaderpass->framerate, t->backgroundshaderpass->numframes)];
t->currentmaterialflags = t->basematerialflags;
t->currentalpha = rsurface.colormod[3] * t->basealpha;
t->currentmaterialflags |= MATERIALFLAG_NOSHADOW | MATERIALFLAG_NOCULLFACE;
if (rsurface.ent_flags & (RENDER_NODEPTHTEST | RENDER_VIEWMODEL))
t->currentmaterialflags |= MATERIALFLAG_SHORTDEPTHRANGE;
- if (t->backgroundnumskinframes)
+ if (t->backgroundshaderpass)
t->currentmaterialflags |= MATERIALFLAG_VERTEXTEXTUREBLEND;
if (t->currentmaterialflags & MATERIALFLAG_BLENDED)
{
Matrix4x4_CreateIdentity(&t->currentbackgroundtexmatrix);
}
- for (i = 0, tcmod = t->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++)
- R_tcMod_ApplyToMatrix(&t->currenttexmatrix, tcmod, t->currentmaterialflags);
- for (i = 0, tcmod = t->backgroundtcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++)
- R_tcMod_ApplyToMatrix(&t->currentbackgroundtexmatrix, tcmod, t->currentmaterialflags);
+ if (t->materialshaderpass)
+ for (i = 0, tcmod = t->materialshaderpass->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++)
+ R_tcMod_ApplyToMatrix(&t->currenttexmatrix, tcmod, t->currentmaterialflags);
t->colormapping = VectorLength2(rsurface.colormap_pantscolor) + VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f);
if (t->currentskinframe->qpixels)
t->glowtexture = t->currentskinframe->glow;
t->fogtexture = t->currentskinframe->fog;
t->reflectmasktexture = t->currentskinframe->reflect;
- if (t->backgroundnumskinframes)
+ if (t->backgroundshaderpass)
{
+ for (i = 0, tcmod = t->backgroundshaderpass->tcmods; i < Q3MAXTCMODS && tcmod->tcmod; i++, tcmod++)
+ R_tcMod_ApplyToMatrix(&t->currentbackgroundtexmatrix, tcmod, t->currentmaterialflags);
t->backgroundbasetexture = (!t->colormapping && t->backgroundcurrentskinframe->merged) ? t->backgroundcurrentskinframe->merged : t->backgroundcurrentskinframe->base;
t->backgroundnmaptexture = t->backgroundcurrentskinframe->nmap;
t->backgroundglosstexture = r_texture_black;
break;
}
}
- switch(rsurface.texture->tcgen.tcgen)
+ if (rsurface.texture->materialshaderpass)
{
- default:
- case Q3TCGEN_TEXTURE:
- break;
- case Q3TCGEN_LIGHTMAP:
- if (!dynamicvertex)
+ switch (rsurface.texture->materialshaderpass->tcgen.tcgen)
{
- r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_lightmap] += 1;
- r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_lightmap] += batchnumsurfaces;
- r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_lightmap] += batchnumvertices;
- r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_lightmap] += batchnumtriangles;
- }
- dynamicvertex = true;
- batchneed |= BATCHNEED_ARRAY_LIGHTMAP;
- needsupdate |= BATCHNEED_VERTEXMESH_LIGHTMAP;
- break;
- case Q3TCGEN_VECTOR:
- if (!dynamicvertex)
- {
- r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_vector] += 1;
- r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_vector] += batchnumsurfaces;
- r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_vector] += batchnumvertices;
- r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_vector] += batchnumtriangles;
- }
- dynamicvertex = true;
- batchneed |= BATCHNEED_ARRAY_VERTEX;
- needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
- break;
- case Q3TCGEN_ENVIRONMENT:
- if (!dynamicvertex)
- {
- r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_environment] += 1;
- r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_environment] += batchnumsurfaces;
- r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_environment] += batchnumvertices;
- r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_environment] += batchnumtriangles;
+ default:
+ case Q3TCGEN_TEXTURE:
+ break;
+ case Q3TCGEN_LIGHTMAP:
+ if (!dynamicvertex)
+ {
+ r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_lightmap] += 1;
+ r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_lightmap] += batchnumsurfaces;
+ r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_lightmap] += batchnumvertices;
+ r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_lightmap] += batchnumtriangles;
+ }
+ dynamicvertex = true;
+ batchneed |= BATCHNEED_ARRAY_LIGHTMAP;
+ needsupdate |= BATCHNEED_VERTEXMESH_LIGHTMAP;
+ break;
+ case Q3TCGEN_VECTOR:
+ if (!dynamicvertex)
+ {
+ r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_vector] += 1;
+ r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_vector] += batchnumsurfaces;
+ r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_vector] += batchnumvertices;
+ r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_vector] += batchnumtriangles;
+ }
+ dynamicvertex = true;
+ batchneed |= BATCHNEED_ARRAY_VERTEX;
+ needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
+ break;
+ case Q3TCGEN_ENVIRONMENT:
+ if (!dynamicvertex)
+ {
+ r_refdef.stats[r_stat_batch_dynamic_batches_because_tcgen_environment] += 1;
+ r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcgen_environment] += batchnumsurfaces;
+ r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcgen_environment] += batchnumvertices;
+ r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcgen_environment] += batchnumtriangles;
+ }
+ dynamicvertex = true;
+ batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL;
+ needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
+ break;
}
- dynamicvertex = true;
- batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL;
- needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
- break;
- }
- if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
- {
- if (!dynamicvertex)
+ if (rsurface.texture->materialshaderpass->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
{
- r_refdef.stats[r_stat_batch_dynamic_batches_because_tcmod_turbulent] += 1;
- r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcmod_turbulent] += batchnumsurfaces;
- r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcmod_turbulent] += batchnumvertices;
- r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcmod_turbulent] += batchnumtriangles;
+ if (!dynamicvertex)
+ {
+ r_refdef.stats[r_stat_batch_dynamic_batches_because_tcmod_turbulent] += 1;
+ r_refdef.stats[r_stat_batch_dynamic_surfaces_because_tcmod_turbulent] += batchnumsurfaces;
+ r_refdef.stats[r_stat_batch_dynamic_vertices_because_tcmod_turbulent] += batchnumvertices;
+ r_refdef.stats[r_stat_batch_dynamic_triangles_because_tcmod_turbulent] += batchnumtriangles;
+ }
+ dynamicvertex = true;
+ batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD;
+ needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
}
- dynamicvertex = true;
- batchneed |= BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_TEXCOORD;
- needsupdate |= BATCHNEED_VERTEXMESH_TEXCOORD;
}
if (!rsurface.modelvertexmesh && (batchneed & (BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | BATCHNEED_VERTEXMESH_LIGHTMAP)))
}
}
- if (rsurface.batchtexcoordtexture2f)
+ if (rsurface.batchtexcoordtexture2f && rsurface.texture->materialshaderpass)
{
// generate texcoords based on the chosen texcoord source
- switch(rsurface.texture->tcgen.tcgen)
+ switch(rsurface.texture->materialshaderpass->tcgen.tcgen)
{
default:
case Q3TCGEN_TEXTURE:
// rsurface.batchtexcoordtexture2f_bufferoffset = 0;
for (j = 0;j < batchnumvertices;j++)
{
- rsurface.batchtexcoordtexture2f[j*2+0] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms);
- rsurface.batchtexcoordtexture2f[j*2+1] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms + 3);
+ rsurface.batchtexcoordtexture2f[j*2+0] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->materialshaderpass->tcgen.parms);
+ rsurface.batchtexcoordtexture2f[j*2+1] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->materialshaderpass->tcgen.parms + 3);
}
break;
case Q3TCGEN_ENVIRONMENT:
// and we only support that as the first one
// (handling a mixture of turbulent and other tcmods would be problematic
// without punting it entirely to a software path)
- if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
+ if (rsurface.texture->materialshaderpass->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
{
- amplitude = rsurface.texture->tcmods[0].parms[1];
- animpos = rsurface.texture->tcmods[0].parms[2] + rsurface.shadertime * rsurface.texture->tcmods[0].parms[3];
+ amplitude = rsurface.texture->materialshaderpass->tcmods[0].parms[1];
+ animpos = rsurface.texture->materialshaderpass->tcmods[0].parms[2] + rsurface.shadertime * rsurface.texture->materialshaderpass->tcmods[0].parms[3];
// rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
// rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
// rsurface.batchtexcoordtexture2f_bufferoffset = 0;