From 35acf042fb74302fcede8e3792d880f2f2732c37 Mon Sep 17 00:00:00 2001 From: havoc Date: Tue, 10 Sep 2002 17:12:15 +0000 Subject: [PATCH] surfaces are now texture sorted rather than shader sorted, OpaqueWall renderers have been reorganized to minimize state checks, which offers a minor speedup r_vertexsurfacesthreshold is gone, no longer supported... git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2348 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rsurf.c | 511 ++++++++++++++++++++++--------------------------- makefile | 8 +- model_brush.c | 118 +++++------- model_brush.h | 51 ++--- model_shared.h | 2 +- 5 files changed, 308 insertions(+), 382 deletions(-) diff --git a/gl_rsurf.c b/gl_rsurf.c index f33bd315..5f23baaa 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -784,7 +784,7 @@ static int RSurf_LightCheck(const matrix4x4_t *matrix, const int *dlightbits, co 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; @@ -819,7 +819,7 @@ static void RSurfShader_Sky(const entity_render_t *ent, const msurface_t *firsts 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) { @@ -907,20 +907,21 @@ static void RSurfShader_Water_Callback(const void *calldata1, int calldata2) } } -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) @@ -1052,141 +1053,179 @@ static void RSurfShader_Wall_Pass_Fog(const entity_render_t *ent, const msurface } } -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]; @@ -1194,60 +1233,71 @@ static void RSurfShader_OpaqueWall_Pass_Fog(const entity_render_t *ent, const ms 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); + } } } @@ -1263,13 +1313,13 @@ static void RSurfShader_Wall_Fullbright_Callback(const void *calldata1, int call 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); @@ -1277,24 +1327,14 @@ static void RSurfShader_Wall_Fullbright(const entity_render_t *ent, const msurfa } 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); } } @@ -1310,155 +1350,69 @@ static void RSurfShader_Wall_Vertex_Callback(const void *calldata1, int calldata 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, @@ -1467,29 +1421,33 @@ Cshader_t *Cshaders[5] = 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 @@ -1515,28 +1473,22 @@ void R_DrawSurfaces(entity_render_t *ent, int sky, int normal) { 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) { @@ -1545,20 +1497,20 @@ void R_DrawSurfaces(entity_render_t *ent, int sky, int 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 @@ -1567,12 +1519,9 @@ void R_DrawSurfaces(entity_render_t *ent, int sky, int normal) } } - 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); } } diff --git a/makefile b/makefile index fff672e4..ec3105c2 100644 --- a/makefile +++ b/makefile @@ -50,11 +50,11 @@ NOPROFILEOPTIMIZATIONS= #this is used to ensure that all released versions are free of warnings. #normal compile -OPTIMIZATIONS= -O6 -fno-strict-aliasing -ffast-math -funroll-loops $(NOPROFILEOPTIMIZATIONS) -fexpensive-optimizations $(CPUOPTIMIZATIONS) -CFLAGS= -MD -Wall -Werror -I/usr/X11R6/include $(OPTIMIZATIONS) $(PROFILEOPTION) +#OPTIMIZATIONS= -O6 -fno-strict-aliasing -ffast-math -funroll-loops $(NOPROFILEOPTIMIZATIONS) -fexpensive-optimizations $(CPUOPTIMIZATIONS) +#CFLAGS= -MD -Wall -Werror -I/usr/X11R6/include $(OPTIMIZATIONS) $(PROFILEOPTION) #debug compile -#OPTIMIZATIONS= -#CFLAGS= -MD -Wall -Werror -I/usr/X11R6/include -ggdb $(OPTIMIZATIONS) $(PROFILEOPTION) +OPTIMIZATIONS= +CFLAGS= -MD -Wall -Werror -I/usr/X11R6/include -ggdb $(OPTIMIZATIONS) $(PROFILEOPTION) LDFLAGS= -L/usr/X11R6/lib -lm -lX11 -lXext -lXxf86dga -lXxf86vm -ldl $(SOUNDLIB) $(PROFILEOPTION) diff --git a/model_brush.c b/model_brush.c index edcb6093..785ef2d0 100644 --- a/model_brush.c +++ b/model_brush.c @@ -29,7 +29,6 @@ cvar_t halflifebsp = {0, "halflifebsp", "0"}; 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"}; @@ -49,7 +48,6 @@ void Mod_BrushInit (void) 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)); @@ -227,17 +225,20 @@ static void Mod_LoadTextures (lump_t *l) // 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) @@ -278,13 +279,10 @@ static void Mod_LoadTextures (lump_t *l) 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]) { @@ -412,20 +410,23 @@ static void Mod_LoadTextures (lump_t *l) 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]; @@ -434,7 +435,7 @@ static void Mod_LoadTextures (lump_t *l) // 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]) @@ -446,7 +447,7 @@ static void Mod_LoadTextures (lump_t *l) 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; @@ -883,15 +884,20 @@ static void Mod_LoadTexinfo (lump_t *l) 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); } } } @@ -1164,13 +1170,15 @@ void Mod_GenerateWallMesh (msurface_t *surf, int vertexonly) { 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]; @@ -1328,56 +1336,18 @@ static void Mod_LoadFaces (lump_t *l) 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); } } @@ -2462,7 +2432,7 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer) 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++) { diff --git a/model_brush.h b/model_brush.h index 65f8cac4..19832c18 100644 --- a/model_brush.h +++ b/model_brush.h @@ -56,6 +56,27 @@ typedef struct mplane_s } mplane_t; +#define SHADERSTAGE_SKY 0 +#define SHADERSTAGE_NORMAL 1 +#define SHADERSTAGE_COUNT 2 + +#define SHADERFLAGS_NEEDLIGHTMAP 1 + +struct entity_render_s; +struct texture_s; +// change this stuff when real shaders are added +typedef struct Cshader_s +{ + void (*shaderfunc[SHADERSTAGE_COUNT])(const struct entity_render_s *ent, const struct texture_s *texture); + int flags; +} +Cshader_t; + +extern Cshader_t Cshader_wall_lightmap; +extern Cshader_t Cshader_wall_fullbright; +extern Cshader_t Cshader_water; +extern Cshader_t Cshader_sky; + typedef struct texture_s { // name @@ -74,6 +95,12 @@ typedef struct texture_s // detail texture (usually not used if transparent) rtexture_t *detailtexture; + // shader to use for this texture + Cshader_t *shader; + + // list of surfaces to render using this texture + struct msurface_s *surfacechain; + // total frames in sequence and alternate sequence int anim_total[2]; // direct pointers to each of the frames in the sequences @@ -138,8 +165,8 @@ typedef struct msurface_s mplane_t *plane; // SURF_ flags int flags; - struct Cshader_s *shader; - struct msurface_s *chain; // shader rendering chain + // rendering chain + struct msurface_s *texturechain; // look up in model->surfedges[], negative numbers are backwards edges int firstedge; @@ -194,26 +221,6 @@ typedef struct msurface_s } msurface_t; -#define SHADERSTAGE_SKY 0 -#define SHADERSTAGE_NORMAL 1 -#define SHADERSTAGE_COUNT 2 - -struct entity_render_s; -// change this stuff when real shaders are added -typedef struct Cshader_s -{ - void (*shaderfunc[SHADERSTAGE_COUNT])(const struct entity_render_s *ent, const msurface_t *firstsurf); - // list of surfaces using this shader (used during surface rendering) - msurface_t *chain; -} -Cshader_t; - -extern Cshader_t Cshader_wall_vertex; -extern Cshader_t Cshader_wall_lightmap; -extern Cshader_t Cshader_wall_fullbright; -extern Cshader_t Cshader_water; -extern Cshader_t Cshader_sky; - typedef struct mnode_s { // common with leaf diff --git a/model_shared.h b/model_shared.h index d35e06a5..d0280aa5 100644 --- a/model_shared.h +++ b/model_shared.h @@ -156,7 +156,7 @@ typedef struct model_s hull_t hulls[MAX_MAP_HULLS]; int numtextures; - texture_t **textures; + texture_t *textures; qbyte *visdata; qbyte *lightdata; -- 2.39.2