return false;
}
-static void RSurfShader_Sky(const entity_render_t *ent, const msurface_t *firstsurf)
+static void RSurfShader_Sky(const entity_render_t *ent, const texture_t *texture)
{
const msurface_t *surf;
const surfmesh_t *mesh;
m.wantoverbright = false;
m.depthwrite = true;
R_Mesh_State(&m);
- for (surf = firstsurf;surf;surf = surf->chain)
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
{
for (mesh = surf->mesh;mesh;mesh = mesh->chain)
{
}
}
-static void RSurfShader_Water(const entity_render_t *ent, const msurface_t *firstsurf)
+static void RSurfShader_Water(const entity_render_t *ent, const texture_t *texture)
{
const msurface_t *surf;
vec3_t center;
- for (surf = firstsurf;surf;surf = surf->chain)
+ if ((r_wateralpha.value < 1 && !(texture->flags & SURF_DRAWNOALPHA)) || ent->effects & EF_ADDITIVE || texture->fogtexture)
{
- if ((r_wateralpha.value < 1 && !(surf->flags & SURF_DRAWNOALPHA)) || ent->effects & EF_ADDITIVE || surf->currenttexture->fogtexture)
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
{
Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
R_MeshQueue_AddTransparent(center, RSurfShader_Water_Callback, ent, surf - ent->model->surfaces);
}
- else
- RSurfShader_Water_Callback(ent, surf - ent->model->surfaces);
}
+ else
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
+ RSurfShader_Water_Callback(ent, surf - ent->model->surfaces);
}
static void RSurfShader_Wall_Pass_BaseVertex(const entity_render_t *ent, const msurface_t *surf)
}
}
-static void RSurfShader_OpaqueWall_Pass_TripleTexCombine(const entity_render_t *ent, const msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(const entity_render_t *ent, const texture_t *texture)
{
+ const msurface_t *surf;
const surfmesh_t *mesh;
- static rmeshstate_t m;
+ rmeshstate_t m;
+ int lightmaptexturenum;
float cl;
- //memset(&m, 0, sizeof(m));
+ memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
- m.wantoverbright = false;
- m.tex[0] = R_GetTexture(surf->currenttexture->texture);
- m.texrgbscale[0] = 1.0f;
- m.tex[1] = R_GetTexture(surf->lightmaptexture);
- m.texrgbscale[1] = 4.0f;
- m.tex[2] = R_GetTexture(surf->currenttexture->detailtexture);
- m.texrgbscale[2] = 2.0f;
+ //m.wantoverbright = false;
+ m.tex[0] = R_GetTexture(texture->texture);
+ m.tex[1] = R_GetTexture(texture->surfacechain->lightmaptexture);
+ m.tex[2] = R_GetTexture(texture->detailtexture);
+ m.texrgbscale[0] = 1;
+ m.texrgbscale[1] = 4;
+ m.texrgbscale[2] = 2;
R_Mesh_State(&m);
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
{
- R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
- memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
- memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- memcpy(varray_texcoord[0], mesh->st, mesh->numverts * sizeof(float[2]));
- memcpy(varray_texcoord[1], mesh->uv, mesh->numverts * sizeof(float[2]));
- memcpy(varray_texcoord[2], mesh->ab, mesh->numverts * sizeof(float[2]));
- cl = (float) (1 << lightscalebit) * mesh_colorscale;
- R_FillColors(varray_color, mesh->numverts, cl, cl, cl, 1);
- R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ lightmaptexturenum = R_GetTexture(surf->lightmaptexture);
+ if (m.tex[1] != lightmaptexturenum)
+ {
+ m.tex[1] = lightmaptexturenum;
+ R_Mesh_State(&m);
+ }
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
+ memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
+ memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
+ memcpy(varray_texcoord[0], mesh->st, mesh->numverts * sizeof(float[2]));
+ memcpy(varray_texcoord[1], mesh->uv, mesh->numverts * sizeof(float[2]));
+ memcpy(varray_texcoord[2], mesh->ab, mesh->numverts * sizeof(float[2]));
+ cl = (float) (1 << lightscalebit) * mesh_colorscale;
+ R_FillColors(varray_color, mesh->numverts, cl, cl, cl, 1);
+ R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ }
}
}
-static void RSurfShader_OpaqueWall_Pass_BaseMTex(const entity_render_t *ent, const msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseDoubleTex(const entity_render_t *ent, const texture_t *texture)
{
+ const msurface_t *surf;
const surfmesh_t *mesh;
rmeshstate_t m;
+ int lightmaptexturenum;
float cl;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
m.wantoverbright = true;
- m.tex[0] = R_GetTexture(surf->currenttexture->texture);
- m.tex[1] = R_GetTexture(surf->lightmaptexture);
+ m.tex[0] = R_GetTexture(texture->texture);
+ m.tex[1] = R_GetTexture(texture->surfacechain->lightmaptexture);
R_Mesh_State(&m);
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
{
- R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
- memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
- memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- memcpy(varray_texcoord[0], mesh->st, mesh->numverts * sizeof(float[2]));
- memcpy(varray_texcoord[1], mesh->uv, mesh->numverts * sizeof(float[2]));
- cl = (float) (1 << lightscalebit) * mesh_colorscale;
- R_FillColors(varray_color, mesh->numverts, cl, cl, cl, 1);
- R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ lightmaptexturenum = R_GetTexture(surf->lightmaptexture);
+ if (m.tex[1] != lightmaptexturenum)
+ {
+ m.tex[1] = lightmaptexturenum;
+ R_Mesh_State(&m);
+ }
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
+ memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
+ memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
+ memcpy(varray_texcoord[0], mesh->st, mesh->numverts * sizeof(float[2]));
+ memcpy(varray_texcoord[1], mesh->uv, mesh->numverts * sizeof(float[2]));
+ cl = (float) (1 << lightscalebit) * mesh_colorscale;
+ R_FillColors(varray_color, mesh->numverts, cl, cl, cl, 1);
+ R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ }
}
}
-static void RSurfShader_OpaqueWall_Pass_BaseTexture(const entity_render_t *ent, const msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseTexture(const entity_render_t *ent, const texture_t *texture)
{
+ const msurface_t *surf;
const surfmesh_t *mesh;
rmeshstate_t m;
- float cl;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ONE;
m.blendfunc2 = GL_ZERO;
- m.wantoverbright = false;
- m.tex[0] = R_GetTexture(surf->currenttexture->texture);
+ //m.wantoverbright = false;
+ m.tex[0] = R_GetTexture(texture->texture);
R_Mesh_State(&m);
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
{
- R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
- memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
- memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- memcpy(varray_texcoord[0], mesh->st, mesh->numverts * sizeof(float[2]));
- cl = mesh_colorscale;
- R_FillColors(varray_color, mesh->numverts, cl, cl, cl, 1);
- R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
+ memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
+ memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
+ memcpy(varray_texcoord[0], mesh->st, mesh->numverts * sizeof(float[2]));
+ R_FillColors(varray_color, mesh->numverts, 1, 1, 1, 1);
+ R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ }
}
}
-static void RSurfShader_OpaqueWall_Pass_BaseLightmap(const entity_render_t *ent, const msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseLightmap(const entity_render_t *ent, const texture_t *texture)
{
+ const msurface_t *surf;
const surfmesh_t *mesh;
rmeshstate_t m;
+ int lightmaptexturenum;
float cl;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_ZERO;
m.blendfunc2 = GL_SRC_COLOR;
m.wantoverbright = true;
- m.tex[0] = R_GetTexture(surf->lightmaptexture);
+ m.tex[0] = R_GetTexture(texture->surfacechain->lightmaptexture);
R_Mesh_State(&m);
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
{
- R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
- memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
- memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- memcpy(varray_texcoord[0], mesh->uv, mesh->numverts * sizeof(float[2]));
- cl = (float) (1 << lightscalebit) * mesh_colorscale;
- R_FillColors(varray_color, mesh->numverts, cl, cl, cl, 1);
- R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ lightmaptexturenum = R_GetTexture(surf->lightmaptexture);
+ if (m.tex[0] != lightmaptexturenum)
+ {
+ m.tex[0] = lightmaptexturenum;
+ R_Mesh_State(&m);
+ }
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
+ memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
+ memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
+ memcpy(varray_texcoord[0], mesh->uv, mesh->numverts * sizeof(float[2]));
+ cl = (float) (1 << lightscalebit) * mesh_colorscale;
+ R_FillColors(varray_color, mesh->numverts, cl, cl, cl, 1);
+ R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ }
}
}
-static void RSurfShader_OpaqueWall_Pass_Light(const entity_render_t *ent, const msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Light(const entity_render_t *ent, const texture_t *texture)
{
+ const msurface_t *surf;
const surfmesh_t *mesh;
rmeshstate_t m;
- if (surf->dlightframe != r_framecount)
- return;
- if (ent->effects & EF_FULLBRIGHT)
- return;
-
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
m.wantoverbright = true;
- m.tex[0] = R_GetTexture(surf->currenttexture->texture);
+ m.tex[0] = R_GetTexture(texture->texture);
R_Mesh_State(&m);
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
{
- if (RSurf_LightCheck(&ent->inversematrix, surf->dlightbits, mesh))
+ if (surf->dlightframe == r_framecount)
{
- R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
- memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
- memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- memcpy(varray_texcoord[0], mesh->st, mesh->numverts * sizeof(float[2]));
- R_FillColors(varray_color, mesh->numverts, 0, 0, 0, 1);
- RSurf_LightSeparate(&ent->inversematrix, surf->dlightbits, mesh->numverts, varray_vertex, varray_color);
- RSurf_ScaleColors(varray_color, mesh_colorscale, mesh->numverts);
- R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ if (RSurf_LightCheck(&ent->inversematrix, surf->dlightbits, mesh))
+ {
+ R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
+ memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
+ memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
+ memcpy(varray_texcoord[0], mesh->st, mesh->numverts * sizeof(float[2]));
+ R_FillColors(varray_color, mesh->numverts, 0, 0, 0, 1);
+ RSurf_LightSeparate(&ent->inversematrix, surf->dlightbits, mesh->numverts, varray_vertex, varray_color);
+ RSurf_ScaleColors(varray_color, mesh_colorscale, mesh->numverts);
+ R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ }
+ }
}
}
}
-static void RSurfShader_OpaqueWall_Pass_Fog(const entity_render_t *ent, const msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Fog(const entity_render_t *ent, const texture_t *texture)
{
+ const msurface_t *surf;
const surfmesh_t *mesh;
rmeshstate_t m;
float modelorg[3];
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE_MINUS_SRC_ALPHA;
- m.wantoverbright = false;
- m.tex[0] = R_GetTexture(surf->currenttexture->fogtexture);
+ //m.wantoverbright = false;
+ //m.tex[0] = 0;
R_Mesh_State(&m);
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
{
- R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
- memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
- memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- if (m.tex[0])
- memcpy(varray_texcoord[0], mesh->st, mesh->numverts * sizeof(float[2]));
- RSurf_FogPassColors(varray_vertex, varray_color, fogcolor[0], fogcolor[1], fogcolor[2], 1, mesh_colorscale, mesh->numverts, modelorg);
- R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
+ memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
+ memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
+ if (m.tex[0])
+ memcpy(varray_texcoord[0], mesh->st, mesh->numverts * sizeof(float[2]));
+ RSurf_FogPassColors(varray_vertex, varray_color, fogcolor[0], fogcolor[1], fogcolor[2], 1, mesh_colorscale, mesh->numverts, modelorg);
+ R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ }
}
}
-static void RSurfShader_OpaqueWall_Pass_BaseDetail(const entity_render_t *ent, const msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_BaseDetail(const entity_render_t *ent, const texture_t *texture)
{
+ const msurface_t *surf;
const surfmesh_t *mesh;
rmeshstate_t m;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_DST_COLOR;
m.blendfunc2 = GL_SRC_COLOR;
- m.wantoverbright = false;
- m.tex[0] = R_GetTexture(surf->currenttexture->detailtexture);
+ //m.wantoverbright = false;
+ m.tex[0] = R_GetTexture(texture->detailtexture);
R_Mesh_State(&m);
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
{
- R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
- memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
- memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- memcpy(varray_texcoord[0], mesh->ab, mesh->numverts * sizeof(float[2]));
- R_FillColors(varray_color, mesh->numverts, 1, 1, 1, 1);
- R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
+ memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
+ memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
+ memcpy(varray_texcoord[0], mesh->ab, mesh->numverts * sizeof(float[2]));
+ R_FillColors(varray_color, mesh->numverts, 1, 1, 1, 1);
+ R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ }
}
}
-static void RSurfShader_OpaqueWall_Pass_Glow(const entity_render_t *ent, const msurface_t *surf)
+static void RSurfShader_OpaqueWall_Pass_Glow(const entity_render_t *ent, const texture_t *texture)
{
+ const msurface_t *surf;
const surfmesh_t *mesh;
rmeshstate_t m;
memset(&m, 0, sizeof(m));
m.blendfunc1 = GL_SRC_ALPHA;
m.blendfunc2 = GL_ONE;
- m.wantoverbright = false;
- m.tex[0] = R_GetTexture(surf->currenttexture->glowtexture);
+ //m.wantoverbright = false;
+ m.tex[0] = R_GetTexture(texture->glowtexture);
R_Mesh_State(&m);
- for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
{
- R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
- memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
- memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- memcpy(varray_texcoord[0], mesh->st, mesh->numverts * sizeof(float[2]));
- R_FillColors(varray_color, mesh->numverts, mesh_colorscale, mesh_colorscale, mesh_colorscale, 1);
- R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ for (mesh = surf->mesh;mesh;mesh = mesh->chain)
+ {
+ R_Mesh_ResizeCheck(mesh->numverts, mesh->numtriangles);
+ memcpy(varray_element, mesh->index, mesh->numtriangles * sizeof(int[3]));
+ memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
+ memcpy(varray_texcoord[0], mesh->st, mesh->numverts * sizeof(float[2]));
+ R_FillColors(varray_color, mesh->numverts, mesh_colorscale, mesh_colorscale, mesh_colorscale, 1);
+ R_Mesh_Draw(mesh->numverts, mesh->numtriangles);
+ }
}
}
RSurfShader_Wall_Pass_Fog(ent, surf);
}
-static void RSurfShader_Wall_Fullbright(const entity_render_t *ent, const msurface_t *firstsurf)
+static void RSurfShader_Wall_Fullbright(const entity_render_t *ent, const texture_t *texture)
{
const msurface_t *surf;
vec3_t center;
- if (ent->effects & EF_ADDITIVE || ent->alpha < 1)
+ if (ent->effects & EF_ADDITIVE || ent->alpha < 1 || texture->fogtexture != NULL)
{
- for (surf = firstsurf;surf;surf = surf->chain)
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
{
Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
R_MeshQueue_AddTransparent(center, RSurfShader_Wall_Fullbright_Callback, ent, surf - ent->model->surfaces);
}
else
{
- for (surf = firstsurf;surf;surf = surf->chain)
- {
- if (surf->currenttexture->fogtexture != NULL)
- {
- Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
- R_MeshQueue_AddTransparent(center, RSurfShader_Wall_Fullbright_Callback, ent, surf - ent->model->surfaces);
- }
- else
- RSurfShader_Wall_Pass_BaseFullbright(ent, surf);
- }
- for (surf = firstsurf;surf;surf = surf->chain)
- if (surf->currenttexture->glowtexture)
- if (surf->currenttexture->fogtexture == NULL)
- RSurfShader_Wall_Pass_Glow(ent, surf);
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
+ RSurfShader_Wall_Pass_BaseFullbright(ent, surf);
+ if (texture->glowtexture)
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
+ RSurfShader_Wall_Pass_Glow(ent, surf);
if (fogenabled)
- for (surf = firstsurf;surf;surf = surf->chain)
- if (surf->currenttexture->fogtexture == NULL)
- RSurfShader_Wall_Pass_Fog(ent, surf);
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
+ RSurfShader_Wall_Pass_Fog(ent, surf);
}
}
RSurfShader_Wall_Pass_Fog(ent, surf);
}
-static void RSurfShader_Wall_Vertex(const entity_render_t *ent, const msurface_t *firstsurf)
+static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const texture_t *texture)
{
const msurface_t *surf;
vec3_t center;
- if (ent->effects & EF_ADDITIVE || ent->alpha < 1)
+ if (ent->effects & EF_ADDITIVE || ent->alpha < 1 || texture->fogtexture != NULL)
{
- for (surf = firstsurf;surf;surf = surf->chain)
+ // transparent vertex shaded from lightmap
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
{
Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
R_MeshQueue_AddTransparent(center, RSurfShader_Wall_Vertex_Callback, ent, surf - ent->model->surfaces);
}
}
- else
+ else if (r_vertexsurfaces.integer)
{
- for (surf = firstsurf;surf;surf = surf->chain)
- {
- if (surf->currenttexture->fogtexture != NULL)
- {
- Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
- R_MeshQueue_AddTransparent(center, RSurfShader_Wall_Vertex_Callback, ent, surf - ent->model->surfaces);
- }
- else
- RSurfShader_Wall_Pass_BaseVertex(ent, surf);
- }
- for (surf = firstsurf;surf;surf = surf->chain)
- if (surf->currenttexture->glowtexture)
- if (surf->currenttexture->fogtexture == NULL)
- RSurfShader_Wall_Pass_Glow(ent, surf);
+ // opaque vertex shaded from lightmap
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
+ RSurfShader_Wall_Pass_BaseVertex(ent, surf);
+ if (texture->glowtexture)
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
+ RSurfShader_Wall_Pass_Glow(ent, surf);
if (fogenabled)
- for (surf = firstsurf;surf;surf = surf->chain)
- if (surf->currenttexture->fogtexture == NULL)
- RSurfShader_Wall_Pass_Fog(ent, surf);
- }
-}
-
-static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const msurface_t *firstsurf)
-{
- const msurface_t *surf;
- vec3_t center;
- if (ent->alpha < 1 || ent->effects & EF_ADDITIVE)
- {
- for (surf = firstsurf;surf;surf = surf->chain)
- {
- Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
- R_MeshQueue_AddTransparent(center, RSurfShader_Wall_Vertex_Callback, ent, surf - ent->model->surfaces);
- }
- }
- else if (r_vertexsurfaces.integer || ent->alpha < 1 || ent->effects & EF_ADDITIVE)
- {
- for (surf = firstsurf;surf;surf = surf->chain)
- {
- if (surf->currenttexture->fogtexture != NULL)
- {
- Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
- R_MeshQueue_AddTransparent(center, RSurfShader_Wall_Vertex_Callback, ent, surf - ent->model->surfaces);
- }
- else
- RSurfShader_Wall_Pass_BaseVertex(ent, surf);
- }
- for (surf = firstsurf;surf;surf = surf->chain)
- if (surf->currenttexture->glowtexture)
- if (surf->currenttexture->fogtexture == NULL)
- RSurfShader_Wall_Pass_Glow(ent, surf);
- if (fogenabled)
- for (surf = firstsurf;surf;surf = surf->chain)
- if (surf->currenttexture->fogtexture == NULL)
- RSurfShader_Wall_Pass_Fog(ent, surf);
+ for (surf = texture->surfacechain;surf;surf = surf->texturechain)
+ RSurfShader_Wall_Pass_Fog(ent, surf);
}
else
{
+ // opaque lightmapped
if (r_textureunits.integer >= 2)
{
if (r_textureunits.integer >= 3 && gl_combine.integer && r_detailtextures.integer)
- {
- for (surf = firstsurf;surf;surf = surf->chain)
- {
- if (surf->currenttexture->fogtexture != NULL)
- {
- Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
- R_MeshQueue_AddTransparent(center, RSurfShader_Wall_Vertex_Callback, ent, surf - ent->model->surfaces);
- }
- else
- RSurfShader_OpaqueWall_Pass_TripleTexCombine(ent, surf);
- }
- }
+ RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(ent, texture);
else
{
- for (surf = firstsurf;surf;surf = surf->chain)
- {
- if (surf->currenttexture->fogtexture != NULL)
- {
- Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
- R_MeshQueue_AddTransparent(center, RSurfShader_Wall_Vertex_Callback, ent, surf - ent->model->surfaces);
- }
- else
- RSurfShader_OpaqueWall_Pass_BaseMTex(ent, surf);
- }
+ RSurfShader_OpaqueWall_Pass_BaseDoubleTex(ent, texture);
if (r_detailtextures.integer)
- for (surf = firstsurf;surf;surf = surf->chain)
- if (surf->currenttexture->fogtexture == NULL)
- RSurfShader_OpaqueWall_Pass_BaseDetail(ent, surf);
+ RSurfShader_OpaqueWall_Pass_BaseDetail(ent, texture);
}
}
else
{
- for (surf = firstsurf;surf;surf = surf->chain)
- {
- if (surf->currenttexture->fogtexture != NULL)
- {
- Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
- R_MeshQueue_AddTransparent(center, RSurfShader_Wall_Vertex_Callback, ent, surf - ent->model->surfaces);
- }
- else
- RSurfShader_OpaqueWall_Pass_BaseTexture(ent, surf);
- }
- for (surf = firstsurf;surf;surf = surf->chain)
- if (surf->currenttexture->fogtexture == NULL)
- RSurfShader_OpaqueWall_Pass_BaseLightmap(ent, surf);
+ RSurfShader_OpaqueWall_Pass_BaseTexture(ent, texture);
+ RSurfShader_OpaqueWall_Pass_BaseLightmap(ent, texture);
if (r_detailtextures.integer)
- for (surf = firstsurf;surf;surf = surf->chain)
- if (surf->currenttexture->fogtexture == NULL)
- RSurfShader_OpaqueWall_Pass_BaseDetail(ent, surf);
+ RSurfShader_OpaqueWall_Pass_BaseDetail(ent, texture);
}
- if (!r_dlightmap.integer)
- for (surf = firstsurf;surf;surf = surf->chain)
- if (surf->dlightframe == r_framecount)
- if (surf->currenttexture->fogtexture == NULL)
- RSurfShader_OpaqueWall_Pass_Light(ent, surf);
- for (surf = firstsurf;surf;surf = surf->chain)
- if (surf->currenttexture->glowtexture)
- if (surf->currenttexture->fogtexture == NULL)
- RSurfShader_OpaqueWall_Pass_Glow(ent, surf);
+ if (!r_dlightmap.integer && !(ent->effects & EF_FULLBRIGHT))
+ RSurfShader_OpaqueWall_Pass_Light(ent, texture);
+ if (texture->glowtexture)
+ RSurfShader_OpaqueWall_Pass_Glow(ent, texture);
if (fogenabled)
- for (surf = firstsurf;surf;surf = surf->chain)
- if (surf->currenttexture->fogtexture == NULL)
- RSurfShader_OpaqueWall_Pass_Fog(ent, surf);
+ RSurfShader_OpaqueWall_Pass_Fog(ent, texture);
}
}
-Cshader_t Cshader_wall_vertex = {{NULL, RSurfShader_Wall_Vertex}, NULL};
-Cshader_t Cshader_wall_lightmap = {{NULL, RSurfShader_Wall_Lightmap}, NULL};
-Cshader_t Cshader_wall_fullbright = {{NULL, RSurfShader_Wall_Fullbright}, NULL};
-Cshader_t Cshader_water = {{NULL, RSurfShader_Water}, NULL};
-Cshader_t Cshader_sky = {{RSurfShader_Sky, NULL}, NULL};
+Cshader_t Cshader_wall_lightmap = {{NULL, RSurfShader_Wall_Lightmap}, SHADERFLAGS_NEEDLIGHTMAP};
+Cshader_t Cshader_wall_fullbright = {{NULL, RSurfShader_Wall_Fullbright}, 0};
+Cshader_t Cshader_water = {{NULL, RSurfShader_Water}, 0};
+Cshader_t Cshader_sky = {{RSurfShader_Sky, NULL}, 0};
-int Cshader_count = 5;
-Cshader_t *Cshaders[5] =
+int Cshader_count = 4;
+Cshader_t *Cshaders[4] =
{
- &Cshader_wall_vertex,
&Cshader_wall_lightmap,
&Cshader_wall_fullbright,
&Cshader_water,
void R_DrawSurfaces(entity_render_t *ent, int sky, int normal)
{
- int i, alttextures, texframe, framecount;
- texture_t *t;
+ int i, alttextures, texframe, framecount, numtextures, numsurfaces;
+ texture_t *t, *textures;
model_t *model;
- msurface_t *surf;
+ msurface_t *surf, *surfaces;
vec3_t modelorg;
- Cshader_t *shader;
if (!ent->model)
return;
R_Mesh_Matrix(&ent->matrix);
- for (i = 0;i < Cshader_count;i++)
- Cshaders[i]->chain = NULL;
-
model = ent->model;
alttextures = ent->frame != 0;
texframe = (int)(cl.time * 5.0f);
Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
- for (i = 0;i < model->nummodelsurfaces;i++)
+
+ textures = model->textures;
+ numtextures = model->numtextures;
+ surfaces = model->surfaces + model->firstmodelsurface;
+ numsurfaces = model->nummodelsurfaces;
+
+ for (i = 0;i < numtextures;i++)
+ textures[i].surfacechain = NULL;
+
+ for (i = 0, surf = surfaces;i < numsurfaces;i++, surf++)
{
- surf = model->surfaces + i + model->firstmodelsurface;
if (surf->visframe == r_framecount)
{
// mark any backface surfaces as not visible
{
framecount = t->anim_total[alttextures];
if (framecount >= 2)
- surf->currenttexture = t->anim_frames[alttextures][texframe % framecount];
+ t = t->anim_frames[alttextures][texframe % framecount];
else
- surf->currenttexture = t->anim_frames[alttextures][0];
+ t = t->anim_frames[alttextures][0];
}
- else
- surf->currenttexture = t;
- surf->chain = surf->shader->chain;
- surf->shader->chain = surf;
+ surf->currenttexture = t;
+ surf->texturechain = t->surfacechain;
+ t->surfacechain = surf;
}
}
}
}
if (sky)
- {
- for (i = 0;i < Cshader_count;i++)
- {
- shader = Cshaders[i];
- if (shader->chain && shader->shaderfunc[SHADERSTAGE_SKY])
- shader->shaderfunc[SHADERSTAGE_SKY](ent, shader->chain);
- }
- }
+ for (i = 0, t = textures;i < numtextures;i++, t++)
+ if (t->surfacechain && t->shader->shaderfunc[SHADERSTAGE_SKY])
+ t->shader->shaderfunc[SHADERSTAGE_SKY](ent, t);
if (normal)
{
if (!r_vertexsurfaces.integer)
{
- for (i = 0, surf = ent->model->surfaces + ent->model->firstmodelsurface;i < ent->model->nummodelsurfaces;i++, surf++)
+ for (i = 0, surf = surfaces;i < numsurfaces;i++, surf++)
{
if (surf->visframe == r_framecount && surf->lightmaptexture != NULL)
{
if (surf->cached_dlight
- || surf->cached_ambient != r_ambient.value
- || surf->cached_lightscalebit != lightscalebit)
+ || surf->cached_ambient != r_ambient.value
+ || surf->cached_lightscalebit != lightscalebit)
R_BuildLightMap(ent, surf, false); // base lighting changed
else if (r_dynamic.integer)
{
if (surf->styles[0] != 255 && (d_lightstylevalue[surf->styles[0]] != surf->cached_light[0]
- || (surf->styles[1] != 255 && (d_lightstylevalue[surf->styles[1]] != surf->cached_light[1]
- || (surf->styles[2] != 255 && (d_lightstylevalue[surf->styles[2]] != surf->cached_light[2]
- || (surf->styles[3] != 255 && (d_lightstylevalue[surf->styles[3]] != surf->cached_light[3]))))))))
+ || (surf->styles[1] != 255 && (d_lightstylevalue[surf->styles[1]] != surf->cached_light[1]
+ || (surf->styles[2] != 255 && (d_lightstylevalue[surf->styles[2]] != surf->cached_light[2]
+ || (surf->styles[3] != 255 && (d_lightstylevalue[surf->styles[3]] != surf->cached_light[3]))))))))
R_BuildLightMap(ent, surf, false); // base lighting changed
else if (surf->dlightframe == r_framecount && r_dlightmap.integer)
R_BuildLightMap(ent, surf, true); // only dlights
}
}
- for (i = 0;i < Cshader_count;i++)
- {
- shader = Cshaders[i];
- if (shader->chain && shader->shaderfunc[SHADERSTAGE_NORMAL])
- shader->shaderfunc[SHADERSTAGE_NORMAL](ent, shader->chain);
- }
+ for (i = 0, t = textures;i < numtextures;i++, t++)
+ if (t->surfacechain && t->shader->shaderfunc[SHADERSTAGE_NORMAL])
+ t->shader->shaderfunc[SHADERSTAGE_NORMAL](ent, t);
}
}
cvar_t r_novis = {0, "r_novis", "0"};
cvar_t r_miplightmaps = {CVAR_SAVE, "r_miplightmaps", "0"};
cvar_t r_lightmaprgba = {0, "r_lightmaprgba", "1"};
-cvar_t r_vertexsurfacesthreshold = {CVAR_SAVE, "r_vertexsurfacesthreshold", "0"};
cvar_t r_nosurftextures = {0, "r_nosurftextures", "0"};
cvar_t r_sortsurfaces = {0, "r_sortsurfaces", "0"};
Cvar_RegisterVariable(&r_novis);
Cvar_RegisterVariable(&r_miplightmaps);
Cvar_RegisterVariable(&r_lightmaprgba);
- Cvar_RegisterVariable(&r_vertexsurfacesthreshold);
Cvar_RegisterVariable(&r_nosurftextures);
Cvar_RegisterVariable(&r_sortsurfaces);
memset(mod_novis, 0xff, sizeof(mod_novis));
// add two slots for notexture walls and notexture liquids
loadmodel->numtextures = m->nummiptex + 2;
- loadmodel->textures = Mem_Alloc(loadmodel->mempool, loadmodel->numtextures * sizeof(*loadmodel->textures));
+ loadmodel->textures = Mem_Alloc(loadmodel->mempool, loadmodel->numtextures * sizeof(texture_t));
// fill out all slots with notexture
- for (i = 0;i < loadmodel->numtextures;i++)
+ for (i = 0, tx = loadmodel->textures;i < loadmodel->numtextures;i++, tx++)
{
- loadmodel->textures[i] = tx = Mem_Alloc(loadmodel->mempool, sizeof(texture_t));
tx->width = 16;
tx->height = 16;
tx->texture = r_notexture;
+ tx->shader = &Cshader_wall_lightmap;
if (i == loadmodel->numtextures - 1)
- tx->flags = SURF_DRAWTURB | SURF_DRAWFULLBRIGHT | SURF_DRAWNOALPHA | SURF_CLIPSOLID;
+ {
+ tx->flags = SURF_DRAWTURB | SURF_LIGHTBOTHSIDES;
+ tx->shader = &Cshader_water;
+ }
}
// just to work around bounds checking when debugging with it (array index out of bounds error thing)
if (name[j] >= 'A' && name[j] <= 'Z')
name[j] += 'a' - 'A';
- tx = loadmodel->textures[i];
+ tx = loadmodel->textures + i;
strcpy(tx->name, name);
tx->width = mtwidth;
tx->height = mtheight;
- tx->texture = NULL;
- tx->glowtexture = NULL;
- tx->fogtexture = NULL;
if (!tx->name[0])
{
if (tx->name[0] == '*')
{
- tx->flags |= (SURF_DRAWTURB | SURF_LIGHTBOTHSIDES);
+ tx->flags |= SURF_DRAWTURB | SURF_LIGHTBOTHSIDES;
// LordHavoc: some turbulent textures should be fullbright and solid
if (!strncmp(tx->name,"*lava",5)
|| !strncmp(tx->name,"*teleport",9)
|| !strncmp(tx->name,"*rift",5)) // Scourge of Armagon texture
- tx->flags |= (SURF_DRAWFULLBRIGHT | SURF_DRAWNOALPHA | SURF_CLIPSOLID);
+ tx->flags |= SURF_DRAWFULLBRIGHT | SURF_DRAWNOALPHA;
+ tx->shader = &Cshader_water;
}
else if (tx->name[0] == 's' && tx->name[1] == 'k' && tx->name[2] == 'y')
- tx->flags |= (SURF_DRAWSKY | SURF_CLIPSOLID);
+ {
+ tx->flags |= SURF_DRAWSKY;
+ tx->shader = &Cshader_sky;
+ }
else
{
tx->flags |= SURF_LIGHTMAP;
- if (!R_TextureHasAlpha(tx->texture))
- tx->flags |= SURF_CLIPSOLID;
+ tx->shader = &Cshader_wall_lightmap;
}
tx->detailtexture = detailtextures[i % NUM_DETAILTEXTURES];
// sequence the animations
for (i = 0;i < m->nummiptex;i++)
{
- tx = loadmodel->textures[i];
+ tx = loadmodel->textures + i;
if (!tx || tx->name[0] != '+' || tx->name[1] == 0 || tx->name[2] == 0)
continue;
if (tx->anim_total[0] || tx->anim_total[1])
for (j = i;j < m->nummiptex;j++)
{
- tx2 = loadmodel->textures[j];
+ tx2 = loadmodel->textures + j;
if (!tx2 || tx2->name[0] != '+' || strcmp (tx2->name+2, tx->name+2))
continue;
if ((unsigned int) miptex >= (unsigned int) loadmodel->numtextures)
Con_Printf ("error in model \"%s\": invalid miptex index %i (of %i)\n", loadmodel->name, miptex, loadmodel->numtextures);
else
- out->texture = loadmodel->textures[miptex];
+ out->texture = loadmodel->textures + miptex;
}
- if (out->texture == NULL)
+ if (out->flags & TEX_SPECIAL)
{
- // choose either the liquid notexture, or the normal notexture
- if (out->flags & TEX_SPECIAL)
- out->texture = loadmodel->textures[loadmodel->numtextures - 1];
- else
- out->texture = loadmodel->textures[loadmodel->numtextures - 2];
+ // if texture chosen is NULL or the shader needs a lightmap,
+ // force to notexture water shader
+ if (out->texture == NULL || out->texture->shader->flags & SHADERFLAGS_NEEDLIGHTMAP)
+ out->texture = loadmodel->textures + (loadmodel->numtextures - 1);
+ }
+ else
+ {
+ // if texture chosen is NULL, force to notexture
+ if (out->texture == NULL)
+ out->texture = loadmodel->textures + (loadmodel->numtextures - 2);
}
}
}
{
s = DotProduct (in, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3];
t = DotProduct (in, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3];
- u = (s + 8 - surf->texturemins[0]) * (1.0 / 16.0) * uscale + ubase;
- v = (t + 8 - surf->texturemins[1]) * (1.0 / 16.0) * vscale + vbase;
+ u = (s + 8 - surf->texturemins[0]) * (1.0 / 16.0);
+ v = (t + 8 - surf->texturemins[1]) * (1.0 / 16.0);
// LordHavoc: calc lightmap data offset for vertex lighting to use
iu = (int) u;
iv = (int) v;
iu = bound(0, iu, smax);
iv = bound(0, iv, tmax);
+ u = u * uscale + ubase;
+ v = v * vscale + vbase;
mesh->verts[i * 4 + 0] = in[0];
mesh->verts[i * 4 + 1] = in[1];
out->samples = loadmodel->lightdata + (i * 3);
Mod_GenerateSurfacePolygon(out);
-
- if (out->texinfo->texture->flags & SURF_DRAWSKY)
+ if (out->texinfo->texture->shader == &Cshader_wall_lightmap)
{
- out->shader = &Cshader_sky;
- out->samples = NULL;
- Mod_GenerateVertexMesh (out);
- }
- else if (out->texinfo->texture->flags & SURF_DRAWTURB)
- {
- out->shader = &Cshader_water;
- out->samples = NULL;
- Mod_GenerateVertexMesh (out);
+ if ((out->extents[0] >> 4) + 1 > (256) || (out->extents[1] >> 4) + 1 > (256))
+ Host_Error ("Bad surface extents");
+ Mod_GenerateWallMesh (out, false);
+ // stainmap for permanent marks on walls
+ out->stainsamples = Mem_Alloc(loadmodel->mempool, ssize * tsize * 3);
+ // clear to white
+ memset(out->stainsamples, 255, ssize * tsize * 3);
}
else
- {
- if (!R_TextureHasAlpha(out->texinfo->texture->texture))
- out->flags |= SURF_CLIPSOLID;
- if (out->texinfo->flags & TEX_SPECIAL)
- {
- // qbsp couldn't find the texture for this surface, but it was either turb or sky... assume turb
- out->shader = &Cshader_water;
- out->shader = &Cshader_water;
- out->samples = NULL;
- Mod_GenerateVertexMesh (out);
- }
- else if ((out->extents[0] >> 4) + 1 > (256) || (out->extents[1] >> 4) + 1 > (256))
- {
- Con_Printf ("Bad surface extents, converting to fullbright polygon");
- out->shader = &Cshader_wall_fullbright;
- out->samples = NULL;
- Mod_GenerateVertexMesh(out);
- }
- else
- {
- // stainmap for permanent marks on walls
- out->stainsamples = Mem_Alloc(loadmodel->mempool, ssize * tsize * 3);
- // clear to white
- memset(out->stainsamples, 255, ssize * tsize * 3);
- if (out->extents[0] < r_vertexsurfacesthreshold.integer && out->extents[1] < r_vertexsurfacesthreshold.integer)
- {
- out->shader = &Cshader_wall_vertex;
- Mod_GenerateWallMesh (out, true);
- }
- else
- {
- out->shader = &Cshader_wall_lightmap;
- Mod_GenerateWallMesh (out, false);
- }
- }
- }
+ Mod_GenerateVertexMesh (out);
}
}
for (j = 0, surf = &mod->surfaces[mod->firstmodelsurface];j < mod->nummodelsurfaces;j++, surf++)
{
// we only need to have a drawsky function if it is used (usually only on world model)
- if (surf->shader == &Cshader_sky)
+ if (surf->texinfo->texture->shader == &Cshader_sky)
mod->DrawSky = R_DrawBrushModelSky;
for (k = 0;k < surf->numedges;k++)
{