]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rsurf.c
added r_fullbright (and EF_FULLBRIGHT) support to q3bsp rendering
[xonotic/darkplaces.git] / gl_rsurf.c
index 3edeb3ed83029dc2a08dd50cfbb031dd8ecd8389..455f96aa9f2507d937182f39e84a86ba305e637b 100644 (file)
@@ -1661,8 +1661,13 @@ void R_DrawWorld(entity_render_t *ent)
 {
        if (ent->model == NULL)
                return;
-       if (!ent->model->brushq1.numleafs && ent->model->Draw)
-               ent->model->Draw(ent);
+       if (!ent->model->brushq1.numleafs)
+       {
+               if (ent->model->DrawSky)
+                       ent->model->DrawSky(ent);
+               if (ent->model->Draw)
+                       ent->model->Draw(ent);
+       }
        else
        {
                R_PrepareSurfaces(ent);
@@ -1723,30 +1728,6 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto
        }
 }
 
-void R_Model_Brush_DrawLightForSurfaceList(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, msurface_t **surflist, int numsurfaces, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz)
-{
-       int surfnum;
-       msurface_t *surf;
-       texture_t *t;
-       if (ent->model == NULL)
-               return;
-       R_Mesh_Matrix(&ent->matrix);
-       R_UpdateTextureInfo(ent);
-       for (surfnum = 0;surfnum < numsurfaces;surfnum++)
-       {
-               surf = surflist[surfnum];
-               if (surf->visframe == r_framecount)
-               {
-                       t = surf->texinfo->texture->currentframe;
-                       if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
-                       {
-                               R_Shadow_DiffuseLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL);
-                               R_Shadow_SpecularLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL);
-                       }
-               }
-       }
-}
-
 void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz)
 {
        int surfnum;
@@ -1792,82 +1773,210 @@ void R_DrawCollisionBrush(colbrushf_t *brush)
        R_Mesh_Draw(brush->numpoints, brush->numtriangles, brush->elements);
 }
 
-void R_Q3BSP_DrawFace(entity_render_t *ent, q3mface_t *face)
+void R_Q3BSP_DrawSkyFace(entity_render_t *ent, q3mface_t *face)
 {
        rmeshstate_t m;
        if (!face->num_triangles)
                return;
-       if (face->texture->renderflags)
+       if (skyrendernow)
        {
-               if (face->texture->renderflags & Q3MTEXTURERENDERFLAGS_SKY)
-               {
-                       if (skyrendernow)
-                       {
-                               skyrendernow = false;
-                               if (skyrendermasked)
-                                       R_Sky();
-                       }
+               skyrendernow = false;
+               if (skyrendermasked)
+                       R_Sky();
+       }
 
-                       R_Mesh_Matrix(&ent->matrix);
+       R_Mesh_Matrix(&ent->matrix);
 
-                       GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
-                       if (skyrendermasked)
-                       {
-                               // depth-only (masking)
-                               qglColorMask(0,0,0,0);
-                               // just to make sure that braindead drivers don't draw anything
-                               // despite that colormask...
-                               GL_BlendFunc(GL_ZERO, GL_ONE);
-                       }
-                       else
-                       {
-                               // fog sky
-                               GL_BlendFunc(GL_ONE, GL_ZERO);
-                       }
-                       GL_DepthMask(true);
-                       GL_DepthTest(true);
+       GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1);
+       if (skyrendermasked)
+       {
+               // depth-only (masking)
+               qglColorMask(0,0,0,0);
+               // just to make sure that braindead drivers don't draw anything
+               // despite that colormask...
+               GL_BlendFunc(GL_ZERO, GL_ONE);
+       }
+       else
+       {
+               // fog sky
+               GL_BlendFunc(GL_ONE, GL_ZERO);
+       }
+       GL_DepthMask(true);
+       GL_DepthTest(true);
 
-                       memset(&m, 0, sizeof(m));
-                       R_Mesh_State_Texture(&m);
+       memset(&m, 0, sizeof(m));
+       R_Mesh_State_Texture(&m);
 
-                       GL_VertexPointer(face->data_vertex3f);
-                       R_Mesh_Draw(face->num_vertices, face->num_triangles, face->data_element3i);
-                       qglColorMask(1,1,1,1);
-                       return;
-               }
-               if (face->texture->renderflags & Q3MTEXTURERENDERFLAGS_NODRAW)
-                       return;
+       GL_VertexPointer(face->data_vertex3f);
+       R_Mesh_Draw(face->num_vertices, face->num_triangles, face->data_element3i);
+       qglColorMask(1,1,1,1);
+}
+
+void R_Q3BSP_DrawFace_OpaqueWall_Pass_OpaqueGlow(entity_render_t *ent, q3mface_t *face)
+{
+       rmeshstate_t m;
+       memset(&m, 0, sizeof(m));
+       GL_BlendFunc(GL_ONE, GL_ZERO);
+       GL_DepthMask(true);
+       GL_DepthTest(true);
+       if (face->texture->skin.glow)
+       {
+               m.tex[0] = R_GetTexture(face->texture->skin.glow);
+               m.pointer_texcoord[0] = face->data_texcoordtexture2f;
+               GL_Color(1, 1, 1, 1);
        }
-       R_Mesh_Matrix(&ent->matrix);
-       face->visframe = r_framecount;
+       else
+               GL_Color(0, 0, 0, 1);
+       R_Mesh_State_Texture(&m);
+       GL_VertexPointer(face->data_vertex3f);
+       R_Mesh_Draw(face->num_vertices, face->num_triangles, face->data_element3i);
+}
+
+void R_Q3BSP_DrawFace_OpaqueWall_Pass_TextureLightmapCombine(entity_render_t *ent, q3mface_t *face)
+{
+       rmeshstate_t m;
+       memset(&m, 0, sizeof(m));
+       GL_BlendFunc(GL_ONE, GL_ZERO);
+       GL_DepthMask(true);
+       GL_DepthTest(true);
+       m.tex[0] = R_GetTexture(face->texture->skin.base);
+       m.pointer_texcoord[0] = face->data_texcoordtexture2f;
+       m.tex[1] = R_GetTexture(face->lightmaptexture);
+       m.pointer_texcoord[1] = face->data_texcoordlightmap2f;
+       m.texrgbscale[1] = 2;
+       GL_Color(1, 1, 1, 1);
+       R_Mesh_State_Texture(&m);
+       GL_VertexPointer(face->data_vertex3f);
+       R_Mesh_Draw(face->num_vertices, face->num_triangles, face->data_element3i);
+}
+
+void R_Q3BSP_DrawFace_OpaqueWall_Pass_Texture(entity_render_t *ent, q3mface_t *face)
+{
+       rmeshstate_t m;
        memset(&m, 0, sizeof(m));
        GL_BlendFunc(GL_ONE, GL_ZERO);
        GL_DepthMask(true);
        GL_DepthTest(true);
        m.tex[0] = R_GetTexture(face->texture->skin.base);
        m.pointer_texcoord[0] = face->data_texcoordtexture2f;
-       if (face->lightmaptexture)
+       GL_Color(1, 1, 1, 1);
+       R_Mesh_State_Texture(&m);
+       GL_VertexPointer(face->data_vertex3f);
+       R_Mesh_Draw(face->num_vertices, face->num_triangles, face->data_element3i);
+}
+
+void R_Q3BSP_DrawFace_OpaqueWall_Pass_Lightmap(entity_render_t *ent, q3mface_t *face)
+{
+       rmeshstate_t m;
+       memset(&m, 0, sizeof(m));
+       GL_BlendFunc(GL_ONE, GL_SRC_COLOR);
+       GL_DepthMask(true);
+       GL_DepthTest(true);
+       m.tex[0] = R_GetTexture(face->lightmaptexture);
+       m.pointer_texcoord[0] = face->data_texcoordlightmap2f;
+       GL_Color(1, 1, 1, 1);
+       R_Mesh_State_Texture(&m);
+       GL_VertexPointer(face->data_vertex3f);
+       R_Mesh_Draw(face->num_vertices, face->num_triangles, face->data_element3i);
+}
+
+void R_Q3BSP_DrawFace_OpaqueWall_Pass_Glow(entity_render_t *ent, q3mface_t *face)
+{
+       rmeshstate_t m;
+       memset(&m, 0, sizeof(m));
+       GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+       GL_DepthMask(true);
+       GL_DepthTest(true);
+       if (face->texture->skin.glow)
        {
-               m.tex[1] = R_GetTexture(face->lightmaptexture);
-               m.pointer_texcoord[1] = face->data_texcoordlightmap2f;
-               m.texrgbscale[1] = 2;
+               m.tex[0] = R_GetTexture(face->texture->skin.glow);
+               m.pointer_texcoord[0] = face->data_texcoordtexture2f;
                GL_Color(1, 1, 1, 1);
        }
        else
-       {
-               m.texrgbscale[0] = 2;
-               GL_ColorPointer(face->data_color4f);
-       }
+               GL_Color(0, 0, 0, 1);
        R_Mesh_State_Texture(&m);
        GL_VertexPointer(face->data_vertex3f);
        R_Mesh_Draw(face->num_vertices, face->num_triangles, face->data_element3i);
 }
 
-/*
-void R_Q3BSP_DrawSky(entity_render_t *ent)
+void R_Q3BSP_DrawFace_OpaqueWall_Pass_TextureVertex(entity_render_t *ent, q3mface_t *face)
 {
+       rmeshstate_t m;
+       memset(&m, 0, sizeof(m));
+       GL_BlendFunc(GL_ONE, GL_ZERO);
+       GL_DepthMask(true);
+       GL_DepthTest(true);
+       m.tex[0] = R_GetTexture(face->texture->skin.base);
+       m.pointer_texcoord[0] = face->data_texcoordtexture2f;
+       m.texrgbscale[0] = 2;
+       GL_ColorPointer(face->data_color4f);
+       R_Mesh_State_Texture(&m);
+       GL_VertexPointer(face->data_vertex3f);
+       R_Mesh_Draw(face->num_vertices, face->num_triangles, face->data_element3i);
+}
+
+void R_Q3BSP_DrawFace_OpaqueWall_Pass_AddTextureAmbient(entity_render_t *ent, q3mface_t *face)
+{
+       rmeshstate_t m;
+       memset(&m, 0, sizeof(m));
+       GL_BlendFunc(GL_ONE, GL_ONE);
+       GL_DepthMask(true);
+       GL_DepthTest(true);
+       m.tex[0] = R_GetTexture(face->texture->skin.base);
+       m.pointer_texcoord[0] = face->data_texcoordtexture2f;
+       GL_Color(r_ambient.value * (1.0f / 128.0f), r_ambient.value * (1.0f / 128.0f), r_ambient.value * (1.0f / 128.0f), 1);
+       R_Mesh_State_Texture(&m);
+       GL_VertexPointer(face->data_vertex3f);
+       R_Mesh_Draw(face->num_vertices, face->num_triangles, face->data_element3i);
+}
+
+void R_Q3BSP_DrawFace(entity_render_t *ent, q3mface_t *face)
+{
+       if (!face->num_triangles)
+               return;
+       if (face->texture->renderflags)
+       {
+               if (face->texture->renderflags & Q3MTEXTURERENDERFLAGS_SKY)
+                       return;
+               if (face->texture->renderflags & Q3MTEXTURERENDERFLAGS_NODRAW)
+                       return;
+       }
+       if (face->texture->nativecontents & CONTENTSQ3_TRANSLUCENT)
+               qglDisable(GL_CULL_FACE);
+       R_Mesh_Matrix(&ent->matrix);
+       face->visframe = r_framecount;
+       if (r_shadow_realtime_world.integer)
+               R_Q3BSP_DrawFace_OpaqueWall_Pass_OpaqueGlow(ent, face);
+       else if ((ent->effects & EF_FULLBRIGHT) || r_fullbright.integer)
+       {
+               R_Q3BSP_DrawFace_OpaqueWall_Pass_Texture(ent, face);
+               if (face->texture->skin.glow)
+                       R_Q3BSP_DrawFace_OpaqueWall_Pass_Glow(ent, face);
+       }
+       else if (face->lightmaptexture)
+       {
+               if (r_textureunits.integer >= 2 && gl_combine.integer)
+                       R_Q3BSP_DrawFace_OpaqueWall_Pass_TextureLightmapCombine(ent, face);
+               else
+               {
+                       R_Q3BSP_DrawFace_OpaqueWall_Pass_Texture(ent, face);
+                       R_Q3BSP_DrawFace_OpaqueWall_Pass_Lightmap(ent, face);
+               }
+               if (face->texture->skin.glow)
+                       R_Q3BSP_DrawFace_OpaqueWall_Pass_Glow(ent, face);
+       }
+       else
+       {
+               R_Q3BSP_DrawFace_OpaqueWall_Pass_TextureVertex(ent, face);
+               if (face->texture->skin.glow)
+                       R_Q3BSP_DrawFace_OpaqueWall_Pass_Glow(ent, face);
+       }
+       if (r_ambient.value)
+               R_Q3BSP_DrawFace_OpaqueWall_Pass_AddTextureAmbient(ent, face);
+       if (face->texture->nativecontents & CONTENTSQ3_TRANSLUCENT)
+               qglEnable(GL_CULL_FACE);
 }
-*/
 
 void R_Q3BSP_RecursiveWorldNode(entity_render_t *ent, q3mnode_t *node, const vec3_t modelorg, qbyte *pvs, int markframe)
 {
@@ -1888,7 +1997,37 @@ void R_Q3BSP_RecursiveWorldNode(entity_render_t *ent, q3mnode_t *node, const vec
                        leaf->firstleafface[i]->markframe = markframe;
 }
 
+static int r_q3bsp_framecount = -1;
 
+void R_Q3BSP_DrawSky(entity_render_t *ent)
+{
+       int i;
+       q3mface_t *face;
+       vec3_t modelorg;
+       model_t *model;
+       qbyte *pvs;
+       R_Mesh_Matrix(&ent->matrix);
+       model = ent->model;
+       if (r_drawcollisionbrushes.integer < 2)
+       {
+               Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
+               if (ent == &cl_entities[0].render && model->brushq3.num_pvsclusters && !r_novis.integer && (pvs = model->brush.GetPVS(model, modelorg)))
+               {
+                       if (r_q3bsp_framecount != r_framecount)
+                       {
+                               r_q3bsp_framecount = r_framecount;
+                               R_Q3BSP_RecursiveWorldNode(ent, model->brushq3.data_nodes, modelorg, pvs, r_framecount);
+                       }
+                       for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++)
+                               if (face->markframe == r_framecount && (face->texture->renderflags & Q3MTEXTURERENDERFLAGS_SKY) && !R_CullBox(face->mins, face->maxs))
+                                       R_Q3BSP_DrawSkyFace(ent, face);
+               }
+               else
+                       for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++)
+                               if ((face->texture->renderflags & Q3MTEXTURERENDERFLAGS_SKY))
+                                       R_Q3BSP_DrawSkyFace(ent, face);
+       }
+}
 
 void R_Q3BSP_Draw(entity_render_t *ent)
 {
@@ -1897,7 +2036,6 @@ void R_Q3BSP_Draw(entity_render_t *ent)
        vec3_t modelorg;
        model_t *model;
        qbyte *pvs;
-       static int markframe = 0;
        R_Mesh_Matrix(&ent->matrix);
        model = ent->model;
        if (r_drawcollisionbrushes.integer < 2)
@@ -1905,9 +2043,13 @@ void R_Q3BSP_Draw(entity_render_t *ent)
                Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
                if (ent == &cl_entities[0].render && model->brushq3.num_pvsclusters && !r_novis.integer && (pvs = model->brush.GetPVS(model, modelorg)))
                {
-                       R_Q3BSP_RecursiveWorldNode(ent, model->brushq3.data_nodes, modelorg, pvs, ++markframe);
+                       if (r_q3bsp_framecount != r_framecount)
+                       {
+                               r_q3bsp_framecount = r_framecount;
+                               R_Q3BSP_RecursiveWorldNode(ent, model->brushq3.data_nodes, modelorg, pvs, r_framecount);
+                       }
                        for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++)
-                               if (face->markframe == markframe && !R_CullBox(face->mins, face->maxs))
+                               if (face->markframe == r_framecount && !R_CullBox(face->mins, face->maxs))
                                        R_Q3BSP_DrawFace(ent, face);
                }
                else