-#include "quakedef.h"
-#include "r_shadow.h"
-
-static texture_t r_aliasnotexture;
-static texture_t *R_FetchAliasSkin(const entity_render_t *ent, const surfmesh_t *mesh)
-{
- model_t *model = ent->model;
- if (model->numskins)
- {
- int s = ent->skinnum;
- if ((unsigned int)s >= (unsigned int)model->numskins)
- s = 0;
- if (model->skinscenes[s].framecount > 1)
- s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
- else
- s = model->skinscenes[s].firstframe;
- if (s >= mesh->num_skins)
- s = 0;
- return mesh->data_skins + s;
- }
- else
- {
- memset(&r_aliasnotexture, 0, sizeof(r_aliasnotexture));
- r_aliasnotexture.skin.base = r_texture_notexture;
- return &r_aliasnotexture;
- }
-}
-
-static void R_DrawAliasModelCallback (const void *calldata1, int calldata2)
-{
- int c, fbbase, fbpants, fbshirt, doglow;
- float tint[3], fog, ifog, colorscale, ambientcolor4f[4], diffusecolor[3], diffusenormal[3], colorbase[3], colorpants[3], colorshirt[3];
- float *vertex3f, *normal3f;
- vec3_t diff;
- qbyte *bcolor;
- rmeshstate_t m;
- const entity_render_t *ent = calldata1;
- msurface_t *surface = ent->model->data_surfaces + calldata2;
- surfmesh_t *mesh = surface->groupmesh;
- texture_t *texture;
-
- R_Mesh_Matrix(&ent->matrix);
-
- fog = 0;
- if (fogenabled)
- {
- VectorSubtract(ent->origin, r_vieworigin, diff);
- fog = DotProduct(diff,diff);
- if (fog < 0.01f)
- fog = 0.01f;
- fog = exp(fogdensity/fog);
- if (fog > 1)
- fog = 1;
- if (fog < 0.01f)
- fog = 0;
- // fog method: darken, additive fog
- // 1. render model as normal, scaled by inverse of fog alpha (darkens it)
- // 2. render fog as additive
- }
- ifog = 1 - fog;
-
- VectorScale(ent->colormod, ifog, colorbase);
- VectorClear(colorpants);
- VectorClear(colorshirt);
- fbbase = ent->effects & EF_FULLBRIGHT;
- fbpants = fbbase;
- fbshirt = fbbase;
- if (ent->colormap >= 0)
- {
- // 128-224 are backwards ranges
- c = (ent->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12;
- if (c >= 224)
- fbpants = true;
- bcolor = (qbyte *) (&palette_complete[c]);
- colorpants[0] = colorbase[0] * bcolor[0] * (1.0f / 255.0f);
- colorpants[1] = colorbase[1] * bcolor[1] * (1.0f / 255.0f);
- colorpants[2] = colorbase[2] * bcolor[2] * (1.0f / 255.0f);
- // 128-224 are backwards ranges
- c = (ent->colormap & 0xF0);c += (c >= 128 && c < 224) ? 4 : 12;
- if (c >= 224)
- fbshirt = true;
- bcolor = (qbyte *) (&palette_complete[c]);
- colorshirt[0] = colorbase[0] * bcolor[0] * (1.0f / 255.0f);
- colorshirt[1] = colorbase[1] * bcolor[1] * (1.0f / 255.0f);
- colorshirt[2] = colorbase[2] * bcolor[2] * (1.0f / 255.0f);
- }
-
- texture = R_FetchAliasSkin(ent, mesh);
-
- if ((ent->effects & EF_ADDITIVE))
- {
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- GL_DepthMask(false);
- }
- else if (texture->skin.fog || ent->alpha != 1.0)
- {
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- GL_DepthMask(false);
- }
- else
- {
- GL_BlendFunc(GL_ONE, GL_ZERO);
- GL_DepthMask(true);
- }
- GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
- colorscale = 1.0f;
- if (ent->frameblend[0].frame == 0 && ent->frameblend[0].lerp == 1)
- {
- vertex3f = mesh->data_vertex3f;
- normal3f = mesh->data_normal3f;
- }
- else
- {
- vertex3f = varray_vertex3f;
- Mod_Alias_GetMesh_Vertex3f(ent->model, ent->frameblend, mesh, vertex3f);
- normal3f = NULL;
- }
-
- doglow = texture->skin.glow != NULL;
-
- memset(&m, 0, sizeof(m));
- m.pointer_vertex = vertex3f;
- m.pointer_texcoord[0] = mesh->data_texcoordtexture2f;
- if (gl_combine.integer)
- {
- colorscale *= 0.25f;
- m.texrgbscale[0] = 4;
- }
-
- m.tex[0] = R_GetTexture((ent->colormap >= 0 || !texture->skin.merged) ? texture->skin.base : texture->skin.merged);
- VectorScale(colorbase, colorscale, tint);
- m.pointer_color = NULL;
- if (fbbase)
- GL_Color(tint[0], tint[1], tint[2], ent->alpha);
- else if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, tint[0], tint[1], tint[2], ent->alpha, false))
- {
- m.pointer_color = varray_color4f;
- if (normal3f == NULL)
- {
- normal3f = varray_normal3f;
- Mod_BuildNormals(0, mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_element3i, normal3f);
- }
- R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, mesh->num_vertices, vertex3f, normal3f, varray_color4f);
- }
- else
- GL_Color(ambientcolor4f[0], ambientcolor4f[1], ambientcolor4f[2], ambientcolor4f[3]);
- if (gl_combine.integer && doglow)
- {
- doglow = false;
- m.tex[1] = R_GetTexture(texture->skin.glow);
- m.pointer_texcoord[1] = mesh->data_texcoordtexture2f;
- m.texcombinergb[1] = GL_ADD;
- }
- R_Mesh_State(&m);
- c_alias_polys += mesh->num_triangles;
- GL_LockArrays(0, mesh->num_vertices);
- R_Mesh_Draw(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i);
- GL_LockArrays(0, 0);
- m.tex[1] = 0;
- m.pointer_texcoord[1] = NULL;
- m.texcombinergb[1] = 0;
-
- VectorScale(colorpants, colorscale, tint);
- if (ent->colormap >= 0 && texture->skin.pants && VectorLength2(tint) >= 0.001)
- {
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- GL_DepthMask(false);
- m.tex[0] = R_GetTexture(texture->skin.pants);
- m.pointer_color = NULL;
- if (fbpants)
- GL_Color(tint[0], tint[1], tint[2], ent->alpha);
- else if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, tint[0], tint[1], tint[2], ent->alpha, false))
- {
- m.pointer_color = varray_color4f;
- if (normal3f == NULL)
- {
- normal3f = varray_normal3f;
- Mod_BuildNormals(0, mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_element3i, normal3f);
- }
- R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, mesh->num_vertices, vertex3f, normal3f, varray_color4f);
- }
- else
- GL_Color(ambientcolor4f[0], ambientcolor4f[1], ambientcolor4f[2], ambientcolor4f[3]);
- R_Mesh_State(&m);
- c_alias_polys += mesh->num_triangles;
- GL_LockArrays(0, mesh->num_vertices);
- R_Mesh_Draw(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i);
- GL_LockArrays(0, 0);
- }
-
- VectorScale(colorshirt, colorscale, tint);
- if (ent->colormap >= 0 && texture->skin.shirt && VectorLength2(tint) >= 0.001)
- {
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- GL_DepthMask(false);
- m.tex[0] = R_GetTexture(texture->skin.shirt);
- m.pointer_color = NULL;
- if (fbshirt)
- GL_Color(tint[0], tint[1], tint[2], ent->alpha);
- else if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, tint[0], tint[1], tint[2], ent->alpha, false))
- {
- m.pointer_color = varray_color4f;
- if (normal3f == NULL)
- {
- normal3f = varray_normal3f;
- Mod_BuildNormals(0, mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_element3i, normal3f);
- }
- R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, mesh->num_vertices, vertex3f, normal3f, varray_color4f);
- }
- else
- GL_Color(ambientcolor4f[0], ambientcolor4f[1], ambientcolor4f[2], ambientcolor4f[3]);
- R_Mesh_State(&m);
- c_alias_polys += mesh->num_triangles;
- GL_LockArrays(0, mesh->num_vertices);
- R_Mesh_Draw(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i);
- GL_LockArrays(0, 0);
- }
-
- colorscale = 1;
- m.texrgbscale[0] = 0;
- m.pointer_color = NULL;
-
- if (doglow)
- {
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- GL_DepthMask(false);
- m.tex[0] = R_GetTexture(texture->skin.glow);
- GL_Color(1, 1, 1, ent->alpha);
- R_Mesh_State(&m);
- c_alias_polys += mesh->num_triangles;
- GL_LockArrays(0, mesh->num_vertices);
- R_Mesh_Draw(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i);
- GL_LockArrays(0, 0);
- }
-
- if (fog > 0)
- {
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- GL_DepthMask(false);
- m.tex[0] = R_GetTexture(texture->skin.fog);
- GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], fog * ent->alpha);
- R_Mesh_State(&m);
- c_alias_polys += mesh->num_triangles;
- GL_LockArrays(0, mesh->num_vertices);
- R_Mesh_Draw(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i);
- GL_LockArrays(0, 0);
- }
-}
-
-void R_Model_Alias_Draw(entity_render_t *ent)
-{
- int surfacenum;
- msurface_t *surface;
- surfmesh_t *mesh;
- if (ent->alpha < (1.0f / 64.0f))
- return; // basically completely transparent
-
- c_models++;
-
- for (surfacenum = 0, surface = ent->model->data_surfaces;surfacenum < ent->model->num_surfaces;surfacenum++, surface++)
- {
- mesh = surface->groupmesh;
- if (ent->effects & EF_ADDITIVE || ent->alpha != 1.0 || R_FetchAliasSkin(ent, mesh)->skin.fog)
- R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : ent->origin, R_DrawAliasModelCallback, ent, surfacenum);
- else
- R_DrawAliasModelCallback(ent, surfacenum);
- }
-}
-
-void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist, const vec3_t lightmins, const vec3_t lightmaxs)
-{
- int surfacenum;
- msurface_t *surface;
- surfmesh_t *mesh;
- texture_t *texture;
- float projectdistance, *vertex3f;
- if (!(ent->flags & RENDER_SHADOW))
- return;
- // check the box in modelspace, it was already checked in worldspace
- if (!BoxesOverlap(ent->model->normalmins, ent->model->normalmaxs, lightmins, lightmaxs))
- return;
- projectdistance = lightradius + ent->model->radius;// - sqrt(DotProduct(relativelightorigin, relativelightorigin));
- if (projectdistance > 0.1)
- {
- for (surfacenum = 0, surface = ent->model->data_surfaces;surfacenum < ent->model->num_surfaces;surfacenum++, surface++)
- {
- mesh = surface->groupmesh;
- texture = R_FetchAliasSkin(ent, mesh);
- if (texture->skin.fog)
- continue;
- if (ent->frameblend[0].frame == 0 && ent->frameblend[0].lerp == 1)
- vertex3f = mesh->data_vertex3f;
- else
- {
- vertex3f = varray_vertex3f;
- Mod_Alias_GetMesh_Vertex3f(ent->model, ent->frameblend, mesh, vertex3f);
- }
- // identify lit faces within the bounding box
- R_Shadow_PrepareShadowMark(mesh->num_triangles);
- R_Shadow_MarkVolumeFromBox(0, mesh->num_triangles, vertex3f, mesh->data_element3i, relativelightorigin, lightmins, lightmaxs, ent->model->normalmins, ent->model->normalmaxs);
- R_Shadow_VolumeFromList(mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_element3i, mesh->data_neighbor3i, relativelightorigin, projectdistance, numshadowmark, shadowmarklist);
- }
- }
-}
-
-void R_Model_Alias_DrawLight(entity_render_t *ent, float *lightcolor, int numsurfaces, const int *surfacelist)
-{
- int c;
- float fog, ifog, lightcolorbase[3], lightcolorpants[3], lightcolorshirt[3];
- float *vertex3f, *svector3f, *tvector3f, *normal3f;
- vec3_t diff;
- qbyte *bcolor;
- int surfacenum;
- msurface_t *surface;
- surfmesh_t *mesh;
- texture_t *texture;
-
- fog = 0;
- if (fogenabled)
- {
- VectorSubtract(ent->origin, r_vieworigin, diff);
- fog = DotProduct(diff,diff);
- if (fog < 0.01f)
- fog = 0.01f;
- fog = exp(fogdensity/fog);
- if (fog > 1)
- fog = 1;
- if (fog < 0.01f)
- fog = 0;
- // fog method: darken, additive fog
- // 1. render model as normal, scaled by inverse of fog alpha (darkens it)
- // 2. render fog as additive
- }
- ifog = 1 - fog;
-
- VectorScale(lightcolor, ifog, lightcolorbase);
- if (VectorLength2(lightcolorbase) < 0.001)
- return;
- VectorClear(lightcolorpants);
- VectorClear(lightcolorshirt);
- if (ent->colormap >= 0)
- {
- // 128-224 are backwards ranges
- c = (ent->colormap & 0xF) << 4;c += (c >= 128 && c < 224) ? 4 : 12;
- // fullbright passes were already taken care of, so skip them in realtime lighting passes
- if (c < 224)
- {
- bcolor = (qbyte *) (&palette_complete[c]);
- 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);
- }
- // 128-224 are backwards ranges
- c = (ent->colormap & 0xF0);c += (c >= 128 && c < 224) ? 4 : 12;
- // fullbright passes were already taken care of, so skip them in realtime lighting passes
- if (c < 224)
- {
- bcolor = (qbyte *) (&palette_complete[c]);
- 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);
- }
- }
-
- for (surfacenum = 0, surface = ent->model->data_surfaces;surfacenum < ent->model->num_surfaces;surfacenum++, surface++)
- {
- mesh = surface->groupmesh;
- texture = R_FetchAliasSkin(ent, mesh);
- // FIXME: transparent skins need to be lit during the transparent render
- if (texture->skin.fog)
- continue;
- if (ent->frameblend[0].frame == 0 && ent->frameblend[0].lerp == 1)
- {
- vertex3f = mesh->data_vertex3f;
- svector3f = mesh->data_svector3f;
- tvector3f = mesh->data_tvector3f;
- normal3f = mesh->data_normal3f;
- }
- else
- {
- vertex3f = varray_vertex3f;
- svector3f = varray_svector3f;
- tvector3f = varray_tvector3f;
- normal3f = varray_normal3f;
- Mod_Alias_GetMesh_Vertex3f(ent->model, ent->frameblend, mesh, vertex3f);
- Mod_BuildTextureVectorsAndNormals(0, mesh->num_vertices, mesh->num_triangles, vertex3f, mesh->data_texcoordtexture2f, mesh->data_element3i, svector3f, tvector3f, normal3f);
- }
- c_alias_polys += mesh->num_triangles;
- R_Shadow_RenderLighting(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, vertex3f, svector3f, tvector3f, normal3f, mesh->data_texcoordtexture2f, lightcolorbase, lightcolorpants, lightcolorshirt, (ent->colormap >= 0 || !texture->skin.merged) ? texture->skin.base : texture->skin.merged, ent->colormap >= 0 ? texture->skin.pants : 0, ent->colormap >= 0 ? texture->skin.shirt : 0, texture->skin.nmap, texture->skin.gloss);
- }
-}
-
void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
{
- // we don't need to set currentframe if t->animated is false because
- // it was already set up by the texture loader for non-animating
- if (t->animated)
+ model_t *model = ent->model;
+ int s = ent->skinnum;
+ if ((unsigned int)s >= (unsigned int)model->numskins)
+ s = 0;
+ if (s >= 1)
+ c_models++;
+ if (model->skinscenes)
{
- t->currentframe = t->anim_frames[ent->frame != 0][(t->anim_total[ent->frame != 0] >= 2) ? ((int)(r_refdef.time * 5.0f) % t->anim_total[ent->frame != 0]) : 0];
- t = t->currentframe;
+ if (model->skinscenes[s].framecount > 1)
+ s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
+ else
+ s = model->skinscenes[s].firstframe;
}
+ if (s > 0)
+ t = t->currentframe = t + s * model->num_surfaces;
+ if (t->animated)
+ t = t->currentframe = t->anim_frames[ent->frame != 0][(t->anim_total[ent->frame != 0] >= 2) ? ((int)(r_refdef.time * 5.0f) % t->anim_total[ent->frame != 0]) : 0];
t->currentmaterialflags = t->basematerialflags;
t->currentalpha = ent->alpha;
if (t->basematerialflags & MATERIALFLAG_WATERALPHA)
R_UpdateTextureInfo(ent, ent->model->data_textures + i);
}
-static void RSurf_DeformVertices(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg)
+float *rsurface_vertex3f;
+float *rsurface_svector3f;
+float *rsurface_tvector3f;
+float *rsurface_normal3f;
+float *rsurface_lightmapcolor4f;
+
+void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg)
{
int i, j;
float center[3], forward[3], right[3], up[3], v[4][3];
matrix4x4_t matrix1, imatrix1;
+ if ((ent->frameblend[0].lerp != 1 || ent->frameblend[0].frame != 0) && (surface->groupmesh->data_morphvertex3f || surface->groupmesh->data_vertexboneweights))
+ {
+ rsurface_vertex3f = varray_vertex3f;
+ rsurface_svector3f = NULL;
+ rsurface_tvector3f = NULL;
+ rsurface_normal3f = NULL;
+ Mod_Alias_GetMesh_Vertex3f(ent->model, ent->frameblend, surface->groupmesh, rsurface_vertex3f);
+ }
+ else
+ {
+ rsurface_vertex3f = surface->groupmesh->data_vertex3f;
+ rsurface_svector3f = surface->groupmesh->data_svector3f;
+ rsurface_tvector3f = surface->groupmesh->data_tvector3f;
+ rsurface_normal3f = surface->groupmesh->data_normal3f;
+ }
if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2)
{
+ if (!rsurface_svector3f)
+ {
+ 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);
+ }
// a single autosprite surface can contain multiple sprites...
VectorClear(forward);
VectorClear(right);
{
VectorClear(center);
for (i = 0;i < 4;i++)
- VectorAdd(center, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
+ VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
VectorScale(center, 0.25f, center);
// FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
- Matrix4x4_FromVectors(&matrix1, (surface->groupmesh->data_normal3f + 3 * surface->num_firstvertex) + j*3, (surface->groupmesh->data_svector3f + 3 * surface->num_firstvertex) + j*3, (surface->groupmesh->data_tvector3f + 3 * surface->num_firstvertex) + j*3, center);
+ Matrix4x4_FromVectors(&matrix1, (rsurface_normal3f + 3 * surface->num_firstvertex) + j*3, (rsurface_svector3f + 3 * surface->num_firstvertex) + j*3, (rsurface_tvector3f + 3 * surface->num_firstvertex) + j*3, center);
Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
for (i = 0;i < 4;i++)
- Matrix4x4_Transform(&imatrix1, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
+ Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
forward[0] = modelorg[0] - center[0];
forward[1] = modelorg[1] - center[1];
VectorNormalize(forward);
for (i = 0;i < 4;i++)
VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, varray_vertex3f + (surface->num_firstvertex+i+j) * 3);
}
+ rsurface_vertex3f = varray_vertex3f;
+ rsurface_svector3f = NULL;
+ rsurface_tvector3f = NULL;
+ rsurface_normal3f = NULL;
}
else if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE)
{
+ if (!rsurface_svector3f)
+ {
+ 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);
+ }
Matrix4x4_Transform(&ent->inversematrix, r_viewforward, forward);
Matrix4x4_Transform(&ent->inversematrix, r_viewright, right);
Matrix4x4_Transform(&ent->inversematrix, r_viewup, up);
{
VectorClear(center);
for (i = 0;i < 4;i++)
- VectorAdd(center, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
+ VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center);
VectorScale(center, 0.25f, center);
// FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out?
- Matrix4x4_FromVectors(&matrix1, (surface->groupmesh->data_normal3f + 3 * surface->num_firstvertex) + j*3, (surface->groupmesh->data_svector3f + 3 * surface->num_firstvertex) + j*3, (surface->groupmesh->data_tvector3f + 3 * surface->num_firstvertex) + j*3, center);
+ Matrix4x4_FromVectors(&matrix1, (rsurface_normal3f + 3 * surface->num_firstvertex) + j*3, (rsurface_svector3f + 3 * surface->num_firstvertex) + j*3, (rsurface_tvector3f + 3 * surface->num_firstvertex) + j*3, center);
Matrix4x4_Invert_Simple(&imatrix1, &matrix1);
for (i = 0;i < 4;i++)
- Matrix4x4_Transform(&imatrix1, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
+ Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]);
for (i = 0;i < 4;i++)
VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, varray_vertex3f + (surface->num_firstvertex+i+j) * 3);
}
+ rsurface_vertex3f = varray_vertex3f;
+ rsurface_svector3f = NULL;
+ rsurface_tvector3f = NULL;
+ rsurface_normal3f = NULL;
}
- else
- memcpy((varray_vertex3f + 3 * surface->num_firstvertex), (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex), sizeof(float[3]) * surface->num_vertices);
+ R_Mesh_VertexPointer(rsurface_vertex3f);
}
-// any sort of deformvertices call is *VERY* rare, so this must be optimized
-// to skip deformvertices quickly!
-#if 1
-#define RSurf_GetVertexPointer(ent, texture, surface, modelorg) ((texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) ? (RSurf_DeformVertices(ent, texture, surface, modelorg), varray_vertex3f) : surface->groupmesh->data_vertex3f)
-#else
-static float *RSurf_GetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg)
+void RSurf_SetColorPointer(const entity_render_t *ent, const msurface_t *surface, const vec3_t modelorg, float r, float g, float b, float a, qboolean lightmodel, qboolean vertexlight, qboolean applycolor, qboolean applyfog)
{
- if (texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
+ int i;
+ float f;
+ float *v, *c, *c2;
+ vec3_t diff;
+ if (lightmodel)
{
- RSurf_DeformVertices(ent, texture, surface, modelorg);
- return varray_vertex3f;
+ vec4_t ambientcolor4f;
+ vec3_t diffusecolor;
+ vec3_t diffusenormal;
+ if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, r, g, b, a, false))
+ {
+ rsurface_lightmapcolor4f = varray_color4f;
+ if (rsurface_normal3f == NULL)
+ {
+ rsurface_normal3f = varray_normal3f;
+ Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle, rsurface_normal3f);
+ }
+ R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, surface->groupmesh->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, rsurface_lightmapcolor4f + 4 * surface->num_firstvertex);
+ r = 1;
+ g = 1;
+ b = 1;
+ a = 1;
+ applycolor = false;
+ }
+ else
+ {
+ r = ambientcolor4f[0];
+ g = ambientcolor4f[1];
+ b = ambientcolor4f[2];
+ a = ambientcolor4f[3];
+ rsurface_lightmapcolor4f = NULL;
+ }
+ }
+ else if (vertexlight)
+ {
+ if (surface->lightmapinfo)
+ {
+ rsurface_lightmapcolor4f = varray_color4f;
+ for (i = 0, c = rsurface_lightmapcolor4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4)
+ {
+ const qbyte *lm = surface->lightmapinfo->samples + (surface->groupmesh->data_lightmapoffsets + surface->num_firstvertex)[i];
+ float scale = d_lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f);
+ VectorScale(lm, scale, c);
+ if (surface->lightmapinfo->styles[1] != 255)
+ {
+ int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
+ lm += size3;
+ scale = d_lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f);
+ VectorMA(c, scale, lm, c);
+ if (surface->lightmapinfo->styles[2] != 255)
+ {
+ lm += size3;
+ scale = d_lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f);
+ VectorMA(c, scale, lm, c);
+ if (surface->lightmapinfo->styles[3] != 255)
+ {
+ lm += size3;
+ scale = d_lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f);
+ VectorMA(c, scale, lm, c);
+ }
+ }
+ }
+ }
+ }
+ else
+ rsurface_lightmapcolor4f = surface->groupmesh->data_lightmapcolor4f;
}
else
- return surface->groupmesh->data_vertex3f;
+ rsurface_lightmapcolor4f = NULL;
+ if (applyfog)
+ {
+ if (rsurface_lightmapcolor4f)
+ {
+ for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (rsurface_lightmapcolor4f + 4 * surface->num_firstvertex), c2 = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4, c2 += 4)
+ {
+ VectorSubtract(v, modelorg, diff);
+ f = 1 - exp(fogdensity/DotProduct(diff, diff));
+ c2[0] = c[0] * f;
+ c2[1] = c[1] * f;
+ c2[2] = c[2] * f;
+ c2[3] = c[3];
+ }
+ }
+ else
+ {
+ for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c2 = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c2 += 4)
+ {
+ VectorSubtract(v, modelorg, diff);
+ f = 1 - exp(fogdensity/DotProduct(diff, diff));
+ c2[0] = f;
+ c2[1] = f;
+ c2[2] = f;
+ c2[3] = 1;
+ }
+ }
+ rsurface_lightmapcolor4f = varray_color4f;
+ }
+ if (applycolor && rsurface_lightmapcolor4f)
+ {
+ for (i = 0, c = (rsurface_lightmapcolor4f + 4 * surface->num_firstvertex), c2 = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, c += 4, c2 += 4)
+ {
+ c2[0] = c[0] * r;
+ c2[1] = c[1] * g;
+ c2[2] = c[2] * b;
+ c2[3] = c[3] * a;
+ }
+ }
+ R_Mesh_ColorPointer(rsurface_lightmapcolor4f);
+ GL_Color(r, g, b, a);
}
-#endif
+
static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg)
{
int i;
int texturesurfaceindex;
- const float *v, *vertex3f;
+ const float *v;
float *c;
float diff[3];
+ float colorpants[3], colorshirt[3];
float f, r, g, b, a, base, colorscale;
const msurface_t *surface;
qboolean dolightmap;
- qboolean dobase;
qboolean doambient;
qboolean dodetail;
qboolean doglow;
qboolean dofogpass;
qboolean fogallpasses;
qboolean waterscrolling;
- surfmesh_t *groupmesh;
- rtexture_t *lightmaptexture;
+ qboolean dopants;
+ qboolean doshirt;
+ qboolean dofullbrightpants;
+ qboolean dofullbrightshirt;
+ qboolean applycolor;
+ qboolean lightmodel = false;
+ rtexture_t *basetexture;
rmeshstate_t m;
texture = texture->currentframe;
if (texture->currentmaterialflags & MATERIALFLAG_NODRAW)
return;
c_faces += texturenumsurfaces;
+ // FIXME: identify models using a better check than ent->model->shadowmesh
+ if (!(ent->effects & EF_FULLBRIGHT) && !ent->model->brush.shadowmesh)
+ lightmodel = true;
// gl_lightmaps debugging mode skips normal texturing
if (gl_lightmaps.integer)
{
surface = texturesurfacelist[texturesurfaceindex];
R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
- R_Mesh_ColorPointer(surface->lightmaptexture ? NULL : surface->groupmesh->data_lightmapcolor4f);
- R_Mesh_VertexPointer(surface->groupmesh->data_vertex3f);
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
+ RSurf_SetColorPointer(ent, surface, modelorg, 1, 1, 1, 1, lightmodel, !surface->lightmaptexture, false, false);
GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
GL_LockArrays(0, 0);
for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
{
surface = texturesurfacelist[texturesurfaceindex];
- R_Mesh_VertexPointer(surface->groupmesh->data_vertex3f);
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
GL_LockArrays(0, 0);
for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
{
surface = texturesurfacelist[texturesurfaceindex];
- R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg));
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f);
GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
else if (texture->currentmaterialflags & (MATERIALFLAG_WATER | MATERIALFLAG_WALL))
{
// normal surface (wall or water)
- dobase = true;
dolightmap = !(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT);
doambient = r_ambient.value >= (1/64.0f);
dodetail = r_detailtextures.integer && texture->skin.detail != NULL && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT);
doglow = texture->skin.glow != NULL;
dofogpass = fogenabled && !(texture->currentmaterialflags & MATERIALFLAG_ADD);
fogallpasses = fogenabled && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT);
- if (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)
+ if (ent->colormap >= 0)
+ {
+ int b;
+ qbyte *bcolor;
+ basetexture = texture->skin.base;
+ dopants = texture->skin.pants != NULL;
+ doshirt = texture->skin.shirt != NULL;
+ // 128-224 are backwards ranges
+ b = (ent->colormap & 0xF) << 4;b += (b >= 128 && b < 224) ? 4 : 12;
+ dofullbrightpants = b >= 224;
+ bcolor = (qbyte *) (&palette_complete[b]);
+ VectorScale(bcolor, (1.0f / 255.0f), colorpants);
+ // 128-224 are backwards ranges
+ b = (ent->colormap & 0xF0);b += (b >= 128 && b < 224) ? 4 : 12;
+ dofullbrightshirt = b >= 224;
+ bcolor = (qbyte *) (&palette_complete[b]);
+ VectorScale(bcolor, (1.0f / 255.0f), colorshirt);
+ }
+ else
{
- if (dobase && dolightmap && gl_combine.integer)
+ basetexture = texture->skin.merged ? texture->skin.merged : texture->skin.base;
+ dopants = false;
+ doshirt = false;
+ //dofullbrightshirt = false;
+ //dofullbrightpants = false;
+ }
+ if (dolightmap && gl_combine.integer)
+ {
+ memset(&m, 0, sizeof(m));
+ m.tex[1] = R_GetTexture(basetexture);
+ if (waterscrolling)
+ m.texmatrix[1] = r_waterscrollmatrix;
+ m.texrgbscale[1] = 2;
+ m.pointer_color = varray_color4f;
+ R_Mesh_State(&m);
+ colorscale = 1;
+ r = ent->colormod[0] * colorscale;
+ g = ent->colormod[1] * colorscale;
+ b = ent->colormod[2] * colorscale;
+ a = texture->currentalpha;
+ base = r_ambient.value * (1.0f / 64.0f);
+ // q3bsp has no lightmap updates, so the lightstylevalue that
+ // would normally be baked into the lightmaptexture must be
+ // applied to the color
+ if (ent->model->brushq3.data_lightmaps)
+ {
+ float scale = d_lightstylevalue[0] * (1.0f / 128.0f);
+ r *= scale;
+ g *= scale;
+ b *= scale;
+ }
+ applycolor = r != 1 || g != 1 || b != 1 || a != 1;
+ for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+ {
+ surface = texturesurfacelist[texturesurfaceindex];
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
+ R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
+ R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f);
+ if (surface->lightmaptexture)
+ R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
+ else
+ R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+ RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmodel, !surface->lightmaptexture, applycolor, fogallpasses);
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
+ GL_LockArrays(0, 0);
+ }
+ }
+ else if (dolightmap && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
+ {
+ // single texture
+ GL_BlendFunc(GL_ONE, GL_ZERO);
+ GL_DepthMask(true);
+ GL_Color(1, 1, 1, 1);
+ memset(&m, 0, sizeof(m));
+ R_Mesh_State(&m);
+ for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+ {
+ surface = texturesurfacelist[texturesurfaceindex];
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
+ R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
+ if (surface->lightmaptexture)
+ {
+ R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
+ R_Mesh_ColorPointer(NULL);
+ }
+ else //if (r == 1 && g == 1 && b == 1)
+ {
+ R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
+ R_Mesh_ColorPointer(surface->groupmesh->data_lightmapcolor4f);
+ }
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
+ GL_LockArrays(0, 0);
+ }
+ GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
+ GL_DepthMask(false);
+ GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(basetexture);
+ if (waterscrolling)
+ m.texmatrix[0] = r_waterscrollmatrix;
+ R_Mesh_State(&m);
+ for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
+ {
+ surface = texturesurfacelist[texturesurfaceindex];
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
+ R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
+ GL_LockArrays(0, 0);
+ }
+ }
+ else
+ {
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(basetexture);
+ if (waterscrolling)
+ m.texmatrix[0] = r_waterscrollmatrix;
+ m.pointer_color = varray_color4f;
+ colorscale = 1;
+ if (gl_combine.integer)
+ {
+ m.texrgbscale[0] = 4;
+ colorscale *= 0.25f;
+ }
+ R_Mesh_State(&m);
+ r = ent->colormod[0] * colorscale;
+ g = ent->colormod[1] * colorscale;
+ b = ent->colormod[2] * colorscale;
+ a = texture->currentalpha;
+ if (dolightmap)
{
- dobase = false;
- memset(&m, 0, sizeof(m));
- m.tex[1] = R_GetTexture(texture->skin.base);
- if (waterscrolling)
- m.texmatrix[1] = r_waterscrollmatrix;
- m.texrgbscale[1] = 2;
- m.pointer_color = varray_color4f;
- R_Mesh_State(&m);
- colorscale = 1;
- r = ent->colormod[0] * colorscale;
- g = ent->colormod[1] * colorscale;
- b = ent->colormod[2] * colorscale;
- a = texture->currentalpha;
- base = r_ambient.value * (1.0f / 64.0f);
// q3bsp has no lightmap updates, so the lightstylevalue that
// would normally be baked into the lightmaptexture must be
// applied to the color
- if (ent->model->brushq1.lightdata)
+ if (ent->model->brushq3.data_lightmaps)
{
float scale = d_lightstylevalue[0] * (1.0f / 128.0f);
r *= scale;
g *= scale;
b *= scale;
}
+ applycolor = r != 1 || g != 1 || b != 1 || a != 1;
for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
{
surface = texturesurfacelist[texturesurfaceindex];
- vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
- R_Mesh_VertexPointer(vertex3f);
- R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
- R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f);
- if (surface->lightmaptexture)
- {
- R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
- if (fogallpasses)
- {
- R_Mesh_ColorPointer(varray_color4f);
- for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
- {
- VectorSubtract(v, modelorg, diff);
- f = 1 - exp(fogdensity/DotProduct(diff, diff));
- c[0] = f * r;
- c[1] = f * g;
- c[2] = f * b;
- c[3] = a;
- }
- }
- else
- {
- R_Mesh_ColorPointer(NULL);
- GL_Color(r, g, b, a);
- }
- }
- else
- {
- R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
- R_Mesh_ColorPointer(varray_color4f);
- if (!surface->lightmaptexture)
- {
- for (i = 0, c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, c += 4)
- {
- c[0] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+0] * r;
- c[1] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+1] * g;
- c[2] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+2] * b;
- c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a;
- }
- if (fogallpasses)
- {
- for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
- {
- VectorSubtract(v, modelorg, diff);
- f = 1 - exp(fogdensity/DotProduct(diff, diff));
- VectorScale(c, f, c);
- }
- }
- }
- else
- {
- R_Mesh_ColorPointer(NULL);
- GL_Color(0, 0, 0, a);
- }
- }
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
+ R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
+ RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmodel, true, applycolor, fogallpasses);
GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
GL_LockArrays(0, 0);
}
}
- if (dobase)
+ else
{
- dobase = false;
- memset(&m, 0, sizeof(m));
- m.tex[0] = R_GetTexture(texture->skin.base);
- if (waterscrolling)
- m.texmatrix[0] = r_waterscrollmatrix;
- m.pointer_color = varray_color4f;
- colorscale = 1;
- if (gl_combine.integer)
- {
- m.texrgbscale[0] = 4;
- colorscale *= 0.25f;
- }
- R_Mesh_State(&m);
- r = ent->colormod[0] * colorscale;
- g = ent->colormod[1] * colorscale;
- b = ent->colormod[2] * colorscale;
- a = texture->currentalpha;
- if (dolightmap)
- {
- // q3bsp has no lightmap updates, so the lightstylevalue that
- // would normally be baked into the lightmaptexture must be
- // applied to the color
- if (!ent->model->brushq1.lightdata)
- {
- float scale = d_lightstylevalue[0] * (1.0f / 128.0f);
- r *= scale;
- g *= scale;
- b *= scale;
- }
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
- R_Mesh_VertexPointer(vertex3f);
- R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
- for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
- {
- c[0] = 0;
- c[1] = 0;
- c[2] = 0;
- if (!surface->lightmapinfo)
- VectorCopy((surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex) + i*4, c);
- else //if (surface->lightmapinfo)
- {
- const qbyte *lm = surface->lightmapinfo->samples + (surface->groupmesh->data_lightmapoffsets + surface->num_firstvertex)[i];
- float scale = d_lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f);
- VectorMA(c, scale, lm, c);
- if (surface->lightmapinfo->styles[1] != 255)
- {
- int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3;
- lm += size3;
- scale = d_lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f);
- VectorMA(c, scale, lm, c);
- if (surface->lightmapinfo->styles[2] != 255)
- {
- lm += size3;
- scale = d_lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f);
- VectorMA(c, scale, lm, c);
- if (surface->lightmapinfo->styles[3] != 255)
- {
- lm += size3;
- scale = d_lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f);
- VectorMA(c, scale, lm, c);
- }
- }
- }
- }
- c[0] *= r;
- c[1] *= g;
- c[2] *= b;
- if (fogallpasses)
- {
- VectorSubtract(v, modelorg, diff);
- f = 1 - exp(fogdensity/DotProduct(diff, diff));
- VectorScale(c, f, c);
- }
- if (!surface->lightmapinfo && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
- c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a;
- else
- c[3] = a;
- }
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- GL_LockArrays(0, 0);
- }
- }
- else
+ applycolor = r != 1 || g != 1 || b != 1 || a != 1;
+ for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
{
- if (fogallpasses)
- {
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
- R_Mesh_VertexPointer(vertex3f);
- R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
- if (!surface->lightmapinfo && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
- {
- R_Mesh_ColorPointer(varray_color4f);
- for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
- {
- VectorSubtract(v, modelorg, diff);
- f = 1 - exp(fogdensity/DotProduct(diff, diff));
- c[0] = r * f;
- c[1] = g * f;
- c[2] = b * f;
- c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a;
- }
- }
- else
- {
- R_Mesh_ColorPointer(varray_color4f);
- for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
- {
- VectorSubtract(v, modelorg, diff);
- f = 1 - exp(fogdensity/DotProduct(diff, diff));
- c[0] = r * f;
- c[1] = g * f;
- c[2] = b * f;
- c[3] = a;
- }
- }
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- GL_LockArrays(0, 0);
- }
- }
- else
- {
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
- R_Mesh_VertexPointer(vertex3f);
- R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
- if (!surface->lightmaptexture && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
- {
- R_Mesh_ColorPointer(varray_color4f);
- for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
- {
- c[0] = r;
- c[1] = g;
- c[2] = b;
- c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a;
- }
- }
- else
- {
- R_Mesh_ColorPointer(NULL);
- GL_Color(r, g, b, a);
- }
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- GL_LockArrays(0, 0);
- }
- }
+ surface = texturesurfacelist[texturesurfaceindex];
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
+ R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
+ RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, false, false, applycolor, fogallpasses);
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
+ GL_LockArrays(0, 0);
}
}
}
- else
+ if (dopants)
{
- if (!dolightmap && dobase)
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(texture->skin.pants);
+ if (waterscrolling)
+ m.texmatrix[0] = r_waterscrollmatrix;
+ m.pointer_color = varray_color4f;
+ colorscale = 1;
+ if (gl_combine.integer)
+ {
+ m.texrgbscale[0] = 4;
+ colorscale *= 0.25f;
+ }
+ R_Mesh_State(&m);
+ r = ent->colormod[0] * colorpants[0] * colorscale;
+ g = ent->colormod[1] * colorpants[1] * colorscale;
+ b = ent->colormod[2] * colorpants[2] * colorscale;
+ a = texture->currentalpha;
+ if (dolightmap && !dofullbrightpants)
{
- dolightmap = false;
- dobase = false;
- GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], 1);
- memset(&m, 0, sizeof(m));
- m.tex[0] = R_GetTexture(texture->skin.base);
- if (waterscrolling)
- m.texmatrix[0] = r_waterscrollmatrix;
- R_Mesh_State(&m);
+ // q3bsp has no lightmap updates, so the lightstylevalue that
+ // would normally be baked into the lightmaptexture must be
+ // applied to the color
+ if (ent->model->brushq3.data_lightmaps)
+ {
+ float scale = d_lightstylevalue[0] * (1.0f / 128.0f);
+ r *= scale;
+ g *= scale;
+ b *= scale;
+ }
+ applycolor = r != 1 || g != 1 || b != 1 || a != 1;
for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
{
surface = texturesurfacelist[texturesurfaceindex];
- R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg));
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
+ RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmodel, true, applycolor, fogallpasses);
GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
GL_LockArrays(0, 0);
}
}
- if (r_lightmapintensity <= 0 && dolightmap && dobase)
+ else
{
- dolightmap = false;
- dobase = false;
- GL_Color(0, 0, 0, 1);
- memset(&m, 0, sizeof(m));
- R_Mesh_State(&m);
+ applycolor = r != 1 || g != 1 || b != 1 || a != 1;
for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
{
surface = texturesurfacelist[texturesurfaceindex];
- R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg));
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
+ R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
+ RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, false, false, applycolor, fogallpasses);
GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
GL_LockArrays(0, 0);
}
}
- if (r_textureunits.integer >= 2 && gl_combine.integer && dolightmap && dobase)
+ }
+ if (doshirt)
+ {
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ memset(&m, 0, sizeof(m));
+ m.tex[0] = R_GetTexture(texture->skin.shirt);
+ if (waterscrolling)
+ m.texmatrix[0] = r_waterscrollmatrix;
+ m.pointer_color = varray_color4f;
+ colorscale = 1;
+ if (gl_combine.integer)
{
- // dualtexture combine
- GL_BlendFunc(GL_ONE, GL_ZERO);
- GL_DepthMask(true);
- dolightmap = false;
- dobase = false;
- memset(&m, 0, sizeof(m));
- m.tex[1] = R_GetTexture(texture->skin.base);
- if (waterscrolling)
- m.texmatrix[1] = r_waterscrollmatrix;
- m.texrgbscale[1] = 2;
- R_Mesh_State(&m);
- r = ent->colormod[0] * r_lightmapintensity;
- g = ent->colormod[1] * r_lightmapintensity;
- b = ent->colormod[2] * r_lightmapintensity;
- GL_Color(r, g, b, 1);
- if (texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
- {
- R_Mesh_VertexPointer(varray_vertex3f);
- if (r == 1 && g == 1 && b == 1)
- {
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- RSurf_DeformVertices(ent, texture, surface, modelorg);
- R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
- R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f);
- if (surface->lightmaptexture)
- {
- R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
- R_Mesh_ColorPointer(NULL);
- }
- else //if (r == 1 && g == 1 && b == 1)
- {
- R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
- R_Mesh_ColorPointer(surface->groupmesh->data_lightmapcolor4f);
- }
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- GL_LockArrays(0, 0);
- }
- }
- else
- {
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- RSurf_DeformVertices(ent, texture, surface, modelorg);
- R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
- R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f);
- if (surface->lightmaptexture)
- {
- R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
- R_Mesh_ColorPointer(NULL);
- }
- else
- {
- R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
- R_Mesh_ColorPointer(varray_color4f);
- for (i = 0, c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, c += 4)
- {
- c[0] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+0] * r;
- c[1] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+1] * g;
- c[2] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+2] * b;
- c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3];
- }
- }
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- GL_LockArrays(0, 0);
- }
- }
- }
- else
- {
- if (r == 1 && g == 1 && b == 1)
- {
-#if 0
- // experimental direct state calls for measuring
- // R_Mesh_ call overhead, do not use!
- R_Mesh_VertexPointer(varray_vertex3f);
- R_Mesh_TexCoordPointer(0, 2, varray_texcoord2f[0]);
- R_Mesh_TexCoordPointer(1, 2, varray_texcoord2f[1]);
- R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
- R_Mesh_ColorPointer(varray_color4f);
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), surface->groupmesh->data_vertex3f);
- qglClientActiveTexture(GL_TEXTURE0_ARB);
- qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), surface->groupmesh->data_texcoordlightmap2f);
- qglClientActiveTexture(GL_TEXTURE1_ARB);
- qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), surface->groupmesh->data_texcoordtexture2f);
- if (surface->lightmaptexture)
- {
- R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
- qglDisableClientState(GL_COLOR_ARRAY);
- qglColor4f(r, g, b, 1);
- }
- else //if (r == 1 && g == 1 && b == 1)
- {
- R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
- qglEnableClientState(GL_COLOR_ARRAY);
- qglColorPointer(4, GL_FLOAT, sizeof(float[4]), surface->groupmesh->data_lightmapcolor4f);
- }
- qglLockArraysEXT(0, surface->num_vertices);
- qglDrawRangeElements(GL_TRIANGLES, surface->num_firstvertex, surface->num_firstvertex + surface->num_vertices, surface->num_triangles * 3, GL_UNSIGNED_INT, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- qglUnlockArraysEXT();
- }
-#else
- groupmesh = NULL;
- lightmaptexture = NULL;
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- if (groupmesh != surface->groupmesh)
- {
- groupmesh = surface->groupmesh;
- R_Mesh_VertexPointer(groupmesh->data_vertex3f);
- R_Mesh_TexCoordPointer(0, 2, groupmesh->data_texcoordlightmap2f);
- R_Mesh_TexCoordPointer(1, 2, groupmesh->data_texcoordtexture2f);
- if (!lightmaptexture)
- R_Mesh_ColorPointer(groupmesh->data_lightmapcolor4f);
- }
- if (lightmaptexture != surface->lightmaptexture)
- {
- lightmaptexture = surface->lightmaptexture;
- if (lightmaptexture)
- {
- R_Mesh_TexBind(0, R_GetTexture(lightmaptexture));
- R_Mesh_ColorPointer(NULL);
- }
- else //if (r == 1 && g == 1 && b == 1)
- {
- R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
- R_Mesh_ColorPointer(surface->groupmesh->data_lightmapcolor4f);
- }
- }
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- GL_LockArrays(0, 0);
- }
-#endif
- }
- else
- {
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- R_Mesh_VertexPointer(surface->groupmesh->data_vertex3f);
- R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
- R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f);
- if (surface->lightmaptexture)
- {
- R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
- R_Mesh_ColorPointer(NULL);
- }
- else
- {
- R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
- R_Mesh_ColorPointer(varray_color4f);
- for (i = 0, c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, c += 4)
- {
- c[0] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+0] * r;
- c[1] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+1] * g;
- c[2] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+2] * b;
- c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3];
- }
- }
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- GL_LockArrays(0, 0);
- }
- }
- }
+ m.texrgbscale[0] = 4;
+ colorscale *= 0.25f;
}
- // single texture
- if (dolightmap)
+ R_Mesh_State(&m);
+ r = ent->colormod[0] * colorshirt[0] * colorscale;
+ g = ent->colormod[1] * colorshirt[1] * colorscale;
+ b = ent->colormod[2] * colorshirt[2] * colorscale;
+ a = texture->currentalpha;
+ if (dolightmap && !dofullbrightshirt)
{
- GL_BlendFunc(GL_ONE, GL_ZERO);
- GL_DepthMask(true);
- GL_Color(1, 1, 1, 1);
- memset(&m, 0, sizeof(m));
- R_Mesh_State(&m);
- if (texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
+ // q3bsp has no lightmap updates, so the lightstylevalue that
+ // would normally be baked into the lightmaptexture must be
+ // applied to the color
+ if (ent->model->brushq3.data_lightmaps)
{
- R_Mesh_VertexPointer(varray_vertex3f);
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- RSurf_DeformVertices(ent, texture, surface, modelorg);
- R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f);
- if (surface->lightmaptexture)
- {
- R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture));
- R_Mesh_ColorPointer(NULL);
- }
- else //if (r == 1 && g == 1 && b == 1)
- {
- R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
- R_Mesh_ColorPointer(surface->groupmesh->data_lightmapcolor4f);
- }
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- GL_LockArrays(0, 0);
- }
+ float scale = d_lightstylevalue[0] * (1.0f / 128.0f);
+ r *= scale;
+ g *= scale;
+ b *= scale;
}
- else
+ applycolor = r != 1 || g != 1 || b != 1 || a != 1;
+ for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
{
- groupmesh = NULL;
- lightmaptexture = NULL;
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- if (groupmesh != surface->groupmesh)
- {
- groupmesh = surface->groupmesh;
- R_Mesh_VertexPointer(groupmesh->data_vertex3f);
- R_Mesh_TexCoordPointer(0, 2, groupmesh->data_texcoordlightmap2f);
- if (!lightmaptexture)
- R_Mesh_ColorPointer(groupmesh->data_lightmapcolor4f);
- }
- if (lightmaptexture != surface->lightmaptexture)
- {
- lightmaptexture = surface->lightmaptexture;
- if (lightmaptexture)
- {
- R_Mesh_TexBind(0, R_GetTexture(lightmaptexture));
- R_Mesh_ColorPointer(NULL);
- }
- else //if (r == 1 && g == 1 && b == 1)
- {
- R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
- R_Mesh_ColorPointer(surface->groupmesh->data_lightmapcolor4f);
- }
- }
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- GL_LockArrays(0, 0);
- }
+ surface = texturesurfacelist[texturesurfaceindex];
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
+ R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
+ RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmodel, true, applycolor, fogallpasses);
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
+ GL_LockArrays(0, 0);
}
}
- if (dobase)
+ else
{
- GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
- GL_DepthMask(false);
- GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1);
- memset(&m, 0, sizeof(m));
- m.tex[0] = R_GetTexture(texture->skin.base);
- if (waterscrolling)
- m.texmatrix[0] = r_waterscrollmatrix;
- R_Mesh_State(&m);
- if (texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
- {
- R_Mesh_VertexPointer(varray_vertex3f);
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- RSurf_DeformVertices(ent, texture, surface, modelorg);
- R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- GL_LockArrays(0, 0);
- }
- }
- else
+ applycolor = r != 1 || g != 1 || b != 1 || a != 1;
+ for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
{
- groupmesh = NULL;
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- if (groupmesh != surface->groupmesh)
- {
- groupmesh = surface->groupmesh;
- R_Mesh_VertexPointer(groupmesh->data_vertex3f);
- R_Mesh_TexCoordPointer(0, 2, groupmesh->data_texcoordtexture2f);
- }
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- GL_LockArrays(0, 0);
- }
+ surface = texturesurfacelist[texturesurfaceindex];
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
+ R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
+ RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, false, false, applycolor, fogallpasses);
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
+ GL_LockArrays(0, 0);
}
}
}
g = ent->colormod[1] * colorscale * base;
b = ent->colormod[2] * colorscale * base;
a = texture->currentalpha;
+ applycolor = r != 1 || g != 1 || b != 1 || a != 1;
for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
{
surface = texturesurfacelist[texturesurfaceindex];
- vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
- R_Mesh_VertexPointer(vertex3f);
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
- for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
- {
- c[0] = r;
- c[1] = g;
- c[2] = b;
- if (fogallpasses)
- {
- VectorSubtract(v, modelorg, diff);
- f = 1 - exp(fogdensity/DotProduct(diff, diff));
- VectorScale(c, f, c);
- }
- if (!surface->lightmaptexture && surface->groupmesh->data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
- c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a;
- else
- c[3] = a;
- }
+ RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, false, false, applycolor, fogallpasses);
GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
GL_LockArrays(0, 0);
for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
{
surface = texturesurfacelist[texturesurfaceindex];
- R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg));
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoorddetail2f);
GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
g = ent->colormod[1] * colorscale;
b = ent->colormod[2] * colorscale;
a = texture->currentalpha;
- if (fogallpasses)
- {
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
- R_Mesh_VertexPointer(vertex3f);
- R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
- R_Mesh_ColorPointer(varray_color4f);
- if (!surface->lightmaptexture && surface->groupmesh->data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
- {
- for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
- {
- VectorSubtract(v, modelorg, diff);
- f = 1 - exp(fogdensity/DotProduct(diff, diff));
- c[0] = f * r;
- c[1] = f * g;
- c[2] = f * b;
- c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a;
- }
- }
- else
- {
- for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
- {
- VectorSubtract(v, modelorg, diff);
- f = 1 - exp(fogdensity/DotProduct(diff, diff));
- c[0] = f * r;
- c[1] = f * g;
- c[2] = f * b;
- c[3] = a;
- }
- }
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- GL_LockArrays(0, 0);
- }
- }
- else
+ applycolor = r != 1 || g != 1 || b != 1 || a != 1;
+ for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
{
- for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
- {
- surface = texturesurfacelist[texturesurfaceindex];
- vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
- R_Mesh_VertexPointer(vertex3f);
- R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
- if (!surface->lightmaptexture && surface->groupmesh->data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
- {
- R_Mesh_ColorPointer(varray_color4f);
- for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
- {
- c[0] = r;
- c[1] = g;
- c[2] = b;
- c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a;
- }
- }
- else
- {
- R_Mesh_ColorPointer(NULL);
- GL_Color(r, g, b, a);
- }
- GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
- R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
- GL_LockArrays(0, 0);
- }
+ surface = texturesurfacelist[texturesurfaceindex];
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
+ R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
+ RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, false, false, applycolor, fogallpasses);
+ GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
+ R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
+ GL_LockArrays(0, 0);
}
}
if (dofogpass)
// were darkened by fog already, and we should not add fog color
// (because the background was not darkened, there is no fog color
// that was lost behind it).
- if (!fogallpasses)
+ if (fogallpasses)
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
else
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
g = fogcolor[1];
b = fogcolor[2];
a = texture->currentalpha;
+ applycolor = r != 1 || g != 1 || b != 1 || a != 1;
for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++)
{
surface = texturesurfacelist[texturesurfaceindex];
- vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg);
- R_Mesh_VertexPointer(vertex3f);
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f);
R_Mesh_ColorPointer(varray_color4f);
//RSurf_FogPassColors_Vertex3f_Color4f((surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex), varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], texture->currentalpha, 1, surface->num_vertices, modelorg);
if (!surface->lightmaptexture && surface->groupmesh->data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
{
- for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
+ for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
{
VectorSubtract(v, modelorg, diff);
f = exp(fogdensity/DotProduct(diff, diff));
}
else
{
- for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
+ for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4)
{
VectorSubtract(v, modelorg, diff);
f = exp(fogdensity/DotProduct(diff, diff));
*outnumsurfacespointer = info.outnumsurfaces;
}
+extern float *rsurface_vertex3f;
+extern float *rsurface_svector3f;
+extern float *rsurface_tvector3f;
+extern float *rsurface_normal3f;
+extern void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg);
+
void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist, const vec3_t lightmins, const vec3_t lightmaxs)
{
model_t *model = ent->model;
msurface_t *surface;
int surfacelistindex;
- if (r_drawcollisionbrushes.integer < 2)
+ float projectdistance = lightradius + model->radius + r_shadow_projectdistance.value;
+ vec3_t modelorg;
+ texture_t *texture;
+ // check the box in modelspace, it was already checked in worldspace
+ if (!BoxesOverlap(ent->model->normalmins, ent->model->normalmaxs, lightmins, lightmaxs))
+ return;
+ if (r_drawcollisionbrushes.integer >= 2)
+ return;
+ if (!r_shadow_compilingrtlight)
+ R_UpdateAllTextureInfo(ent);
+ if (model->brush.shadowmesh)
{
R_Shadow_PrepareShadowMark(model->brush.shadowmesh->numtriangles);
- if (!r_shadow_compilingrtlight)
- R_UpdateAllTextureInfo(ent);
+ 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++)
+ {
+ 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;
+ Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
{
surface = model->data_surfaces + surfacelist[surfacelistindex];
- if ((surface->texture->currentmaterialflags & (MATERIALFLAG_NODRAW | MATERIALFLAG_TRANSPARENT | MATERIALFLAG_WALL)) != MATERIALFLAG_WALL)
+ // FIXME: get current skin
+ texture = surface->texture;//R_FetchAliasSkin(ent, surface->groupmesh);
+ if (texture->currentmaterialflags & (MATERIALFLAG_NODRAW | MATERIALFLAG_TRANSPARENT) || !surface->num_triangles)
continue;
- if (surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
- 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);
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
+ // identify lit faces within the bounding box
+ R_Shadow_PrepareShadowMark(surface->groupmesh->num_triangles);
+ R_Shadow_MarkVolumeFromBox(surface->num_firsttriangle, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_element3i, relativelightorigin, lightmins, lightmaxs, surface->mins, surface->maxs);
+ R_Shadow_VolumeFromList(surface->groupmesh->num_vertices, surface->groupmesh->num_triangles, rsurface_vertex3f, surface->groupmesh->data_element3i, surface->groupmesh->data_neighbor3i, relativelightorigin, projectdistance, numshadowmark, shadowmarklist);
}
- 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 + r_shadow_projectdistance.value, numshadowmark, shadowmarklist);
}
}
{
model_t *model = ent->model;
msurface_t *surface;
- texture_t *t;
+ texture_t *texture;
int surfacelistindex;
- if (r_drawcollisionbrushes.integer < 2)
+ vec3_t modelorg;
+ if (r_drawcollisionbrushes.integer >= 2)
+ return;
+ if (r_shadow_compilingrtlight)
{
- R_Mesh_Matrix(&ent->matrix);
- if (!r_shadow_compilingrtlight)
- R_UpdateAllTextureInfo(ent);
+ // if compiling an rtlight, capture the meshes
+ int tri;
+ int *e;
+ float *lightmins, *lightmaxs, *v[3], *vertex3f;
for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
{
surface = model->data_surfaces + surfacelist[surfacelistindex];
- if (surface->texture->basematerialflags & MATERIALFLAG_NODRAW || !surface->num_triangles)
+ texture = surface->texture;
+ if ((texture->basematerialflags & (MATERIALFLAG_WALL | MATERIALFLAG_TRANSPARENT)) != MATERIALFLAG_WALL || !surface->num_triangles)
continue;
- if (r_shadow_compilingrtlight)
+ 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 compiling an rtlight, capture the mesh
- t = surface->texture;
- if ((t->basematerialflags & (MATERIALFLAG_WALL | MATERIALFLAG_TRANSPARENT)) == MATERIALFLAG_WALL)
- {
-#if 1
- int tri;
- int *e;
- float *lightmins, *lightmaxs, *v[3], *vertex3f;
- 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)
- {
- 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);
- }
-#else
- 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, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle));
-#endif
- }
+ 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);
}
- else if (ent != r_refdef.worldentity || r_worldsurfacevisible[surfacelist[surfacelistindex]])
+ }
+ }
+ 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];
+ texture = surface->texture->currentframe;
+ // FIXME: transparent surfaces need to be lit later
+ if ((texture->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_TRANSPARENT)) != MATERIALFLAG_WALL || !surface->num_triangles)
+ continue;
+ if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+ qglDisable(GL_CULL_FACE);
+ RSurf_SetVertexPointer(ent, texture, surface, modelorg);
+ if (!rsurface_svector3f)
{
- t = surface->texture->currentframe;
- // FIXME: transparent surfaces need to be lit later
- if ((t->currentmaterialflags & (MATERIALFLAG_WALL | MATERIALFLAG_TRANSPARENT)) == MATERIALFLAG_WALL)
- {
- if (surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
- qglDisable(GL_CULL_FACE);
- R_Shadow_RenderLighting(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle), surface->groupmesh->data_vertex3f, surface->groupmesh->data_svector3f, surface->groupmesh->data_tvector3f, surface->groupmesh->data_normal3f, surface->groupmesh->data_texcoordtexture2f, lightcolor, vec3_origin, vec3_origin, t->skin.base, NULL, NULL, t->skin.nmap, t->skin.gloss);
- if (surface->texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
- qglEnable(GL_CULL_FACE);
- }
+ 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);
}
+ // FIXME: add colormapping
+ 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.base, NULL, NULL, texture->skin.nmap, texture->skin.gloss);
+ if (texture->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+ qglEnable(GL_CULL_FACE);
}
}
}
float segmentmins[3], segmentmaxs[3];
msurface_t *surface;
surfmesh_t *mesh;
- colbrushf_t *thisbrush_start, *thisbrush_end;
+ colbrushf_t *thisbrush_start = NULL, *thisbrush_end = NULL;
matrix4x4_t startmatrix, endmatrix;
memset(trace, 0, sizeof(*trace));
trace->fraction = 1;
}
skin->skin = *skinframe;
+ skin->currentframe = skin;
+ skin->basematerialflags = MATERIALFLAG_WALL;
+ if (skin->skin.fog)
+ skin->basematerialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_TRANSPARENT;
+ skin->currentmaterialflags = skin->basematerialflags;
}
static void Mod_BuildAliasSkinsFromSkinFiles(texture_t *skin, skinfile_t *skinfile, char *meshname, char *shadername)
#define BOUNDI(VALUE,MIN,MAX) if (VALUE < MIN || VALUE >= MAX) Host_Error("model %s has an invalid ##VALUE (%d exceeds %d - %d)\n", loadmodel->name, VALUE, MIN, MAX);
#define BOUNDF(VALUE,MIN,MAX) if (VALUE < MIN || VALUE >= MAX) Host_Error("model %s has an invalid ##VALUE (%f exceeds %f - %f)\n", loadmodel->name, VALUE, MIN, MAX);
-extern void R_Model_Alias_Draw(entity_render_t *ent);
-extern void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist, const vec3_t lightmins, const vec3_t lightmaxs);
-extern void R_Model_Alias_DrawLight(entity_render_t *ent, float *lightcolor, int numsurfaces, const int *surfacelist);
+extern void R_Q1BSP_Draw(entity_render_t *ent);
+extern void R_Q1BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius, int numsurfaces, const int *surfacelist, const vec3_t lightmins, const vec3_t lightmaxs);
+extern void R_Q1BSP_DrawLight(entity_render_t *ent, float *lightcolor, int numsurfaces, const int *surfacelist);
void Mod_IDP0_Load(model_t *mod, void *buffer)
{
int i, j, version, totalskins, skinwidth, skinheight, groupframes, groupskins, numverts;
loadmodel->type = mod_alias;
loadmodel->DrawSky = NULL;
- loadmodel->Draw = R_Model_Alias_Draw;
- loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume;
- loadmodel->DrawLight = R_Model_Alias_DrawLight;
+ loadmodel->Draw = R_Q1BSP_Draw;
+ loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
+ loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
loadmodel->num_surfaces = 1;
+ loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
loadmodel->nummeshes = loadmodel->num_surfaces;
- data = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->nummeshes * sizeof(surfmesh_t *) + loadmodel->nummeshes * sizeof(surfmesh_t));
+ data = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->nummeshes * sizeof(surfmesh_t *) + loadmodel->nummeshes * sizeof(surfmesh_t));
loadmodel->data_surfaces = (void *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
+ loadmodel->surfacelist = (void *)data;data += loadmodel->num_surfaces * sizeof(int);
loadmodel->meshlist = (void *)data;data += loadmodel->num_surfaces * sizeof(surfmesh_t *);
for (i = 0;i < loadmodel->num_surfaces;i++)
+ {
+ loadmodel->surfacelist[i] = i;
loadmodel->meshlist[i] = (void *)data;data += sizeof(surfmesh_t);
+ }
loadmodel->numskins = LittleLong(pinmodel->numskins);
BOUNDI(loadmodel->numskins,0,65536);
Mem_Free(vertremap);
// load the skins
- if ((skinfiles = Mod_LoadSkinFiles()))
+ skinfiles = Mod_LoadSkinFiles();
+ totalskins = loadmodel->numskins;
+ loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, loadmodel->numskins * sizeof(animscene_t));
+ loadmodel->num_textures = loadmodel->num_surfaces;
+ loadmodel->data_textures = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
+ if (skinfiles)
{
- loadmodel->meshlist[0]->num_skins = totalskins = loadmodel->numskins;
- loadmodel->meshlist[0]->data_skins = Mem_Alloc(loadmodel->mempool, loadmodel->meshlist[0]->num_skins * sizeof(texture_t));
- Mod_BuildAliasSkinsFromSkinFiles(loadmodel->meshlist[0]->data_skins, skinfiles, "default", "");
+ Mod_BuildAliasSkinsFromSkinFiles(loadmodel->data_textures, skinfiles, "default", "");
Mod_FreeSkinFiles(skinfiles);
- loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins);
for (i = 0;i < loadmodel->numskins;i++)
{
loadmodel->skinscenes[i].firstframe = i;
}
else
{
- loadmodel->meshlist[0]->num_skins = totalskins;
- loadmodel->meshlist[0]->data_skins = Mem_Alloc(loadmodel->mempool, loadmodel->meshlist[0]->num_skins * sizeof(texture_t));
- loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, loadmodel->numskins * sizeof(animscene_t));
totalskins = 0;
datapointer = startskins;
for (i = 0;i < loadmodel->numskins;i++)
sprintf (name, "%s_%i", loadmodel->name, i);
if (!Mod_LoadSkinFrame(&tempskinframe, name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_CLAMP | TEXF_ALPHA | TEXF_PICMIP, true, false, true))
Mod_LoadSkinFrame_Internal(&tempskinframe, name, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_CLAMP | TEXF_ALPHA | TEXF_PICMIP, true, false, r_fullbrights.integer, (qbyte *)datapointer, skinwidth, skinheight);
- Mod_BuildAliasSkinFromSkinFrame(loadmodel->meshlist[0]->data_skins + totalskins, &tempskinframe);
+ Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + totalskins * loadmodel->num_surfaces, &tempskinframe);
datapointer += skinwidth * skinheight;
totalskins++;
}
memcpy(loadmodel->skinscenes, tempskinscenes, loadmodel->numskins * sizeof(animscene_t));
Mem_Free(tempskinscenes);
- tempaliasskins = loadmodel->meshlist[0]->data_skins;
- loadmodel->meshlist[0]->data_skins = Mem_Alloc(loadmodel->mempool, (totalskins + 1) * sizeof(texture_t));
- memcpy(loadmodel->meshlist[0]->data_skins, tempaliasskins, totalskins * sizeof(texture_t));
+ tempaliasskins = loadmodel->data_textures;
+ loadmodel->data_textures = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * (totalskins + 1) * sizeof(texture_t));
+ memcpy(loadmodel->data_textures, tempaliasskins, loadmodel->num_surfaces * totalskins * sizeof(texture_t));
Mem_Free(tempaliasskins);
// store the info about the new skin
- Mod_BuildAliasSkinFromSkinFrame(loadmodel->meshlist[0]->data_skins + totalskins, &tempskinframe);
+ Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + totalskins * loadmodel->num_surfaces, &tempskinframe);
strcpy(loadmodel->skinscenes[loadmodel->numskins].name, name);
loadmodel->skinscenes[loadmodel->numskins].firstframe = totalskins;
loadmodel->skinscenes[loadmodel->numskins].framecount = 1;
loadmodel->skinscenes[loadmodel->numskins].loop = true;
//increase skin counts
- loadmodel->meshlist[0]->num_skins++;
loadmodel->numskins++;
totalskins++;
}
}
surface = loadmodel->data_surfaces;
+ surface->texture = loadmodel->data_textures;
surface->groupmesh = loadmodel->meshlist[0];
- // FIXME: need to store data_skins in msurface_t, not surfmesh_t
- surface->texture = surface->groupmesh->data_skins;
surface->num_firsttriangle = 0;
surface->num_triangles = surface->groupmesh->num_triangles;
surface->num_firstvertex = 0;
loadmodel->type = mod_alias;
loadmodel->DrawSky = NULL;
- loadmodel->Draw = R_Model_Alias_Draw;
- loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume;
- loadmodel->DrawLight = R_Model_Alias_DrawLight;
+ loadmodel->Draw = R_Q1BSP_Draw;
+ loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
+ loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
if (LittleLong(pinmodel->num_tris) < 1 || LittleLong(pinmodel->num_tris) > 65536)
Host_Error ("%s is not a valid model", loadmodel->name);
loadmodel->num_surfaces = 1;
+ loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
loadmodel->nummeshes = loadmodel->num_surfaces;
- data = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->nummeshes * sizeof(surfmesh_t *) + loadmodel->nummeshes * sizeof(surfmesh_t));
+ data = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->nummeshes * sizeof(surfmesh_t *) + loadmodel->nummeshes * sizeof(surfmesh_t));
loadmodel->data_surfaces = (void *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
+ loadmodel->surfacelist = (void *)data;data += loadmodel->num_surfaces * sizeof(int);
loadmodel->meshlist = (void *)data;data += loadmodel->num_surfaces * sizeof(surfmesh_t *);
for (i = 0;i < loadmodel->num_surfaces;i++)
+ {
+ loadmodel->surfacelist[i] = i;
loadmodel->meshlist[i] = (void *)data;data += sizeof(surfmesh_t);
+ }
loadmodel->numskins = LittleLong(pinmodel->num_skins);
numxyz = LittleLong(pinmodel->num_xyz);
// load the skins
inskin = (void*)(base + LittleLong(pinmodel->ofs_skins));
- if ((skinfiles = Mod_LoadSkinFiles()))
+ skinfiles = Mod_LoadSkinFiles();
+ if (skinfiles)
{
- loadmodel->meshlist[0]->num_skins = loadmodel->numskins;
- loadmodel->meshlist[0]->data_skins = Mem_Alloc(loadmodel->mempool, loadmodel->meshlist[0]->num_skins * sizeof(texture_t));
- Mod_BuildAliasSkinsFromSkinFiles(loadmodel->meshlist[0]->data_skins, skinfiles, "default", "");
+ loadmodel->num_textures = loadmodel->num_surfaces;
+ loadmodel->data_textures = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
+ Mod_BuildAliasSkinsFromSkinFiles(loadmodel->data_textures, skinfiles, "default", "");
Mod_FreeSkinFiles(skinfiles);
}
else if (loadmodel->numskins)
{
// skins found (most likely not a player model)
- loadmodel->meshlist[0]->num_skins = loadmodel->numskins;
- loadmodel->meshlist[0]->data_skins = Mem_Alloc(loadmodel->mempool, loadmodel->meshlist[0]->num_skins * sizeof(texture_t));
+ loadmodel->num_textures = loadmodel->num_surfaces;
+ loadmodel->data_textures = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
for (i = 0;i < loadmodel->numskins;i++, inskin += MD2_SKINNAME)
{
if (Mod_LoadSkinFrame(&tempskinframe, inskin, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_CLAMP | TEXF_PRECACHE | TEXF_PICMIP, true, false, true))
- Mod_BuildAliasSkinFromSkinFrame(loadmodel->meshlist[0]->data_skins + i, &tempskinframe);
+ Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + i * loadmodel->num_surfaces, &tempskinframe);
else
{
Con_Printf("%s is missing skin \"%s\"\n", loadmodel->name, inskin);
- Mod_BuildAliasSkinFromSkinFrame(loadmodel->meshlist[0]->data_skins + i, NULL);
+ Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + i * loadmodel->num_surfaces, NULL);
}
}
}
{
// no skins (most likely a player model)
loadmodel->numskins = 1;
- loadmodel->meshlist[0]->num_skins = loadmodel->numskins;
- loadmodel->meshlist[0]->data_skins = Mem_Alloc(loadmodel->mempool, loadmodel->meshlist[0]->num_skins * sizeof(texture_t));
- Mod_BuildAliasSkinFromSkinFrame(loadmodel->meshlist[0]->data_skins, NULL);
+ loadmodel->num_textures = loadmodel->num_surfaces;
+ loadmodel->data_textures = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
+ Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures, NULL);
}
loadmodel->skinscenes = Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numskins);
surface = loadmodel->data_surfaces;
surface->groupmesh = loadmodel->meshlist[0];
- // FIXME: need to store data_skins in msurface_t, not surfmesh_t
- surface->texture = surface->groupmesh->data_skins;
+ surface->texture = loadmodel->data_textures;
surface->num_firsttriangle = 0;
surface->num_triangles = surface->groupmesh->num_triangles;
surface->num_firstvertex = 0;
loadmodel->type = mod_alias;
loadmodel->DrawSky = NULL;
- loadmodel->Draw = R_Model_Alias_Draw;
- loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume;
- loadmodel->DrawLight = R_Model_Alias_DrawLight;
+ loadmodel->Draw = R_Q1BSP_Draw;
+ loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
+ loadmodel->DrawLight = R_Q1BSP_DrawLight;
loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox;
loadmodel->flags = LittleLong(pinmodel->flags);
loadmodel->synctype = ST_RAND;
}
// load meshes
+ loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
loadmodel->nummeshes = loadmodel->num_surfaces;
- data = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->nummeshes * sizeof(surfmesh_t *) + loadmodel->nummeshes * sizeof(surfmesh_t));
+ loadmodel->num_textures = loadmodel->num_surfaces;
+ data = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->nummeshes * sizeof(surfmesh_t *) + loadmodel->nummeshes * sizeof(surfmesh_t) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
loadmodel->data_surfaces = (void *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
+ loadmodel->surfacelist = (void *)data;data += loadmodel->num_surfaces * sizeof(int);
loadmodel->meshlist = (void *)data;data += loadmodel->num_surfaces * sizeof(surfmesh_t *);
+ loadmodel->data_textures = (void *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
for (i = 0;i < loadmodel->num_surfaces;i++)
- mesh = loadmodel->meshlist[i] = (void *)data;data += sizeof(surfmesh_t);
+ {
+ loadmodel->surfacelist[i] = i;
+ loadmodel->meshlist[i] = (void *)data;data += sizeof(surfmesh_t);
+ }
for (i = 0, pinmesh = (md3mesh_t *)((qbyte *)pinmodel + LittleLong(pinmodel->lump_meshes));i < loadmodel->num_surfaces;i++, pinmesh = (md3mesh_t *)((qbyte *)pinmesh + LittleLong(pinmesh->lump_end)))
{
if (memcmp(pinmesh->identifier, "IDP3", 4))
Host_Error("Mod_IDP3_Load: invalid mesh identifier (not IDP3)\n");
mesh = loadmodel->meshlist[i];
- mesh->num_skins = loadmodel->numskins;
mesh->num_morphframes = LittleLong(pinmesh->num_frames);
mesh->num_vertices = LittleLong(pinmesh->num_vertices);
mesh->num_triangles = LittleLong(pinmesh->num_triangles);
- mesh->data_skins = Mem_Alloc(loadmodel->mempool, mesh->num_skins * sizeof(texture_t));
mesh->data_element3i = Mem_Alloc(loadmodel->mempool, mesh->num_triangles * sizeof(int[3]));
mesh->data_neighbor3i = Mem_Alloc(loadmodel->mempool, mesh->num_triangles * sizeof(int[3]));
mesh->data_texcoordtexture2f = Mem_Alloc(loadmodel->mempool, mesh->num_vertices * sizeof(float[2]));
Mod_Alias_Mesh_CompileFrameZero(mesh);
if (LittleLong(pinmesh->num_shaders) >= 1)
- Mod_BuildAliasSkinsFromSkinFiles(mesh->data_skins, skinfiles, pinmesh->name, ((md3shader_t *)((qbyte *) pinmesh + LittleLong(pinmesh->lump_shaders)))->name);
+ Mod_BuildAliasSkinsFromSkinFiles(loadmodel->data_textures + i, skinfiles, pinmesh->name, ((md3shader_t *)((qbyte *) pinmesh + LittleLong(pinmesh->lump_shaders)))->name);
else
- for (j = 0;j < mesh->num_skins;j++)
- Mod_BuildAliasSkinFromSkinFrame(mesh->data_skins + j, NULL);
+ for (j = 0;j < loadmodel->numskins;j++)
+ Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + i + j * loadmodel->num_surfaces, NULL);
surface = loadmodel->data_surfaces + i;
surface->groupmesh = mesh;
- // FIXME: need to store data_skins in msurface_t, not surfmesh_t
- surface->texture = mesh->data_skins;
+ surface->texture = loadmodel->data_textures + i;
surface->num_firsttriangle = 0;
surface->num_triangles = mesh->num_triangles;
surface->num_firstvertex = 0;
loadmodel->type = mod_alias;
loadmodel->DrawSky = NULL;
- loadmodel->Draw = R_Model_Alias_Draw;
- loadmodel->DrawShadowVolume = R_Model_Alias_DrawShadowVolume;
- loadmodel->DrawLight = R_Model_Alias_DrawLight;
+ loadmodel->Draw = R_Q1BSP_Draw;
+ loadmodel->DrawShadowVolume = R_Q1BSP_DrawShadowVolume;
+ loadmodel->DrawLight = R_Q1BSP_DrawLight;
//loadmodel->TraceBox = Mod_MDLMD2MD3_TraceBox; // FIXME: implement collisions
loadmodel->flags = 0; // there are no flags on zym models
loadmodel->synctype = ST_RAND;
//loadmodel->alias.zymdata_trizone = Mem_Alloc(loadmodel->mempool, pheader->numtris);
//memcpy(loadmodel->alias.zymdata_trizone, (void *) (pheader->lump_trizone.start + pbase), pheader->numtris);
+ loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
loadmodel->nummeshes = loadmodel->num_surfaces;
- data = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->nummeshes * sizeof(surfmesh_t *) + loadmodel->nummeshes * sizeof(surfmesh_t));
+ loadmodel->num_textures = loadmodel->num_surfaces;
+ data = Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->nummeshes * sizeof(surfmesh_t *) + loadmodel->nummeshes * sizeof(surfmesh_t) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t));
loadmodel->data_surfaces = (void *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
+ loadmodel->surfacelist = (void *)data;data += loadmodel->num_surfaces * sizeof(int);
loadmodel->meshlist = (void *)data;data += loadmodel->num_surfaces * sizeof(surfmesh_t *);
+ loadmodel->data_textures = (void *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
for (i = 0;i < loadmodel->num_surfaces;i++)
- mesh = loadmodel->meshlist[i] = (void *)data;data += sizeof(surfmesh_t);
+ {
+ loadmodel->surfacelist[i] = i;
+ loadmodel->meshlist[i] = (void *)data;data += sizeof(surfmesh_t);
+ }
//zymlump_t lump_shaders; // char shadername[numshaders][32]; // shaders used on this model
//zymlump_t lump_render; // int renderlist[rendersize]; // sorted by shader with run lengths (int count), shaders are sequentially used, each run can be used with glDrawElements (each triangle is 3 int indices)
if (renderlist + count * 3 > renderlistend || (i == pheader->numshaders - 1 && renderlist + count * 3 != renderlistend))
Host_Error("%s corrupt renderlist (wrong size)\n", loadmodel->name);
mesh = loadmodel->meshlist[i];
- mesh->num_skins = loadmodel->numskins;
mesh->num_triangles = count;
- mesh->data_skins = Mem_Alloc(loadmodel->mempool, mesh->num_skins * sizeof(texture_t));
mesh->data_element3i = Mem_Alloc(loadmodel->mempool, mesh->num_triangles * sizeof(int[3]));
mesh->data_neighbor3i = Mem_Alloc(loadmodel->mempool, mesh->num_triangles * sizeof(int[3]));
outelements = mesh->data_element3i;
// name as the section name
shadername = (char *) (pheader->lump_shaders.start + pbase) + i * 32;
if (shadername[0])
- Mod_BuildAliasSkinsFromSkinFiles(mesh->data_skins, skinfiles, shadername, shadername);
+ Mod_BuildAliasSkinsFromSkinFiles(loadmodel->data_textures + i, skinfiles, shadername, shadername);
else
- for (j = 0;j < mesh->num_skins;j++)
- Mod_BuildAliasSkinFromSkinFrame(mesh->data_skins + j, NULL);
+ for (j = 0;j < loadmodel->numskins;j++)
+ Mod_BuildAliasSkinFromSkinFrame(loadmodel->data_textures + i + j * loadmodel->num_surfaces, NULL);
surface = loadmodel->data_surfaces + i;
surface->groupmesh = mesh;
- // FIXME: need to store data_skins in msurface_t, not surfmesh_t
- surface->texture = mesh->data_skins;
+ surface->texture = loadmodel->data_textures + i;
surface->num_firsttriangle = 0;
surface->num_triangles = mesh->num_triangles;
surface->num_firstvertex = 0;