From bca6ff3a0962b1bde364755a153e0f5ccb98f18a Mon Sep 17 00:00:00 2001 From: havoc Date: Fri, 13 May 2005 03:24:13 +0000 Subject: [PATCH] finished model/map rendering merge, model renderer has been completely removed model_t num_textures now lies a bit to keep things simple, it equals num_surfaces on models, even if there are multiple skins, in data_textures these extra textures really do exist even though num_textures does not count them (this was done so that UpdateAllTextureInfo won't crash trying to index later skins on the later skins themselves) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@5277 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_models.c | 392 ------------------ gl_rmain.c | 1078 ++++++++++++++++++++---------------------------- gl_rsurf.c | 155 ++++--- model_alias.c | 150 ++++--- model_shared.h | 3 - 5 files changed, 627 insertions(+), 1151 deletions(-) diff --git a/gl_models.c b/gl_models.c index 6bd61f43..8b137891 100644 --- a/gl_models.c +++ b/gl_models.c @@ -1,393 +1 @@ -#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); - } -} - diff --git a/gl_rmain.c b/gl_rmain.c index 834017ca..4ea8d46c 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -1453,13 +1453,23 @@ void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *plane 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) @@ -1480,13 +1490,41 @@ void R_UpdateAllTextureInfo(entity_render_t *ent) 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); @@ -1495,13 +1533,13 @@ static void RSurf_DeformVertices(const entity_render_t *ent, const texture_t *te { 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); @@ -1510,9 +1548,20 @@ static void RSurf_DeformVertices(const entity_render_t *ent, const texture_t *te 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); @@ -1521,62 +1570,170 @@ static void RSurf_DeformVertices(const entity_render_t *ent, const texture_t *te { 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) { @@ -1592,8 +1749,8 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text 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); @@ -1646,7 +1803,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text 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); @@ -1679,7 +1836,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text 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); @@ -1694,585 +1851,295 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text 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); } } } @@ -2298,28 +2165,13 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text 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); @@ -2336,7 +2188,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text 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)); @@ -2359,72 +2211,16 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text 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) @@ -2440,7 +2236,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text // 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); @@ -2454,17 +2250,17 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text 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)); @@ -2476,7 +2272,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text } 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)); diff --git a/gl_rsurf.c b/gl_rsurf.c index 839cf24a..c55d8902 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -656,26 +656,75 @@ void R_Q1BSP_GetLightInfo(entity_render_t *ent, vec3_t relativelightorigin, floa *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); } } @@ -683,58 +732,64 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, float *lightcolor, int numsurfaces, { 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); } } } diff --git a/model_alias.c b/model_alias.c index 8334f3ec..15f97cba 100644 --- a/model_alias.c +++ b/model_alias.c @@ -185,7 +185,7 @@ static void Mod_MDLMD2MD3_TraceBox(model_t *model, int frame, trace_t *trace, co 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; @@ -361,6 +361,11 @@ static void Mod_BuildAliasSkinFromSkinFrame(texture_t *skin, skinframe_t *skinfr } 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) @@ -414,9 +419,9 @@ static void Mod_BuildAliasSkinsFromSkinFiles(texture_t *skin, skinfile_t *skinfi #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; @@ -451,18 +456,23 @@ void Mod_IDP0_Load(model_t *mod, void *buffer) 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); @@ -616,13 +626,15 @@ void Mod_IDP0_Load(model_t *mod, void *buffer) 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; @@ -633,9 +645,6 @@ void Mod_IDP0_Load(model_t *mod, void *buffer) } 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++) @@ -680,7 +689,7 @@ void Mod_IDP0_Load(model_t *mod, void *buffer) 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++; } @@ -695,13 +704,13 @@ void Mod_IDP0_Load(model_t *mod, void *buffer) 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; @@ -709,16 +718,14 @@ void Mod_IDP0_Load(model_t *mod, void *buffer) 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; @@ -770,9 +777,9 @@ void Mod_IDP2_Load(model_t *mod, void *buffer) 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) @@ -797,12 +804,17 @@ void Mod_IDP2_Load(model_t *mod, void *buffer) 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); @@ -817,26 +829,27 @@ void Mod_IDP2_Load(model_t *mod, void *buffer) // 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); } } } @@ -844,9 +857,9 @@ void Mod_IDP2_Load(model_t *mod, void *buffer) { // 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); @@ -969,8 +982,7 @@ void Mod_IDP2_Load(model_t *mod, void *buffer) 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; @@ -1004,9 +1016,9 @@ void Mod_IDP3_Load(model_t *mod, void *buffer) 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; @@ -1054,22 +1066,27 @@ void Mod_IDP3_Load(model_t *mod, void *buffer) } // 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])); @@ -1093,15 +1110,14 @@ void Mod_IDP3_Load(model_t *mod, void *buffer) 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; @@ -1135,9 +1151,9 @@ void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer) 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; @@ -1291,12 +1307,19 @@ void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer) //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) @@ -1314,9 +1337,7 @@ void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer) 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; @@ -1383,15 +1404,14 @@ void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer) // 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; diff --git a/model_shared.h b/model_shared.h index 614ac4c1..5004a972 100644 --- a/model_shared.h +++ b/model_shared.h @@ -99,9 +99,6 @@ typedef struct surfmesh_s float *data_texcoorddetail2f; // float[verts*2] texcoords for detail texture float *data_lightmapcolor4f; int *data_lightmapoffsets; // index into surface's lightmap samples for vertex lighting - // if a model these will be a skin list to choose from - int num_skins; - struct texture_s *data_skins; // morph blending, these are zero if model is skeletal or static int num_morphframes; float *data_morphvertex3f; -- 2.39.2