- if (rendertype == SURFRENDER_ADD)
- {
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- GL_DepthMask(false);
- }
- else if (rendertype == SURFRENDER_ALPHA)
- {
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- GL_DepthMask(false);
- }
- else
- {
- GL_BlendFunc(GL_ONE, GL_ZERO);
- GL_DepthMask(true);
- }
- m.tex[0] = R_GetTexture(texture->skin.base);
- colorscale = 1;
- if (gl_combine.integer)
- {
- m.texrgbscale[0] = 4;
- colorscale *= 0.25f;
- }
- base = ent->effects & EF_FULLBRIGHT ? 2.0f : r_ambient.value * (1.0f / 64.0f);
- GL_DepthTest(true);
- GL_ColorPointer(varray_color4f);
-
- GL_VertexPointer(surf->mesh.data_vertex3f);
- m.pointer_texcoord[0] = surf->mesh.data_texcoordtexture2f;
- R_Mesh_State_Texture(&m);
- R_FillColors(varray_color4f, surf->mesh.num_vertices, base, base, base, currentalpha);
- if (!(ent->effects & EF_FULLBRIGHT))
- {
- if (surf->dlightframe == r_framecount)
- RSurf_LightSeparate_Vertex3f_Color4f(&ent->inversematrix, surf->dlightbits, surf->mesh.num_vertices, surf->mesh.data_vertex3f, varray_color4f, 1);
- if (surf->flags & SURF_LIGHTMAP)
- RSurf_AddLightmapToVertexColors_Color4f(surf->mesh.data_lightmapoffsets, varray_color4f,surf->mesh.num_vertices, surf->samples, ((surf->extents[0]>>4)+1)*((surf->extents[1]>>4)+1)*3, surf->styles);
- }
- RSurf_FogColors_Vertex3f_Color4f(surf->mesh.data_vertex3f, varray_color4f, colorscale, surf->mesh.num_vertices, modelorg);
- R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i);
-}
-
-static void RSurfShader_Wall_Pass_Glow(const entity_render_t *ent, const msurface_t *surf, const texture_t *texture, int rendertype, float currentalpha)
-{
- rmeshstate_t m;
- float modelorg[3];
- Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
- memset(&m, 0, sizeof(m));
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- GL_DepthMask(false);
- GL_DepthTest(true);
- m.tex[0] = R_GetTexture(texture->skin.glow);
- GL_ColorPointer(varray_color4f);
-
- GL_VertexPointer(surf->mesh.data_vertex3f);
- if (m.tex[0])
- m.pointer_texcoord[0] = surf->mesh.data_texcoordtexture2f;
- R_Mesh_State_Texture(&m);
- RSurf_FoggedColors_Vertex3f_Color4f(surf->mesh.data_vertex3f, varray_color4f, 1, 1, 1, currentalpha, 1, surf->mesh.num_vertices, modelorg);
- R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i);
-}
-
-static void RSurfShader_Wall_Pass_Fog(const entity_render_t *ent, const msurface_t *surf, const texture_t *texture, int rendertype, float currentalpha)
-{
- rmeshstate_t m;
- float modelorg[3];
- Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
- memset(&m, 0, sizeof(m));
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- GL_DepthMask(false);
- GL_DepthTest(true);
- m.tex[0] = R_GetTexture(texture->skin.fog);
- GL_ColorPointer(varray_color4f);
-
- GL_VertexPointer(surf->mesh.data_vertex3f);
- if (m.tex[0])
- m.pointer_texcoord[0] = surf->mesh.data_texcoordtexture2f;
- R_Mesh_State_Texture(&m);
- RSurf_FogPassColors_Vertex3f_Color4f(surf->mesh.data_vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], currentalpha, 1, surf->mesh.num_vertices, modelorg);
- R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i);
-}
-
-static void RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
-{
- const msurface_t *surf;
- rmeshstate_t m;
- int lightmaptexturenum;
- memset(&m, 0, sizeof(m));
- GL_BlendFunc(GL_ONE, GL_ZERO);
- GL_DepthMask(true);
- GL_DepthTest(true);
- m.tex[0] = R_GetTexture(texture->skin.base);
- m.tex[1] = R_GetTexture((**surfchain).lightmaptexture);
- m.texrgbscale[1] = 2;
- m.tex[2] = R_GetTexture(texture->skin.detail);
- m.texrgbscale[2] = 2;
- GL_Color(1, 1, 1, 1);
-
- while((surf = *surfchain++) != NULL)
- {
- if (surf->visframe == r_framecount)
- {
- lightmaptexturenum = R_GetTexture(surf->lightmaptexture);
- //if (m.tex[1] != lightmaptexturenum)
- //{
- m.tex[1] = lightmaptexturenum;
- // R_Mesh_State_Texture(&m);
- //}
- GL_VertexPointer(surf->mesh.data_vertex3f);
- m.pointer_texcoord[0] = surf->mesh.data_texcoordtexture2f;
- m.pointer_texcoord[1] = surf->mesh.data_texcoordlightmap2f;
- m.pointer_texcoord[2] = surf->mesh.data_texcoorddetail2f;
- R_Mesh_State_Texture(&m);
- R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i);
- }
- }
-}
-
-static void RSurfShader_OpaqueWall_Pass_BaseDoubleTexCombine(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
-{
- const msurface_t *surf;
- rmeshstate_t m;
- int lightmaptexturenum;
- memset(&m, 0, sizeof(m));
- GL_BlendFunc(GL_ONE, GL_ZERO);
- GL_DepthMask(true);
- GL_DepthTest(true);
- m.tex[0] = R_GetTexture(texture->skin.base);
- m.tex[1] = R_GetTexture((**surfchain).lightmaptexture);
- m.texrgbscale[1] = 2;
- GL_Color(1, 1, 1, 1);
- while((surf = *surfchain++) != NULL)
- {
- if (surf->visframe == r_framecount)
- {
- lightmaptexturenum = R_GetTexture(surf->lightmaptexture);
- //if (m.tex[1] != lightmaptexturenum)
- //{
- m.tex[1] = lightmaptexturenum;
- // R_Mesh_State_Texture(&m);
- //}
- GL_VertexPointer(surf->mesh.data_vertex3f);
- m.pointer_texcoord[0] = surf->mesh.data_texcoordtexture2f;
- m.pointer_texcoord[1] = surf->mesh.data_texcoordlightmap2f;
- R_Mesh_State_Texture(&m);
- R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i);
- }
- }
-}
-
-static void RSurfShader_OpaqueWall_Pass_BaseTexture(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
-{
- const msurface_t *surf;
- rmeshstate_t m;
- memset(&m, 0, sizeof(m));
- GL_DepthMask(true);
- GL_DepthTest(true);
- GL_BlendFunc(GL_ONE, GL_ZERO);
- m.tex[0] = R_GetTexture(texture->skin.base);
- GL_Color(1, 1, 1, 1);
- while((surf = *surfchain++) != NULL)
- {
- if (surf->visframe == r_framecount)
- {
- GL_VertexPointer(surf->mesh.data_vertex3f);
- m.pointer_texcoord[0] = surf->mesh.data_texcoordtexture2f;
- R_Mesh_State_Texture(&m);
- R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i);
- }
- }
-}
-
-static void RSurfShader_OpaqueWall_Pass_BaseLightmap(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
-{
- const msurface_t *surf;
- rmeshstate_t m;
- int lightmaptexturenum;
- memset(&m, 0, sizeof(m));
- GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
- GL_DepthMask(false);
- GL_DepthTest(true);
- m.tex[0] = R_GetTexture((**surfchain).lightmaptexture);
- GL_Color(1, 1, 1, 1);
- while((surf = *surfchain++) != NULL)
- {
- if (surf->visframe == r_framecount)
- {
- lightmaptexturenum = R_GetTexture(surf->lightmaptexture);
- //if (m.tex[0] != lightmaptexturenum)
- //{
- m.tex[0] = lightmaptexturenum;
- // R_Mesh_State_Texture(&m);
- //}
- GL_VertexPointer(surf->mesh.data_vertex3f);
- m.pointer_texcoord[0] = surf->mesh.data_texcoordlightmap2f;
- R_Mesh_State_Texture(&m);
- R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i);
- }
- }
-}
-
-static void RSurfShader_OpaqueWall_Pass_Fog(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
-{
- const msurface_t *surf;
- rmeshstate_t m;
- float modelorg[3];
- Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
- memset(&m, 0, sizeof(m));
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- GL_DepthMask(false);
- GL_DepthTest(true);
- GL_ColorPointer(varray_color4f);
- while((surf = *surfchain++) != NULL)
- {
- if (surf->visframe == r_framecount)
- {
- GL_VertexPointer(surf->mesh.data_vertex3f);
- if (m.tex[0])
- m.pointer_texcoord[0] = surf->mesh.data_texcoordtexture2f;
- R_Mesh_State_Texture(&m);
- RSurf_FogPassColors_Vertex3f_Color4f(surf->mesh.data_vertex3f, varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], 1, 1, surf->mesh.num_vertices, modelorg);
- R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i);
- }
- }
-}
-
-static void RSurfShader_OpaqueWall_Pass_BaseDetail(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
-{
- const msurface_t *surf;
- rmeshstate_t m;
- memset(&m, 0, sizeof(m));
- GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
- GL_DepthMask(false);
- GL_DepthTest(true);
- m.tex[0] = R_GetTexture(texture->skin.detail);
- GL_Color(1, 1, 1, 1);
- while((surf = *surfchain++) != NULL)
- {
- if (surf->visframe == r_framecount)
- {
- GL_VertexPointer(surf->mesh.data_vertex3f);
- m.pointer_texcoord[0] = surf->mesh.data_texcoorddetail2f;
- R_Mesh_State_Texture(&m);
- R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i);
- }
- }
-}
-
-static void RSurfShader_OpaqueWall_Pass_Glow(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
-{
- const msurface_t *surf;
- rmeshstate_t m;
- memset(&m, 0, sizeof(m));
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- GL_DepthMask(false);
- GL_DepthTest(true);
- m.tex[0] = R_GetTexture(texture->skin.glow);
- GL_Color(1, 1, 1, 1);
- while((surf = *surfchain++) != NULL)
- {
- if (surf->visframe == r_framecount)
- {
- GL_VertexPointer(surf->mesh.data_vertex3f);
- m.pointer_texcoord[0] = surf->mesh.data_texcoordtexture2f;
- R_Mesh_State_Texture(&m);
- R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i);
- }
- }
-}
-
-static void RSurfShader_OpaqueWall_Pass_OpaqueGlow(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
-{
- const msurface_t *surf;
- rmeshstate_t m;
- memset(&m, 0, sizeof(m));
- GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
- GL_DepthMask(true);
- m.tex[0] = R_GetTexture(texture->skin.glow);
- if (m.tex[0])
- GL_Color(1, 1, 1, 1);
- else
- GL_Color(0, 0, 0, 1);
- while((surf = *surfchain++) != NULL)
- {
- if (surf->visframe == r_framecount)
- {
- GL_VertexPointer(surf->mesh.data_vertex3f);
- m.pointer_texcoord[0] = surf->mesh.data_texcoordtexture2f;
- R_Mesh_State_Texture(&m);
- R_Mesh_Draw(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i);
- }
- }
-}
-
-static void RSurfShader_Wall_Vertex_Callback(const void *calldata1, int calldata2)
-{
- const entity_render_t *ent = calldata1;
- const msurface_t *surf = ent->model->brushq1.surfaces + calldata2;
- int rendertype;
- float currentalpha;
- texture_t *texture;
- R_Mesh_Matrix(&ent->matrix);
-
- texture = surf->texinfo->texture;
- if (texture->animated)
- texture = texture->anim_frames[ent->frame != 0][(texture->anim_total[ent->frame != 0] >= 2) ? ((int) (cl.time * 5.0f) % texture->anim_total[ent->frame != 0]) : 0];
-
- currentalpha = ent->alpha;
- if (ent->effects & EF_ADDITIVE)
- rendertype = SURFRENDER_ADD;
- else if (currentalpha < 1 || texture->skin.fog != NULL)
- rendertype = SURFRENDER_ALPHA;
- else
- rendertype = SURFRENDER_OPAQUE;
-
- RSurfShader_Wall_Pass_BaseVertex(ent, surf, texture, rendertype, currentalpha);
- if (texture->skin.glow)
- RSurfShader_Wall_Pass_Glow(ent, surf, texture, rendertype, currentalpha);
- if (fogenabled)
- RSurfShader_Wall_Pass_Fog(ent, surf, texture, rendertype, currentalpha);
-}
-
-static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const texture_t *texture, msurface_t **surfchain)
-{
- const msurface_t *surf;
- msurface_t **chain;
- vec3_t center;
- if (texture->rendertype != SURFRENDER_OPAQUE)
- {
- // transparent vertex shaded from lightmap
- for (chain = surfchain;(surf = *chain) != NULL;chain++)
- {
- if (surf->visframe == r_framecount)
- {
- Matrix4x4_Transform(&ent->matrix, surf->poly_center, center);
- R_MeshQueue_AddTransparent(center, RSurfShader_Wall_Vertex_Callback, ent, surf - ent->model->brushq1.surfaces);
- }
- }
- }
- else if (r_shadow_realtime_world.integer)
- {
- // opaque base lighting
- RSurfShader_OpaqueWall_Pass_OpaqueGlow(ent, texture, surfchain);
- if (fogenabled)
- RSurfShader_OpaqueWall_Pass_Fog(ent, texture, surfchain);
- }
- else
- {
- // opaque lightmapped
- if (r_textureunits.integer >= 3 && gl_combine.integer && r_detailtextures.integer)
- {
- RSurfShader_OpaqueWall_Pass_BaseTripleTexCombine(ent, texture, surfchain);
- if (texture->skin.glow)
- RSurfShader_OpaqueWall_Pass_Glow(ent, texture, surfchain);
- if (fogenabled)
- RSurfShader_OpaqueWall_Pass_Fog(ent, texture, surfchain);
- }
- else if (r_textureunits.integer >= 2 && gl_combine.integer)
- {
- RSurfShader_OpaqueWall_Pass_BaseDoubleTexCombine(ent, texture, surfchain);
- if (r_detailtextures.integer)
- RSurfShader_OpaqueWall_Pass_BaseDetail(ent, texture, surfchain);
- if (texture->skin.glow)
- RSurfShader_OpaqueWall_Pass_Glow(ent, texture, surfchain);
- if (fogenabled)
- RSurfShader_OpaqueWall_Pass_Fog(ent, texture, surfchain);
- }
- else
- {
- RSurfShader_OpaqueWall_Pass_BaseTexture(ent, texture, surfchain);
- RSurfShader_OpaqueWall_Pass_BaseLightmap(ent, texture, surfchain);
- if (r_detailtextures.integer)
- RSurfShader_OpaqueWall_Pass_BaseDetail(ent, texture, surfchain);
- if (texture->skin.glow)
- RSurfShader_OpaqueWall_Pass_Glow(ent, texture, surfchain);
- if (fogenabled)
- RSurfShader_OpaqueWall_Pass_Fog(ent, texture, surfchain);
- }
- }
-}
-
-Cshader_t Cshader_wall_lightmap = {{NULL, RSurfShader_Wall_Lightmap}, SHADERFLAGS_NEEDLIGHTMAP};
-Cshader_t Cshader_water = {{NULL, RSurfShader_Water}, 0};
-Cshader_t Cshader_sky = {{RSurfShader_Sky, NULL}, 0};
-
-int Cshader_count = 3;
-Cshader_t *Cshaders[3] =
-{
- &Cshader_wall_lightmap,
- &Cshader_water,
- &Cshader_sky
-};
-
-void R_UpdateTextureInfo(entity_render_t *ent)
-{
- int i, texframe, alttextures;
- texture_t *t;
-
- if (!ent->model)
- return;
-
- alttextures = ent->frame != 0;
- texframe = (int)(cl.time * 5.0f);
- for (i = 0;i < ent->model->brushq1.numtextures;i++)
- {
- t = ent->model->brushq1.textures + i;
- t->currentalpha = ent->alpha;
- if (t->flags & SURF_WATERALPHA)
- t->currentalpha *= r_wateralpha.value;
- if (ent->effects & EF_ADDITIVE)
- t->rendertype = SURFRENDER_ADD;
- else if (t->currentalpha < 1 || t->skin.fog != NULL)
- t->rendertype = SURFRENDER_ALPHA;
- else
- t->rendertype = SURFRENDER_OPAQUE;
- // 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)
- t->currentframe = t->anim_frames[alttextures][(t->anim_total[alttextures] >= 2) ? (texframe % t->anim_total[alttextures]) : 0];
- }
-}
-
-void R_PrepareSurfaces(entity_render_t *ent)
-{
- int i, numsurfaces, *surfacevisframes;
- model_t *model;
- msurface_t *surf, *surfaces, **surfchain;
- vec3_t modelorg;
-
- if (!ent->model)
- return;
-
- model = ent->model;
- Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
- numsurfaces = model->brushq1.nummodelsurfaces;
- surfaces = model->brushq1.surfaces + model->brushq1.firstmodelsurface;
- surfacevisframes = model->brushq1.surfacevisframes + model->brushq1.firstmodelsurface;
-
- R_UpdateTextureInfo(ent);
-
- if (r_dynamic.integer && !r_shadow_realtime_dlight.integer)
- R_MarkLights(ent);
-
- if (model->brushq1.light_ambient != r_ambient.value)
- {
- model->brushq1.light_ambient = r_ambient.value;
- for (i = 0;i < model->brushq1.nummodelsurfaces;i++)
- model->brushq1.surfaces[i + model->brushq1.firstmodelsurface].cached_dlight = true;
- }
- else
- {
- for (i = 0;i < model->brushq1.light_styles;i++)
- {
- if (model->brushq1.light_stylevalue[i] != d_lightstylevalue[model->brushq1.light_style[i]])
- {
- model->brushq1.light_stylevalue[i] = d_lightstylevalue[model->brushq1.light_style[i]];
- for (surfchain = model->brushq1.light_styleupdatechains[i];*surfchain;surfchain++)
- (**surfchain).cached_dlight = true;
- }
- }
- }
-
- for (i = 0, surf = surfaces;i < numsurfaces;i++, surf++)
- {
- if (surfacevisframes[i] == r_framecount)
- {
-#if !WORLDNODECULLBACKFACES
- // mark any backface surfaces as not visible
- if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
- {
- if (!(surf->flags & SURF_PLANEBACK))
- surfacevisframes[i] = -1;
- }
- else
- {
- if ((surf->flags & SURF_PLANEBACK))
- surfacevisframes[i] = -1;
- }
- if (surfacevisframes[i] == r_framecount)
-#endif
- {
- c_faces++;
- surf->visframe = r_framecount;
- if (surf->cached_dlight && surf->lightmaptexture != NULL)
- R_BuildLightMap(ent, surf);
- }
- }
- }
-}
-
-void R_DrawSurfaces(entity_render_t *ent, int type, msurface_t ***chains)
-{
- int i;
- texture_t *t;
- if (ent->model == NULL)
- return;
- R_Mesh_Matrix(&ent->matrix);
- for (i = 0, t = ent->model->brushq1.textures;i < ent->model->brushq1.numtextures;i++, t++)
- if (t->shader->shaderfunc[type] && t->currentframe && chains[i] != NULL)
- t->shader->shaderfunc[type](ent, t->currentframe, chains[i]);
-}
-
-static void R_DrawPortal_Callback(const void *calldata1, int calldata2)
-{
- int i;
- float *v;
- rmeshstate_t m;
- const entity_render_t *ent = calldata1;
- const mportal_t *portal = ent->model->brushq1.portals + calldata2;
- GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- GL_DepthMask(false);
- GL_DepthTest(true);
- R_Mesh_Matrix(&ent->matrix);
- GL_VertexPointer(varray_vertex3f);
-
- memset(&m, 0, sizeof(m));
- R_Mesh_State_Texture(&m);
-
- i = portal - ent->model->brushq1.portals;
- GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f),
- ((i & 0x0038) >> 3) * (1.0f / 7.0f),
- ((i & 0x01C0) >> 6) * (1.0f / 7.0f),
- 0.125f);
- if (PlaneDiff(r_vieworigin, (&portal->plane)) < 0)