]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
remove some Blood Omnicide related hacks, fixed video stippling on ATI (always draw...
[xonotic/darkplaces.git] / gl_rmain.c
index bf9f8b587b59c25220acc1f691a5e41a61e7a9ab..d18c1a707306cd7917c57c513d69bf026ea9ddfc 100644 (file)
@@ -76,6 +76,7 @@ cvar_t r_showcollisionbrushes_polygonoffset = {0, "r_showcollisionbrushes_polygo
 cvar_t r_showdisabledepthtest = {0, "r_showdisabledepthtest", "0", "disables depth testing on r_show* cvars, allowing you to see what hidden geometry the graphics card is processing"};
 cvar_t r_drawportals = {0, "r_drawportals", "0", "shows portals (separating polygons) in world interior in quake1 maps"};
 cvar_t r_drawentities = {0, "r_drawentities","1", "draw entities (doors, players, projectiles, etc)"};
+cvar_t r_drawworld = {0, "r_drawworld","1", "draw world (most static stuff)"};
 cvar_t r_drawviewmodel = {0, "r_drawviewmodel","1", "draw your weapon model"};
 cvar_t r_drawexteriormodel = {0, "r_drawexteriormodel","1", "draw your player model (e.g. in chase cam, reflections)"};
 cvar_t r_cullentities_trace = {0, "r_cullentities_trace", "1", "probabistically cull invisible entities"};
@@ -4928,7 +4929,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
        case RENDERPATH_GL20:
                if (gl_mesh_separatearrays.integer)
                {
-                       RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_ARRAY_VERTEXCOLOR | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist);
+                       RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist);
                        R_Mesh_VertexPointer(     3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
                        R_Mesh_ColorPointer(      4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
                        R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
@@ -4939,7 +4940,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                }
                else
                {
-                       RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist);
+                       RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_VERTEXMESH_VERTEXCOLOR : 0) | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist);
                        R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
                }
                R_SetupShader_SetPermutationGLSL(mode, permutation);
@@ -5074,7 +5075,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
 #ifdef SUPPORTCG
                if (gl_mesh_separatearrays.integer)
                {
-                       RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_ARRAY_VERTEXCOLOR | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist);
+                       RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist);
                        R_Mesh_VertexPointer(     3, GL_FLOAT, sizeof(float[3]), rsurface.batchvertex3f, rsurface.batchvertex3f_vertexbuffer, rsurface.batchvertex3f_bufferoffset);
                        R_Mesh_ColorPointer(      4, GL_FLOAT, sizeof(float[4]), rsurface.batchlightmapcolor4f, rsurface.batchlightmapcolor4f_vertexbuffer, rsurface.batchlightmapcolor4f_bufferoffset);
                        R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset);
@@ -5085,7 +5086,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                }
                else
                {
-                       RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | BATCHNEED_VERTEXMESH_VERTEXCOLOR | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist);
+                       RSurf_PrepareVerticesForBatch(BATCHNEED_VERTEXMESH_VERTEX | BATCHNEED_VERTEXMESH_NORMAL | BATCHNEED_VERTEXMESH_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_VERTEXMESH_VERTEXCOLOR : 0) | BATCHNEED_VERTEXMESH_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_VERTEXMESH_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist);
                        R_Mesh_PrepareVertices_Mesh(rsurface.batchnumvertices, rsurface.batchvertexmesh, rsurface.batchvertexmeshbuffer);
                }
                R_SetupShader_SetPermutationCG(mode, permutation);
@@ -6296,7 +6297,6 @@ extern void CL_ParseEntityLump(char *entitystring);
 void gl_main_newmap(void)
 {
        // FIXME: move this code to client
-       int l;
        char *entities, entname[MAX_QPATH];
        if (r_qwskincache)
                Mem_Free(r_qwskincache);
@@ -6304,17 +6304,12 @@ void gl_main_newmap(void)
        r_qwskincache_size = 0;
        if (cl.worldmodel)
        {
-               strlcpy(entname, cl.worldmodel->name, sizeof(entname));
-               l = (int)strlen(entname) - 4;
-               if (l >= 0 && !strcmp(entname + l, ".bsp"))
+               dpsnprintf(entname, sizeof(entname), "%s.ent", cl.worldnamenoextension);
+               if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
                {
-                       memcpy(entname + l, ".ent", 5);
-                       if ((entities = (char *)FS_LoadFile(entname, tempmempool, true, NULL)))
-                       {
-                               CL_ParseEntityLump(entities);
-                               Mem_Free(entities);
-                               return;
-                       }
+                       CL_ParseEntityLump(entities);
+                       Mem_Free(entities);
+                       return;
                }
                if (cl.worldmodel->brush.entities)
                        CL_ParseEntityLump(cl.worldmodel->brush.entities);
@@ -6371,6 +6366,7 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable(&r_showdisabledepthtest);
        Cvar_RegisterVariable(&r_drawportals);
        Cvar_RegisterVariable(&r_drawentities);
+       Cvar_RegisterVariable(&r_drawworld);
        Cvar_RegisterVariable(&r_cullentities_trace);
        Cvar_RegisterVariable(&r_cullentities_trace_samples);
        Cvar_RegisterVariable(&r_cullentities_trace_tempentitysamples);
@@ -10901,32 +10897,39 @@ static void RSurf_BindLightmapForBatch(void)
        }
 }
 
-static void RSurf_BindReflectionForBatch(void)
+static int RSurf_FindWaterPlaneForSurface(const msurface_t *surface)
 {
-       // pick the closest matching water plane and bind textures
-       int planeindex, vertexindex;
+       // pick the closest matching water plane
+       int planeindex, vertexindex, bestplaneindex = -1;
        float d, bestd;
        vec3_t vert;
        const float *v;
-       r_waterstate_waterplane_t *p, *bestp;
+       r_waterstate_waterplane_t *p;
        bestd = 0;
-       bestp = NULL;
        for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
        {
                if(p->camera_entity != rsurface.texture->camera_entity)
                        continue;
                d = 0;
+               RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, 1, &surface);
                for (vertexindex = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3;vertexindex < rsurface.batchnumvertices;vertexindex++, v += 3)
                {
                        Matrix4x4_Transform(&rsurface.matrix, v, vert);
                        d += fabs(PlaneDiff(vert, &p->plane));
                }
-               if (bestd > d || !bestp)
+               if (bestd > d || bestplaneindex < 0)
                {
                        bestd = d;
-                       bestp = p;
+                       bestplaneindex = planeindex;
                }
        }
+       return bestplaneindex;
+}
+
+static void RSurf_BindReflectionForBatch(int planeindex)
+{
+       // pick the closest matching water plane and bind textures
+       r_waterstate_waterplane_t *bestp = planeindex >= 0 ? r_waterstate.waterplanes + planeindex : NULL;
        switch(vid.renderpath)
        {
        case RENDERPATH_CGGL:
@@ -11257,33 +11260,55 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, const msurface
                GL_DepthMask(true);
                R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_DEFERREDGEOMETRY, texturenumsurfaces, texturesurfacelist);
                RSurf_DrawBatch();
+               return;
        }
-       else if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA)) && !r_waterstate.renderingscene)
-       {
-               // render water or distortion background, then blend surface on top
-               GL_DepthMask(true);
-               R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BACKGROUND, texturenumsurfaces, texturesurfacelist);
-               RSurf_BindReflectionForBatch();
-               if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
-                       RSurf_BindLightmapForBatch();
-               RSurf_DrawBatch();
-               GL_DepthMask(false);
-               R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist);
-               if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
-                       RSurf_BindLightmapForBatch();
-               RSurf_DrawBatch();
-       }
-       else
+
+       // bind lightmap texture
+
+       // water/refraction/reflection/camera surfaces have to be handled specially
+       if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA | MATERIALFLAG_REFLECTION)) && !r_waterstate.renderingscene)
        {
-               // render surface normally
-               GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
-               R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist);
-               if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
-                       RSurf_BindReflectionForBatch();
-               if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
-                       RSurf_BindLightmapForBatch();
-               RSurf_DrawBatch();
+               int start, end, startplaneindex;
+               for (start = 0;start < texturenumsurfaces;start = end)
+               {
+                       startplaneindex = RSurf_FindWaterPlaneForSurface(texturesurfacelist[start]);
+                       for (end = start + 1;end < texturenumsurfaces && startplaneindex == RSurf_FindWaterPlaneForSurface(texturesurfacelist[end]);end++)
+                               ;
+                       // now that we have a batch using the same planeindex, render it
+                       if ((rsurface.texture->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_CAMERA)) && !r_waterstate.renderingscene)
+                       {
+                               // render water or distortion background
+                               GL_DepthMask(true);
+                               R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BACKGROUND, end-start, texturesurfacelist + start);
+                               RSurf_BindReflectionForBatch(startplaneindex);
+                               if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
+                                       RSurf_BindLightmapForBatch();
+                               RSurf_DrawBatch();
+                               // blend surface on top
+                               GL_DepthMask(false);
+                               R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start);
+                               RSurf_DrawBatch();
+                       }
+                       else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) && !r_waterstate.renderingscene)
+                       {
+                               // render surface with reflection texture as input
+                               GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
+                               R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, end-start, texturesurfacelist + start);
+                               RSurf_BindReflectionForBatch(startplaneindex);
+                               if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
+                                       RSurf_BindLightmapForBatch();
+                               RSurf_DrawBatch();
+                       }
+               }
+               return;
        }
+
+       // render surface batch normally
+       GL_DepthMask(writedepth && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_BLENDED));
+       R_SetupShader_Surface(vec3_origin, (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) != 0, 1, 1, rsurface.texture->specularscale, RSURFPASS_BASE, texturenumsurfaces, texturesurfacelist);
+       if (rsurface.uselightmaptexture && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
+               RSurf_BindLightmapForBatch();
+       RSurf_DrawBatch();
 }
 
 static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth)
@@ -12285,7 +12310,7 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor
                if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)
                        continue;
                numtriangles = surface->num_triangles;
-               for (triangleindex = 0, e = model->surfmesh.data_element3i + 3*surface->num_firsttriangle;triangleindex < numtriangles;triangleindex++, e += 3)
+               for (triangleindex = 0, e = rsurface.modelelement3i + 3*surface->num_firsttriangle;triangleindex < numtriangles;triangleindex++, e += 3)
                {
                        for (cornerindex = 0;cornerindex < 3;cornerindex++)
                        {