]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
fix a crash reported by Lardarse when using more skin textures for a
[xonotic/darkplaces.git] / gl_rmain.c
index 12be21aa5b6555315dc939a2db233a49523101a8..bfef3c49d083b245f3b1575302c096de1d9e0e08 100644 (file)
@@ -51,7 +51,7 @@ cvar_t r_cullentities_trace_samples = {0, "r_cullentities_trace_samples", "2", "
 cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", "box enlargement for entity culling"};
 cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"};
 cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"};
-cvar_t r_fullbright = {0, "r_fullbright","0", "make everything bright cheat (not allowed in multiplayer)"};
+cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"};
 cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"};
 cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"};
 cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"};
@@ -581,17 +581,17 @@ static const char *builtinshaderstring =
 "      myhvec3 specularnormal = normalize(diffusenormal + myhvec3(normalize(EyeVector)));\n"
 "\n"
 "      // calculate directional shading\n"
-"      color.rgb = LightColor * myhalf(texture2D(Texture_Attenuation, length(CubeVector))) * (color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))) + (SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower)) * myhvec3(texture2D(Texture_Gloss, TexCoord)));\n"
+"      color.rgb = LightColor * myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * (color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))) + (SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower)) * myhvec3(texture2D(Texture_Gloss, TexCoord)));\n"
 "#else\n"
 "#ifdef USEDIFFUSE\n"
 "      myhvec3 surfacenormal = normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5));\n"
 "      myhvec3 diffusenormal = myhvec3(normalize(LightVector));\n"
 "\n"
 "      // calculate directional shading\n"
-"      color.rgb = LightColor * myhalf(texture2D(Texture_Attenuation, length(CubeVector))) * color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0)));\n"
+"      color.rgb = LightColor * myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0)));\n"
 "#else\n"
 "      // calculate directionless shading\n"
-"      color.rgb = color.rgb * LightColor * myhalf(texture2D(Texture_Attenuation, length(CubeVector)));\n"
+"      color.rgb = color.rgb * LightColor * myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n"
 "#endif\n"
 "#endif\n"
 "\n"
@@ -1361,14 +1361,14 @@ static void R_View_UpdateEntityVisible (void)
                for (i = 0;i < r_refdef.numentities;i++)
                {
                        ent = r_refdef.entities[i];
-                       r_viewcache.entityvisible[i] = !(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && ((ent->effects & EF_NODEPTHTEST) || r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.worldmodel, r_viewcache.world_leafvisible, ent->mins, ent->maxs));
+                       r_viewcache.entityvisible[i] = !(ent->flags & renderimask) && !R_CullBox(ent->mins, ent->maxs) && ((ent->effects & EF_NODEPTHTEST) || (ent->flags & RENDER_VIEWMODEL) || r_refdef.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.worldmodel, r_viewcache.world_leafvisible, ent->mins, ent->maxs));
                }
                if(r_cullentities_trace.integer)
                {
                        for (i = 0;i < r_refdef.numentities;i++)
                        {
                                ent = r_refdef.entities[i];
-                               if(r_viewcache.entityvisible[i] && !(ent->effects & EF_NODEPTHTEST) && !(ent->model && (ent->model->name[0] == '*')))
+                               if(r_viewcache.entityvisible[i] && !(ent->effects & EF_NODEPTHTEST) && !(ent->flags & RENDER_VIEWMODEL) && !(ent->model && (ent->model->name[0] == '*')))
                                {
                                        if(Mod_CanSeeBox_Trace(r_cullentities_trace_samples.integer, r_cullentities_trace_enlarge.value, r_refdef.worldmodel, r_view.origin, ent->mins, ent->maxs))
                                                ent->last_trace_visibility = realtime;
@@ -1604,6 +1604,7 @@ void R_ResetViewRendering2D(void)
        GL_AlphaTest(false);
        GL_ScissorTest(false);
        GL_DepthMask(false);
+       GL_DepthRange(0, 1);
        GL_DepthTest(false);
        R_Mesh_Matrix(&identitymatrix);
        R_Mesh_ResetTextureState();
@@ -1636,6 +1637,7 @@ void R_ResetViewRendering3D(void)
        GL_AlphaTest(false);
        GL_ScissorTest(true);
        GL_DepthMask(true);
+       GL_DepthRange(0, 1);
        GL_DepthTest(true);
        R_Mesh_Matrix(&identitymatrix);
        R_Mesh_ResetTextureState();
@@ -2320,6 +2322,7 @@ void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, floa
        float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4];
        GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        GL_DepthMask(false);
+       GL_DepthRange(0, 1);
        GL_DepthTest(true);
        R_Mesh_Matrix(&identitymatrix);
 
@@ -2406,6 +2409,7 @@ void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight
                GL_BlendFunc(GL_ONE, GL_ZERO);
                GL_DepthMask(true);
        }
+       GL_DepthRange(0, (ent->flags & RENDER_VIEWMODEL) ? 0.0625 : 1);
        GL_DepthTest(!(ent->effects & EF_NODEPTHTEST));
        GL_CullFace((ent->effects & EF_DOUBLESIDED) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces
        R_Mesh_VertexPointer(nomodelvertex3f, 0, 0);
@@ -2480,7 +2484,7 @@ void R_CalcBeam_Vertex3f (float *vert, const vec3_t org1, const vec3_t org2, flo
 
 float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1};
 
-void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_t *fogtexture, int depthdisable, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2, float cr, float cg, float cb, float ca)
+void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_t *fogtexture, qboolean depthdisable, qboolean depthshort, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2, float cr, float cg, float cb, float ca)
 {
        float fog = 0.0f, ifog;
        float vertex3f[12];
@@ -2492,6 +2496,7 @@ void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_
        R_Mesh_Matrix(&identitymatrix);
        GL_BlendFunc(blendfunc1, blendfunc2);
        GL_DepthMask(false);
+       GL_DepthRange(0, depthshort ? 0.0625 : 1);
        GL_DepthTest(!depthdisable);
 
        vertex3f[ 0] = origin[0] + left[0] * scalex2 + up[0] * scaley1;
@@ -2707,18 +2712,20 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
        if (!(ent->flags & RENDER_LIGHT))
                t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
        if (ent->effects & EF_ADDITIVE)
-               t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_TRANSPARENT | MATERIALFLAG_NOSHADOW;
+               t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
        else if (t->currentalpha < 1)
-               t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_TRANSPARENT | MATERIALFLAG_NOSHADOW;
+               t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW;
        if (ent->effects & EF_DOUBLESIDED)
                t->currentmaterialflags |= MATERIALFLAG_NOSHADOW | MATERIALFLAG_NOCULLFACE;
        if (ent->effects & EF_NODEPTHTEST)
-               t->currentmaterialflags |= MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_NOSHADOW;
+               t->currentmaterialflags |= MATERIALFLAG_SHORTDEPTHRANGE;
+       if (ent->flags & RENDER_VIEWMODEL)
+               t->currentmaterialflags |= MATERIALFLAG_SHORTDEPTHRANGE;
        if (t->currentmaterialflags & MATERIALFLAG_WATER && r_waterscroll.value != 0)
                t->currenttexmatrix = r_waterscrollmatrix;
        else
                t->currenttexmatrix = identitymatrix;
-       if (t->backgroundnumskinframes && !(t->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
+       if (t->backgroundnumskinframes && !(t->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED))
                t->currentmaterialflags |= MATERIALFLAG_VERTEXTEXTUREBLEND;
 
        t->colormapping = VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f);
@@ -2879,14 +2886,32 @@ void R_Mesh_ResizeArrays(int newvertices)
 }
 
 float *rsurface_modelvertex3f;
+int rsurface_modelvertex3f_bufferobject;
+size_t rsurface_modelvertex3f_bufferoffset;
 float *rsurface_modelsvector3f;
+int rsurface_modelsvector3f_bufferobject;
+size_t rsurface_modelsvector3f_bufferoffset;
 float *rsurface_modeltvector3f;
+int rsurface_modeltvector3f_bufferobject;
+size_t rsurface_modeltvector3f_bufferoffset;
 float *rsurface_modelnormal3f;
+int rsurface_modelnormal3f_bufferobject;
+size_t rsurface_modelnormal3f_bufferoffset;
 float *rsurface_vertex3f;
+int rsurface_vertex3f_bufferobject;
+size_t rsurface_vertex3f_bufferoffset;
 float *rsurface_svector3f;
+int rsurface_svector3f_bufferobject;
+size_t rsurface_svector3f_bufferoffset;
 float *rsurface_tvector3f;
+int rsurface_tvector3f_bufferobject;
+size_t rsurface_tvector3f_bufferoffset;
 float *rsurface_normal3f;
+int rsurface_normal3f_bufferobject;
+size_t rsurface_normal3f_bufferoffset;
 float *rsurface_lightmapcolor4f;
+int rsurface_lightmapcolor4f_bufferobject;
+size_t rsurface_lightmapcolor4f_bufferoffset;
 vec3_t rsurface_modelorg;
 qboolean rsurface_generatedvertex;
 const entity_render_t *rsurface_entity;
@@ -2919,14 +2944,30 @@ void RSurf_ActiveWorldEntity(void)
        R_Mesh_Matrix(&identitymatrix);
        VectorCopy(r_view.origin, rsurface_modelorg);
        rsurface_modelvertex3f  = rsurface_model->surfmesh.data_vertex3f;
+       rsurface_modelvertex3f_bufferobject = rsurface_model->surfmesh.vbo;
+       rsurface_modelvertex3f_bufferoffset = rsurface_model->surfmesh.vbooffset_vertex3f;
        rsurface_modelsvector3f = rsurface_model->surfmesh.data_svector3f;
+       rsurface_modelsvector3f_bufferobject = rsurface_model->surfmesh.vbo;
+       rsurface_modelsvector3f_bufferoffset = rsurface_model->surfmesh.vbooffset_svector3f;
        rsurface_modeltvector3f = rsurface_model->surfmesh.data_tvector3f;
+       rsurface_modeltvector3f_bufferobject = rsurface_model->surfmesh.vbo;
+       rsurface_modeltvector3f_bufferoffset = rsurface_model->surfmesh.vbooffset_tvector3f;
        rsurface_modelnormal3f  = rsurface_model->surfmesh.data_normal3f;
+       rsurface_modelnormal3f_bufferobject = rsurface_model->surfmesh.vbo;
+       rsurface_modelnormal3f_bufferoffset = rsurface_model->surfmesh.vbooffset_normal3f;
        rsurface_generatedvertex = false;
        rsurface_vertex3f  = rsurface_modelvertex3f;
+       rsurface_vertex3f_bufferobject = rsurface_modelvertex3f_bufferobject;
+       rsurface_vertex3f_bufferoffset = rsurface_modelvertex3f_bufferoffset;
        rsurface_svector3f = rsurface_modelsvector3f;
+       rsurface_svector3f_bufferobject = rsurface_modelsvector3f_bufferobject;
+       rsurface_svector3f_bufferoffset = rsurface_modelsvector3f_bufferoffset;
        rsurface_tvector3f = rsurface_modeltvector3f;
+       rsurface_tvector3f_bufferobject = rsurface_modeltvector3f_bufferobject;
+       rsurface_tvector3f_bufferoffset = rsurface_modeltvector3f_bufferoffset;
        rsurface_normal3f  = rsurface_modelnormal3f;
+       rsurface_normal3f_bufferobject = rsurface_modelnormal3f_bufferobject;
+       rsurface_normal3f_bufferoffset = rsurface_modelnormal3f_bufferoffset;
 }
 
 void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents)
@@ -2964,20 +3005,44 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q
                        rsurface_modelnormal3f = NULL;
                        Mod_Alias_GetMesh_Vertices(rsurface_model, rsurface_entity->frameblend, rsurface_array_modelvertex3f, NULL, NULL, NULL);
                }
+               rsurface_modelvertex3f_bufferobject = 0;
+               rsurface_modelvertex3f_bufferoffset = 0;
+               rsurface_modelsvector3f_bufferobject = 0;
+               rsurface_modelsvector3f_bufferoffset = 0;
+               rsurface_modeltvector3f_bufferobject = 0;
+               rsurface_modeltvector3f_bufferoffset = 0;
+               rsurface_modelnormal3f_bufferobject = 0;
+               rsurface_modelnormal3f_bufferoffset = 0;
                rsurface_generatedvertex = true;
        }
        else
        {
                rsurface_modelvertex3f  = rsurface_model->surfmesh.data_vertex3f;
+               rsurface_modelvertex3f_bufferobject = rsurface_model->surfmesh.vbo;
+               rsurface_modelvertex3f_bufferoffset = rsurface_model->surfmesh.vbooffset_vertex3f;
                rsurface_modelsvector3f = rsurface_model->surfmesh.data_svector3f;
+               rsurface_modelsvector3f_bufferobject = rsurface_model->surfmesh.vbo;
+               rsurface_modelsvector3f_bufferoffset = rsurface_model->surfmesh.vbooffset_svector3f;
                rsurface_modeltvector3f = rsurface_model->surfmesh.data_tvector3f;
+               rsurface_modeltvector3f_bufferobject = rsurface_model->surfmesh.vbo;
+               rsurface_modeltvector3f_bufferoffset = rsurface_model->surfmesh.vbooffset_tvector3f;
                rsurface_modelnormal3f  = rsurface_model->surfmesh.data_normal3f;
+               rsurface_modelnormal3f_bufferobject = rsurface_model->surfmesh.vbo;
+               rsurface_modelnormal3f_bufferoffset = rsurface_model->surfmesh.vbooffset_normal3f;
                rsurface_generatedvertex = false;
        }
        rsurface_vertex3f  = rsurface_modelvertex3f;
+       rsurface_vertex3f_bufferobject = rsurface_modelvertex3f_bufferobject;
+       rsurface_vertex3f_bufferoffset = rsurface_modelvertex3f_bufferoffset;
        rsurface_svector3f = rsurface_modelsvector3f;
+       rsurface_svector3f_bufferobject = rsurface_modelsvector3f_bufferobject;
+       rsurface_svector3f_bufferoffset = rsurface_modelsvector3f_bufferoffset;
        rsurface_tvector3f = rsurface_modeltvector3f;
+       rsurface_tvector3f_bufferobject = rsurface_modeltvector3f_bufferobject;
+       rsurface_tvector3f_bufferoffset = rsurface_modeltvector3f_bufferoffset;
        rsurface_normal3f  = rsurface_modelnormal3f;
+       rsurface_normal3f_bufferobject = rsurface_modelnormal3f_bufferobject;
+       rsurface_normal3f_bufferoffset = rsurface_modelnormal3f_bufferoffset;
 }
 
 void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generatetangents, int texturenumsurfaces, msurface_t **texturesurfacelist)
@@ -2992,12 +3057,18 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta
                if (generatenormals && !rsurface_modelnormal3f)
                {
                        rsurface_normal3f = rsurface_modelnormal3f = rsurface_array_modelnormal3f;
+                       rsurface_normal3f_bufferobject = rsurface_modelnormal3f_bufferobject = 0;
+                       rsurface_normal3f_bufferoffset = rsurface_modelnormal3f_bufferoffset = 0;
                        Mod_BuildNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_element3i, rsurface_array_modelnormal3f, r_smoothnormals_areaweighting.integer);
                }
                if (generatetangents && !rsurface_modelsvector3f)
                {
                        rsurface_svector3f = rsurface_modelsvector3f = rsurface_array_modelsvector3f;
+                       rsurface_svector3f_bufferobject = rsurface_modelsvector3f_bufferobject = 0;
+                       rsurface_svector3f_bufferoffset = rsurface_modelsvector3f_bufferoffset = 0;
                        rsurface_tvector3f = rsurface_modeltvector3f = rsurface_array_modeltvector3f;
+                       rsurface_tvector3f_bufferobject = rsurface_modeltvector3f_bufferobject = 0;
+                       rsurface_tvector3f_bufferoffset = rsurface_modeltvector3f_bufferoffset = 0;
                        Mod_BuildTextureVectorsFromNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_modelnormal3f, rsurface_model->surfmesh.data_element3i, rsurface_array_modelsvector3f, rsurface_array_modeltvector3f, r_smoothnormals_areaweighting.integer);
                }
        }
@@ -3045,18 +3116,34 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta
                        Mod_BuildTextureVectorsFromNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_array_deformednormal3f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_deformedsvector3f, rsurface_array_deformedtvector3f, r_smoothnormals_areaweighting.integer);
                }
                rsurface_vertex3f = rsurface_array_deformedvertex3f;
+               rsurface_vertex3f_bufferobject = 0;
+               rsurface_vertex3f_bufferoffset = 0;
                rsurface_svector3f = rsurface_array_deformedsvector3f;
+               rsurface_svector3f_bufferobject = 0;
+               rsurface_svector3f_bufferoffset = 0;
                rsurface_tvector3f = rsurface_array_deformedtvector3f;
+               rsurface_tvector3f_bufferobject = 0;
+               rsurface_tvector3f_bufferoffset = 0;
                rsurface_normal3f = rsurface_array_deformednormal3f;
+               rsurface_normal3f_bufferobject = 0;
+               rsurface_normal3f_bufferoffset = 0;
        }
        else
        {
-               rsurface_vertex3f = rsurface_modelvertex3f;
+               rsurface_vertex3f  = rsurface_modelvertex3f;
+               rsurface_vertex3f_bufferobject = rsurface_modelvertex3f_bufferobject;
+               rsurface_vertex3f_bufferoffset = rsurface_modelvertex3f_bufferoffset;
                rsurface_svector3f = rsurface_modelsvector3f;
+               rsurface_svector3f_bufferobject = rsurface_modelsvector3f_bufferobject;
+               rsurface_svector3f_bufferoffset = rsurface_modelsvector3f_bufferoffset;
                rsurface_tvector3f = rsurface_modeltvector3f;
-               rsurface_normal3f = rsurface_modelnormal3f;
+               rsurface_tvector3f_bufferobject = rsurface_modeltvector3f_bufferobject;
+               rsurface_tvector3f_bufferoffset = rsurface_modeltvector3f_bufferoffset;
+               rsurface_normal3f  = rsurface_modelnormal3f;
+               rsurface_normal3f_bufferobject = rsurface_modelnormal3f_bufferobject;
+               rsurface_normal3f_bufferoffset = rsurface_modelnormal3f_bufferoffset;
        }
-       R_Mesh_VertexPointer(rsurface_vertex3f, 0, 0);
+       R_Mesh_VertexPointer(rsurface_vertex3f, rsurface_vertex3f_bufferobject, rsurface_vertex3f_bufferoffset);
 }
 
 void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacelist)
@@ -3072,7 +3159,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel
        if (texturenumsurfaces == 1)
        {
                GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), 0, 0);
+               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle));
        }
        else if (r_batchmode.integer == 2)
        {
@@ -3085,7 +3172,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel
                        j = i + 1;
                        if (surface->num_triangles > MAXBATCHTRIANGLES)
                        {
-                               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), 0, 0);
+                               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle));
                                continue;
                        }
                        memcpy(batchelements, rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle, surface->num_triangles * sizeof(int[3]));
@@ -3119,7 +3206,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel
                        numvertices = surface2->num_firstvertex + surface2->num_vertices - surface->num_firstvertex;
                        numtriangles = surface2->num_firsttriangle + surface2->num_triangles - surface->num_firsttriangle;
                        GL_LockArrays(surface->num_firstvertex, numvertices);
-                       R_Mesh_Draw(surface->num_firstvertex, numvertices, numtriangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), 0, 0);
+                       R_Mesh_Draw(surface->num_firstvertex, numvertices, numtriangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle));
                }
        }
        else
@@ -3128,7 +3215,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel
                {
                        surface = texturesurfacelist[i];
                        GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), 0, 0);
+                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle));
                }
        }
 }
@@ -3150,7 +3237,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa
                if (deluxemaptexunit >= 0)
                        R_Mesh_TexBind(deluxemaptexunit, R_GetTexture(surface->deluxemaptexture));
                GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), 0, 0);
+               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle));
        }
        else if (r_batchmode.integer == 2)
        {
@@ -3166,7 +3253,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa
                        j = i + 1;
                        if (surface->num_triangles > MAXBATCHTRIANGLES)
                        {
-                               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), 0, 0);
+                               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle));
                                continue;
                        }
                        memcpy(batchelements, rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle, surface->num_triangles * sizeof(int[3]));
@@ -3219,7 +3306,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa
                        numvertices = surface2->num_firstvertex + surface2->num_vertices - surface->num_firstvertex;
                        numtriangles = surface2->num_firsttriangle + surface2->num_triangles - surface->num_firsttriangle;
                        GL_LockArrays(surface->num_firstvertex, numvertices);
-                       R_Mesh_Draw(surface->num_firstvertex, numvertices, numtriangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), 0, 0);
+                       R_Mesh_Draw(surface->num_firstvertex, numvertices, numtriangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle));
                }
 #if 0
                Con_Printf("\n");
@@ -3234,7 +3321,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa
                        if (deluxemaptexunit >= 0)
                                R_Mesh_TexBind(deluxemaptexunit, R_GetTexture(surface->deluxemaptexture));
                        GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), 0, 0);
+                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle));
                }
        }
 }
@@ -3252,7 +3339,7 @@ static void RSurf_DrawBatch_ShowSurfaces(int texturenumsurfaces, msurface_t **te
                        {
                                float f = ((j + surface->num_firsttriangle) & 31) * (1.0f / 31.0f) * r_view.colorscale;
                                GL_Color(f, f, f, 1);
-                               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, 1, (rsurface_model->surfmesh.data_element3i + 3 * (j + surface->num_firsttriangle)), 0, 0);
+                               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, 1, (rsurface_model->surfmesh.data_element3i + 3 * (j + surface->num_firsttriangle)), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * (j + surface->num_firsttriangle)));
                        }
                }
        }
@@ -3264,7 +3351,7 @@ static void RSurf_DrawBatch_ShowSurfaces(int texturenumsurfaces, msurface_t **te
                        int k = (int)(((size_t)surface) / sizeof(msurface_t));
                        GL_Color((k & 15) * (1.0f / 16.0f) * r_view.colorscale, ((k >> 4) & 15) * (1.0f / 16.0f) * r_view.colorscale, ((k >> 8) & 15) * (1.0f / 16.0f) * r_view.colorscale, 1);
                        GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), 0, 0);
+                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle));
                }
        }
 }
@@ -3307,6 +3394,8 @@ static void RSurf_DrawBatch_GL11_ApplyFog(int texturenumsurfaces, msurface_t **t
                }
        }
        rsurface_lightmapcolor4f = rsurface_array_color4f;
+       rsurface_lightmapcolor4f_bufferobject = 0;
+       rsurface_lightmapcolor4f_bufferoffset = 0;
 }
 
 static void RSurf_DrawBatch_GL11_ApplyColor(int texturenumsurfaces, msurface_t **texturesurfacelist, float r, float g, float b, float a)
@@ -3328,15 +3417,19 @@ static void RSurf_DrawBatch_GL11_ApplyColor(int texturenumsurfaces, msurface_t *
                }
        }
        rsurface_lightmapcolor4f = rsurface_array_color4f;
+       rsurface_lightmapcolor4f_bufferobject = 0;
+       rsurface_lightmapcolor4f_bufferoffset = 0;
 }
 
 static void RSurf_DrawBatch_GL11_Lightmap(int texturenumsurfaces, msurface_t **texturesurfacelist, float r, float g, float b, float a, qboolean applycolor, qboolean applyfog)
 {
        // TODO: optimize
        rsurface_lightmapcolor4f = NULL;
+       rsurface_lightmapcolor4f_bufferobject = 0;
+       rsurface_lightmapcolor4f_bufferoffset = 0;
        if (applyfog)   RSurf_DrawBatch_GL11_ApplyFog(texturenumsurfaces, texturesurfacelist);
        if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(texturenumsurfaces, texturesurfacelist, r, g, b, a);
-       R_Mesh_ColorPointer(rsurface_lightmapcolor4f, 0, 0);
+       R_Mesh_ColorPointer(rsurface_lightmapcolor4f, rsurface_lightmapcolor4f_bufferobject, rsurface_lightmapcolor4f_bufferoffset);
        GL_Color(r, g, b, a);
        RSurf_DrawBatch_WithLightmapSwitching(texturenumsurfaces, texturesurfacelist, 0, -1);
 }
@@ -3346,9 +3439,11 @@ static void RSurf_DrawBatch_GL11_Unlit(int texturenumsurfaces, msurface_t **text
        // TODO: optimize applyfog && applycolor case
        // just apply fog if necessary, and tint the fog color array if necessary
        rsurface_lightmapcolor4f = NULL;
+       rsurface_lightmapcolor4f_bufferobject = 0;
+       rsurface_lightmapcolor4f_bufferoffset = 0;
        if (applyfog)   RSurf_DrawBatch_GL11_ApplyFog(texturenumsurfaces, texturesurfacelist);
        if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(texturenumsurfaces, texturesurfacelist, r, g, b, a);
-       R_Mesh_ColorPointer(rsurface_lightmapcolor4f, 0, 0);
+       R_Mesh_ColorPointer(rsurface_lightmapcolor4f, rsurface_lightmapcolor4f_bufferobject, rsurface_lightmapcolor4f_bufferoffset);
        GL_Color(r, g, b, a);
        RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
 }
@@ -3398,12 +3493,18 @@ static void RSurf_DrawBatch_GL11_VertexColor(int texturenumsurfaces, msurface_t
                        }
                }
                rsurface_lightmapcolor4f = rsurface_array_color4f;
+               rsurface_lightmapcolor4f_bufferobject = 0;
+               rsurface_lightmapcolor4f_bufferoffset = 0;
        }
        else
+       {
                rsurface_lightmapcolor4f = rsurface_model->surfmesh.data_lightmapcolor4f;
+               rsurface_lightmapcolor4f_bufferobject = rsurface_model->surfmesh.vbo;
+               rsurface_lightmapcolor4f_bufferoffset = rsurface_model->surfmesh.vbooffset_lightmapcolor4f;
+       }
        if (applyfog)   RSurf_DrawBatch_GL11_ApplyFog(texturenumsurfaces, texturesurfacelist);
        if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(texturenumsurfaces, texturesurfacelist, r, g, b, a);
-       R_Mesh_ColorPointer(rsurface_lightmapcolor4f, 0, 0);
+       R_Mesh_ColorPointer(rsurface_lightmapcolor4f, rsurface_lightmapcolor4f_bufferobject, rsurface_lightmapcolor4f_bufferoffset);
        GL_Color(r, g, b, a);
        RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
 }
@@ -3452,6 +3553,8 @@ static void RSurf_DrawBatch_GL11_VertexShade(int texturenumsurfaces, msurface_t
                a = 1;
                applycolor = false;
                rsurface_lightmapcolor4f = rsurface_array_color4f;
+               rsurface_lightmapcolor4f_bufferobject = 0;
+               rsurface_lightmapcolor4f_bufferoffset = 0;
        }
        else
        {
@@ -3459,16 +3562,19 @@ static void RSurf_DrawBatch_GL11_VertexShade(int texturenumsurfaces, msurface_t
                g = ambientcolor[1];
                b = ambientcolor[2];
                rsurface_lightmapcolor4f = NULL;
+               rsurface_lightmapcolor4f_bufferobject = 0;
+               rsurface_lightmapcolor4f_bufferoffset = 0;
        }
        if (applyfog)   RSurf_DrawBatch_GL11_ApplyFog(texturenumsurfaces, texturesurfacelist);
        if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(texturenumsurfaces, texturesurfacelist, r, g, b, a);
-       R_Mesh_ColorPointer(rsurface_lightmapcolor4f, 0, 0);
+       R_Mesh_ColorPointer(rsurface_lightmapcolor4f, rsurface_lightmapcolor4f_bufferobject, rsurface_lightmapcolor4f_bufferoffset);
        GL_Color(r, g, b, a);
        RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
 }
 
 static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, msurface_t **texturesurfacelist)
 {
+       GL_DepthRange(0, (rsurface_texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
        GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
        GL_CullFace((rsurface_texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces
        if (rsurface_mode != RSURFMODE_SHOWSURFACES)
@@ -3486,7 +3592,7 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, msurfa
 static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, msurface_t **texturesurfacelist)
 {
        // transparent sky would be ridiculous
-       if ((rsurface_texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
+       if ((rsurface_texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED))
                return;
        if (rsurface_mode != RSURFMODE_SKY)
        {
@@ -3503,6 +3609,7 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, msurface_t **te
                // restore entity matrix
                R_Mesh_Matrix(&rsurface_entity->matrix);
        }
+       GL_DepthRange(0, (rsurface_texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
        GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
        GL_CullFace((rsurface_texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces
        GL_DepthMask(true);
@@ -3553,11 +3660,11 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, msurface_t **t
                RSurf_PrepareVerticesForBatch(true, r_glsl_permutation->loc_Texture_Normal, texturenumsurfaces, texturesurfacelist);
        else
                RSurf_PrepareVerticesForBatch(r_glsl_permutation->loc_Texture_Normal, r_glsl_permutation->loc_Texture_Normal, texturenumsurfaces, texturesurfacelist);
-       R_Mesh_TexCoordPointer(0, 2, rsurface_model->surfmesh.data_texcoordtexture2f, 0, 0);
-       R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f, 0, 0);
-       R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f, 0, 0);
-       R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f, 0, 0);
-       R_Mesh_TexCoordPointer(4, 2, rsurface_model->surfmesh.data_texcoordlightmap2f, 0, 0);
+       R_Mesh_TexCoordPointer(0, 2, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_model->surfmesh.vbo, rsurface_model->surfmesh.vbooffset_texcoordtexture2f);
+       R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f, rsurface_svector3f_bufferobject, rsurface_svector3f_bufferoffset);
+       R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f, rsurface_tvector3f_bufferobject, rsurface_tvector3f_bufferoffset);
+       R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f, rsurface_normal3f_bufferobject, rsurface_normal3f_bufferoffset);
+       R_Mesh_TexCoordPointer(4, 2, rsurface_model->surfmesh.data_texcoordlightmap2f, rsurface_model->surfmesh.vbo, rsurface_model->surfmesh.vbooffset_texcoordlightmap2f);
 
        if (rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
        {
@@ -3578,14 +3685,14 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, msurface_t **t
                R_Mesh_TexBind(7, R_GetTexture(r_texture_white));
                if (r_glsl_permutation->loc_Texture_Deluxemap >= 0)
                        R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap));
-               R_Mesh_ColorPointer(rsurface_model->surfmesh.data_lightmapcolor4f, 0, 0);
+               R_Mesh_ColorPointer(rsurface_model->surfmesh.data_lightmapcolor4f, rsurface_model->surfmesh.vbo, rsurface_model->surfmesh.vbooffset_lightmapcolor4f);
        }
 
        if (rsurface_uselightmaptexture && !(rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT))
                RSurf_DrawBatch_WithLightmapSwitching(texturenumsurfaces, texturesurfacelist, 7, r_glsl_permutation->loc_Texture_Deluxemap >= 0 ? 8 : -1);
        else
                RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist);
-       if (rsurface_texture->backgroundnumskinframes && !(rsurface_texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT))
+       if (rsurface_texture->backgroundnumskinframes && !(rsurface_texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED))
        {
        }
 }
@@ -3643,10 +3750,14 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, msurface_t **t
                        memset(&m, 0, sizeof(m));
                        m.tex[0] = R_GetTexture(r_texture_white);
                        m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordlightmap2f;
+                       m.pointer_texcoord_bufferobject[0] = rsurface_model->surfmesh.vbo;
+                       m.pointer_texcoord_bufferoffset[0] = rsurface_model->surfmesh.vbooffset_texcoordlightmap2f;
                        m.tex[1] = R_GetTexture(layer->texture);
                        m.texmatrix[1] = layer->texmatrix;
                        m.texrgbscale[1] = layertexrgbscale;
                        m.pointer_texcoord[1] = rsurface_model->surfmesh.data_texcoordtexture2f;
+                       m.pointer_texcoord_bufferobject[1] = rsurface_model->surfmesh.vbo;
+                       m.pointer_texcoord_bufferoffset[1] = rsurface_model->surfmesh.vbooffset_texcoordtexture2f;
                        R_Mesh_TextureState(&m);
                        if (rsurface_lightmode == 2)
                                RSurf_DrawBatch_GL11_VertexShade(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
@@ -3661,6 +3772,8 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, msurface_t **t
                        m.texmatrix[0] = layer->texmatrix;
                        m.texrgbscale[0] = layertexrgbscale;
                        m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
+                       m.pointer_texcoord_bufferobject[0] = rsurface_model->surfmesh.vbo;
+                       m.pointer_texcoord_bufferoffset[0] = rsurface_model->surfmesh.vbooffset_texcoordtexture2f;
                        R_Mesh_TextureState(&m);
                        RSurf_DrawBatch_GL11_Unlit(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog);
                        break;
@@ -3672,6 +3785,8 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, msurface_t **t
                                m.tex[0] = R_GetTexture(layer->texture);
                                m.texmatrix[0] = layer->texmatrix;
                                m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
+                               m.pointer_texcoord_bufferobject[0] = rsurface_model->surfmesh.vbo;
+                               m.pointer_texcoord_bufferoffset[0] = rsurface_model->surfmesh.vbooffset_texcoordtexture2f;
                        }
                        R_Mesh_TextureState(&m);
                        // generate a color array for the fog pass
@@ -3742,6 +3857,8 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, msurface_t **t
                                memset(&m, 0, sizeof(m));
                                m.tex[0] = R_GetTexture(r_texture_white);
                                m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordlightmap2f;
+                               m.pointer_texcoord_bufferobject[0] = rsurface_model->surfmesh.vbo;
+                               m.pointer_texcoord_bufferoffset[0] = rsurface_model->surfmesh.vbooffset_texcoordlightmap2f;
                                R_Mesh_TextureState(&m);
                                if (rsurface_lightmode == 2)
                                        RSurf_DrawBatch_GL11_VertexShade(texturenumsurfaces, texturesurfacelist, 1, 1, 1, 1, false, false);
@@ -3756,6 +3873,8 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, msurface_t **t
                                m.tex[0] = R_GetTexture(layer->texture);
                                m.texmatrix[0] = layer->texmatrix;
                                m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
+                               m.pointer_texcoord_bufferobject[0] = rsurface_model->surfmesh.vbo;
+                               m.pointer_texcoord_bufferoffset[0] = rsurface_model->surfmesh.vbooffset_texcoordtexture2f;
                                R_Mesh_TextureState(&m);
                                RSurf_DrawBatch_GL11_Unlit(texturenumsurfaces, texturesurfacelist, layer->color[0] * 0.5f, layer->color[1] * 0.5f, layer->color[2] * 0.5f, layer->color[3], layer->color[0] != 2 || layer->color[1] != 2 || layer->color[2] != 2 || layer->color[3] != 1, false);
                        }
@@ -3766,6 +3885,8 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, msurface_t **t
                                m.tex[0] = R_GetTexture(layer->texture);
                                m.texmatrix[0] = layer->texmatrix;
                                m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
+                               m.pointer_texcoord_bufferobject[0] = rsurface_model->surfmesh.vbo;
+                               m.pointer_texcoord_bufferoffset[0] = rsurface_model->surfmesh.vbooffset_texcoordtexture2f;
                                R_Mesh_TextureState(&m);
                                if (rsurface_lightmode == 2)
                                        RSurf_DrawBatch_GL11_VertexShade(texturenumsurfaces, texturesurfacelist, layer->color[0], layer->color[1], layer->color[2], layer->color[3], layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog);
@@ -3779,6 +3900,8 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, msurface_t **t
                        m.tex[0] = R_GetTexture(layer->texture);
                        m.texmatrix[0] = layer->texmatrix;
                        m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
+                       m.pointer_texcoord_bufferobject[0] = rsurface_model->surfmesh.vbo;
+                       m.pointer_texcoord_bufferoffset[0] = rsurface_model->surfmesh.vbooffset_texcoordtexture2f;
                        R_Mesh_TextureState(&m);
                        RSurf_DrawBatch_GL11_Unlit(texturenumsurfaces, texturesurfacelist, layer->color[0], layer->color[1], layer->color[2], layer->color[3], layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog);
                        break;
@@ -3791,6 +3914,8 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, msurface_t **t
                                m.tex[0] = R_GetTexture(layer->texture);
                                m.texmatrix[0] = layer->texmatrix;
                                m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f;
+                               m.pointer_texcoord_bufferobject[0] = rsurface_model->surfmesh.vbo;
+                               m.pointer_texcoord_bufferoffset[0] = rsurface_model->surfmesh.vbooffset_texcoordtexture2f;
                                R_Mesh_TextureState(&m);
                        }
                        else
@@ -3838,6 +3963,7 @@ static void R_DrawTextureSurfaceList(int texturenumsurfaces, msurface_t **textur
                R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist);
        else if (rsurface_texture->currentnumlayers)
        {
+               GL_DepthRange(0, (rsurface_texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1);
                GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST));
                GL_CullFace((rsurface_texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces
                GL_BlendFunc(rsurface_texture->currentlayers[0].blendfunc1, rsurface_texture->currentlayers[0].blendfunc2);
@@ -3924,7 +4050,7 @@ void R_QueueSurfaceList(int numsurfaces, msurface_t **surfacelist, int flagsmask
                                ;
                        continue;
                }
-               if (rsurface_texture->currentmaterialflags & MATERIALFLAG_BLENDED)
+               if (rsurface_texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED)
                {
                        // transparent surfaces get pushed off into the transparent queue
                        const msurface_t *surface = surfacelist[i];
@@ -3974,6 +4100,7 @@ void R_DrawLoc_Callback(const entity_render_t *ent, const rtlight_t *rtlight, in
        CHECKGLERROR
        GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        GL_DepthMask(false);
+       GL_DepthRange(0, 1);
        GL_DepthTest(true);
        GL_CullFace(GL_NONE);
        R_Mesh_Matrix(&identitymatrix);
@@ -4032,6 +4159,7 @@ void R_DrawCollisionBrushes(entity_render_t *ent)
        R_Mesh_ResetTextureState();
        GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
        GL_DepthMask(false);
+       GL_DepthRange(0, 1);
        GL_DepthTest(!r_showdisabledepthtest.integer);
        qglPolygonOffset(r_refdef.polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_refdef.polygonoffset + r_showcollisionbrushes_polygonoffset.value);CHECKGLERROR
        for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
@@ -4051,6 +4179,7 @@ void R_DrawTrianglesAndNormals(entity_render_t *ent, qboolean drawtris, qboolean
        model_t *model = ent->model;
        vec3_t v;
        CHECKGLERROR
+       GL_DepthRange(0, 1);
        GL_DepthTest(!r_showdisabledepthtest.integer);
        GL_DepthMask(true);
        GL_BlendFunc(GL_ONE, GL_ZERO);