implemented uint16 element array support, and use of it for all the
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 10 Apr 2008 07:03:36 +0000 (07:03 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 10 Apr 2008 07:03:36 +0000 (07:03 +0000)
engine-generated geometry (particles, skybox, text, etc), as well as for
any map or model that fits the 65536 vertex limit (this can be disabled
for performance testing using the cvar gl_mesh_prefer_short_elements),
this hopefully improves performance on Radeon 9500-X300 cards and
GeForce1/2 cards which don't support uint32 elements

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8252 d7cf8633-e32d-0410-b094-e92efae38249

19 files changed:
cl_particles.c
cl_screen.c
clvm_cmds.c
draw.h
gl_backend.c
gl_backend.h
gl_draw.c
gl_rmain.c
gl_rsurf.c
model_alias.c
model_brush.c
model_shared.c
model_shared.h
r_explosion.c
r_lightning.c
r_shadow.c
r_shadow.h
r_sky.c
render.h

index 4b4cd1d..7107154 100644 (file)
@@ -1910,19 +1910,19 @@ static void r_part_newmap(void)
 }
 
 #define BATCHSIZE 256
-int particle_element3i[BATCHSIZE*6];
+unsigned short particle_elements[BATCHSIZE*6];
 
 void R_Particles_Init (void)
 {
        int i;
        for (i = 0;i < BATCHSIZE;i++)
        {
-               particle_element3i[i*6+0] = i*4+0;
-               particle_element3i[i*6+1] = i*4+1;
-               particle_element3i[i*6+2] = i*4+2;
-               particle_element3i[i*6+3] = i*4+0;
-               particle_element3i[i*6+4] = i*4+2;
-               particle_element3i[i*6+5] = i*4+3;
+               particle_elements[i*6+0] = i*4+0;
+               particle_elements[i*6+1] = i*4+1;
+               particle_elements[i*6+2] = i*4+2;
+               particle_elements[i*6+3] = i*4+0;
+               particle_elements[i*6+4] = i*4+2;
+               particle_elements[i*6+5] = i*4+3;
        }
 
        Cvar_RegisterVariable(&r_drawparticles);
@@ -2003,7 +2003,7 @@ void R_DrawDecal_TransparentCallback(const entity_render_t *ent, const rtlight_t
        GL_BlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
        R_Mesh_TexBind(0, R_GetTexture(particletexture[63].texture));
        GL_LockArrays(0, numsurfaces*4);
-       R_Mesh_Draw(0, numsurfaces * 4, numsurfaces * 2, particle_element3i, 0, 0);
+       R_Mesh_Draw(0, numsurfaces * 4, 0, numsurfaces * 2, NULL, particle_elements, 0, 0);
        GL_LockArrays(0, 0);
 }
 
@@ -2260,7 +2260,7 @@ void R_DrawParticle_TransparentCallback(const entity_render_t *ent, const rtligh
                }
 
                batchcount = surfacelistindex - batchstart;
-               R_Mesh_Draw(batchstart * 4, batchcount * 4, batchcount * 2, particle_element3i + batchstart * 6, 0, 0);
+               R_Mesh_Draw(batchstart * 4, batchcount * 4, batchstart * 2, batchcount * 2, NULL, particle_elements, 0, 0);
        }
        GL_LockArrays(0, 0);
 }
index d3794fb..6a127f5 100644 (file)
@@ -2081,14 +2081,14 @@ void SCR_UpdateLoadingScreen (qboolean clear)
        if (vid.stereobuffer)
        {
                qglDrawBuffer(GL_FRONT_LEFT);
-               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+               R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
                qglDrawBuffer(GL_FRONT_RIGHT);
-               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+               R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
        }
        else
        {
                qglDrawBuffer(GL_FRONT);
-               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+               R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
        }
        R_Mesh_Finish();
        // refresh
index 67a219b..b14caee 100644 (file)
@@ -2298,7 +2298,7 @@ typedef struct vmpolygons_triangle_s
 {
        rtexture_t              *texture;
        int                             drawflag;
-       int                             element3i[3];
+       unsigned short  elements[3];
 }vmpolygons_triangle_t;
 
 typedef struct vmpolygons_s
@@ -2315,7 +2315,7 @@ typedef struct vmpolygons_s
        int                             max_triangles;
        int                             num_triangles;
        vmpolygons_triangle_t *data_triangles;
-       int                             *data_sortedelement3i;
+       unsigned short  *data_sortedelement3s;
 
        qboolean                begin_active;
        rtexture_t              *begin_texture;
@@ -2352,13 +2352,13 @@ static void VM_ResizePolygons(vmpolygons_t *polys)
        float *oldcolor4f = polys->data_color4f;
        float *oldtexcoord2f = polys->data_texcoord2f;
        vmpolygons_triangle_t *oldtriangles = polys->data_triangles;
-       int *oldsortedelement3i = polys->data_sortedelement3i;
-       polys->max_vertices = polys->max_triangles*3;
+       unsigned short *oldsortedelement3s = polys->data_sortedelement3s;
+       polys->max_vertices = min(polys->max_triangles*3, 65536);
        polys->data_vertex3f = (float *)Mem_Alloc(polys->pool, polys->max_vertices*sizeof(float[3]));
        polys->data_color4f = (float *)Mem_Alloc(polys->pool, polys->max_vertices*sizeof(float[4]));
        polys->data_texcoord2f = (float *)Mem_Alloc(polys->pool, polys->max_vertices*sizeof(float[2]));
        polys->data_triangles = (vmpolygons_triangle_t *)Mem_Alloc(polys->pool, polys->max_triangles*sizeof(vmpolygons_triangle_t));
-       polys->data_sortedelement3i = (int *)Mem_Alloc(polys->pool, polys->max_triangles*sizeof(int[3]));
+       polys->data_sortedelement3s = (unsigned short *)Mem_Alloc(polys->pool, polys->max_triangles*sizeof(unsigned short[3]));
        if (polys->num_vertices)
        {
                memcpy(polys->data_vertex3f, oldvertex3f, polys->num_vertices*sizeof(float[3]));
@@ -2368,7 +2368,7 @@ static void VM_ResizePolygons(vmpolygons_t *polys)
        if (polys->num_triangles)
        {
                memcpy(polys->data_triangles, oldtriangles, polys->num_triangles*sizeof(vmpolygons_triangle_t));
-               memcpy(polys->data_sortedelement3i, oldsortedelement3i, polys->num_triangles*sizeof(int[3]));
+               memcpy(polys->data_sortedelement3s, oldsortedelement3s, polys->num_triangles*sizeof(unsigned short[3]));
        }
        if (oldvertex3f)
                Mem_Free(oldvertex3f);
@@ -2378,8 +2378,8 @@ static void VM_ResizePolygons(vmpolygons_t *polys)
                Mem_Free(oldtexcoord2f);
        if (oldtriangles)
                Mem_Free(oldtriangles);
-       if (oldsortedelement3i)
-               Mem_Free(oldsortedelement3i);
+       if (oldsortedelement3s)
+               Mem_Free(oldsortedelement3s);
 }
 
 static void VM_InitPolygons (vmpolygons_t* polys)
@@ -2420,10 +2420,10 @@ static void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t
                {
                        if (polys->data_triangles[surfacelist[surfacelistindex]].texture != tex || polys->data_triangles[surfacelist[surfacelistindex]].drawflag != drawflag)
                                break;
-                       VectorCopy(polys->data_triangles[surfacelist[surfacelistindex]].element3i, polys->data_sortedelement3i + 3*numtriangles);
+                       VectorCopy(polys->data_triangles[surfacelist[surfacelistindex]].elements, polys->data_sortedelement3s + 3*numtriangles);
                        numtriangles++;
                }
-               R_Mesh_Draw(0, polys->num_vertices, numtriangles, polys->data_sortedelement3i, 0, 0);
+               R_Mesh_Draw(0, polys->num_vertices, 0, numtriangles, NULL, polys->data_sortedelement3s, 0, 0);
        }
 }
 
@@ -2436,7 +2436,7 @@ void VMPolygons_Store(vmpolygons_t *polys)
                mesh.texture = polys->begin_texture;
                mesh.num_vertices = polys->begin_vertices;
                mesh.num_triangles = polys->begin_vertices-2;
-               mesh.data_element3i = polygonelements;
+               mesh.data_element3s = polygonelements;
                mesh.data_vertex3f = polys->begin_vertex[0];
                mesh.data_color4f = polys->begin_color[0];
                mesh.data_texcoord2f = polys->begin_texcoord[0];
@@ -2451,23 +2451,26 @@ void VMPolygons_Store(vmpolygons_t *polys)
                        polys->max_triangles *= 2;
                        VM_ResizePolygons(polys);
                }
-               // needle in a haystack!
-               // polys->num_vertices was used for copying where we actually want to copy begin_vertices
-               // that also caused it to not render the first polygon that is added
-               // --blub
-               memcpy(polys->data_vertex3f + polys->num_vertices * 3, polys->begin_vertex[0], polys->begin_vertices * sizeof(float[3]));
-               memcpy(polys->data_color4f + polys->num_vertices * 4, polys->begin_color[0], polys->begin_vertices * sizeof(float[4]));
-               memcpy(polys->data_texcoord2f + polys->num_vertices * 2, polys->begin_texcoord[0], polys->begin_vertices * sizeof(float[2]));
-               for (i = 0;i < polys->begin_vertices-2;i++)
+               if (polys->num_vertices + polys->begin_vertices <= polys->max_vertices)
                {
-                       polys->data_triangles[polys->num_triangles].texture = polys->begin_texture;
-                       polys->data_triangles[polys->num_triangles].drawflag = polys->begin_drawflag;
-                       polys->data_triangles[polys->num_triangles].element3i[0] = polys->num_vertices;
-                       polys->data_triangles[polys->num_triangles].element3i[1] = polys->num_vertices + i+1;
-                       polys->data_triangles[polys->num_triangles].element3i[2] = polys->num_vertices + i+2;
-                       polys->num_triangles++;
+                       // needle in a haystack!
+                       // polys->num_vertices was used for copying where we actually want to copy begin_vertices
+                       // that also caused it to not render the first polygon that is added
+                       // --blub
+                       memcpy(polys->data_vertex3f + polys->num_vertices * 3, polys->begin_vertex[0], polys->begin_vertices * sizeof(float[3]));
+                       memcpy(polys->data_color4f + polys->num_vertices * 4, polys->begin_color[0], polys->begin_vertices * sizeof(float[4]));
+                       memcpy(polys->data_texcoord2f + polys->num_vertices * 2, polys->begin_texcoord[0], polys->begin_vertices * sizeof(float[2]));
+                       for (i = 0;i < polys->begin_vertices-2;i++)
+                       {
+                               polys->data_triangles[polys->num_triangles].texture = polys->begin_texture;
+                               polys->data_triangles[polys->num_triangles].drawflag = polys->begin_drawflag;
+                               polys->data_triangles[polys->num_triangles].elements[0] = polys->num_vertices;
+                               polys->data_triangles[polys->num_triangles].elements[1] = polys->num_vertices + i+1;
+                               polys->data_triangles[polys->num_triangles].elements[2] = polys->num_vertices + i+2;
+                               polys->num_triangles++;
+                       }
+                       polys->num_vertices += polys->begin_vertices;
                }
-               polys->num_vertices += polys->begin_vertices;
        }
        polys->begin_active = false;
 }
@@ -2489,7 +2492,7 @@ void VM_CL_AddPolygonsToMeshQueue (void)
 
        for (i = 0;i < polys->num_triangles;i++)
        {
-               VectorMAMAM(1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].element3i[0], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].element3i[1], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].element3i[2], center);
+               VectorMAMAM(1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[0], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[1], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[2], center);
                R_MeshQueue_AddTransparent(center, VM_DrawPolygonCallback, NULL, i, NULL);
        }
 
diff --git a/draw.h b/draw.h
index 992fc3d..17c366b 100644 (file)
--- a/draw.h
+++ b/draw.h
@@ -63,7 +63,7 @@ typedef struct drawqueuemesh_s
        rtexture_t *texture;
        int num_triangles;
        int num_vertices;
-       int *data_element3i;
+       unsigned short *data_element3s;
        float *data_vertex3f;
        float *data_texcoord2f;
        float *data_color4f;
index fc9f718..871a6a0 100644 (file)
@@ -5,6 +5,7 @@
 cvar_t gl_mesh_drawrangeelements = {0, "gl_mesh_drawrangeelements", "1", "use glDrawRangeElements function if available instead of glDrawElements (for performance comparisons or bug testing)"};
 cvar_t gl_mesh_testarrayelement = {0, "gl_mesh_testarrayelement", "0", "use glBegin(GL_TRIANGLES);glArrayElement();glEnd(); primitives instead of glDrawElements (useful to test for driver bugs with glDrawElements)"};
 cvar_t gl_mesh_testmanualfeeding = {0, "gl_mesh_testmanualfeeding", "0", "use glBegin(GL_TRIANGLES);glTexCoord2f();glVertex3f();glEnd(); primitives instead of glDrawElements (useful to test for driver bugs with glDrawElements)"};
+cvar_t gl_mesh_prefer_short_elements = {0, "gl_mesh_prefer_short_elements", "1", "use GL_UNSIGNED_SHORT element arrays instead of GL_UNSIGNED_INT"};
 cvar_t gl_paranoid = {0, "gl_paranoid", "0", "enables OpenGL error checking and other tests"};
 cvar_t gl_printcheckerror = {0, "gl_printcheckerror", "0", "prints all OpenGL error checks, useful to identify location of driver crashes"};
 
@@ -136,8 +137,8 @@ for (y = 0;y < rows - 1;y++)
 }
 */
 
-int polygonelements[(POLYGONELEMENTS_MAXPOINTS-2)*3];
-int quadelements[QUADELEMENTS_MAXQUADS*6];
+unsigned short polygonelements[(POLYGONELEMENTS_MAXPOINTS-2)*3];
+unsigned short quadelements[QUADELEMENTS_MAXQUADS*6];
 
 void GL_Backend_AllocArrays(void)
 {
@@ -261,6 +262,7 @@ void gl_backend_init(void)
        Cvar_RegisterVariable(&gl_mesh_drawrangeelements);
        Cvar_RegisterVariable(&gl_mesh_testarrayelement);
        Cvar_RegisterVariable(&gl_mesh_testmanualfeeding);
+       Cvar_RegisterVariable(&gl_mesh_prefer_short_elements);
 
        Cmd_AddCommand("gl_vbostats", GL_VBOStats_f, "prints a list of all buffer objects (vertex data and triangle elements) and total video memory used by them");
 
@@ -1083,16 +1085,22 @@ void GL_Backend_RenumberElements(int *out, int count, const int *in, int offset)
 
 // renders triangles using vertices from the active arrays
 int paranoidblah = 0;
-void R_Mesh_Draw(int firstvertex, int numvertices, int numtriangles, const int *elements, int bufferobject, size_t bufferoffset)
+void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int bufferobject3i, int bufferobject3s)
 {
        unsigned int numelements = numtriangles * 3;
        if (numvertices < 3 || numtriangles < 1)
        {
-               Con_Printf("R_Mesh_Draw(%d, %d, %d, %8p, %i, %p);\n", firstvertex, numvertices, numtriangles, elements, bufferobject, (void *)bufferoffset);
+               Con_Printf("R_Mesh_Draw(%d, %d, %d, %d, %8p, %8p, %i, %i);\n", firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, bufferobject3i, bufferobject3s);
                return;
        }
+       if (!gl_mesh_prefer_short_elements.integer && element3i)
+               element3s = NULL;
+       if (element3i)
+               element3i += firsttriangle * 3;
+       if (element3s)
+               element3s += firsttriangle * 3;
        if (gl_vbo.integer != 1)
-               bufferobject = 0;
+               bufferobject3i = bufferobject3s = 0;
        CHECKGLERROR
        r_refdef.stats.meshes++;
        r_refdef.stats.meshes_elements += numelements;
@@ -1133,12 +1141,26 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int numtriangles, const int *
                                                paranoidblah += *p;
                        }
                }
-               for (i = 0;i < (unsigned int) numtriangles * 3;i++)
+               if (element3i)
+               {
+                       for (i = 0;i < (unsigned int) numtriangles * 3;i++)
+                       {
+                               if (element3i[i] < firstvertex || element3i[i] >= firstvertex + numvertices)
+                               {
+                                       Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3i array\n", element3i[i], firstvertex, firstvertex + numvertices);
+                                       return;
+                               }
+                       }
+               }
+               if (element3s)
                {
-                       if (elements[i] < firstvertex || elements[i] >= firstvertex + numvertices)
+                       for (i = 0;i < (unsigned int) numtriangles * 3;i++)
                        {
-                               Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in elements list\n", elements[i], firstvertex, firstvertex + numvertices);
-                               return;
+                               if (element3s[i] < firstvertex || element3s[i] >= firstvertex + numvertices)
+                               {
+                                       Con_Printf("R_Mesh_Draw: invalid vertex index %i (outside range %i - %i) in element3s array\n", element3s[i], firstvertex, firstvertex + numvertices);
+                                       return;
+                               }
                        }
                }
                CHECKGLERROR
@@ -1148,11 +1170,12 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int numtriangles, const int *
                CHECKGLERROR
                if (gl_mesh_testmanualfeeding.integer)
                {
-                       unsigned int i, j;
+                       unsigned int i, j, element;
                        const GLfloat *p;
                        qglBegin(GL_TRIANGLES);
                        for (i = 0;i < (unsigned int) numtriangles * 3;i++)
                        {
+                               element = element3i ? element3i[i] : element3s[i];
                                for (j = 0;j < backendarrayunits;j++)
                                {
                                        if (gl_state.units[j].pointer_texcoord && gl_state.units[j].arrayenabled)
@@ -1161,22 +1184,22 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int numtriangles, const int *
                                                {
                                                        if (gl_state.units[j].arraycomponents == 4)
                                                        {
-                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 4;
+                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + element * 4;
                                                                qglMultiTexCoord4f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2], p[3]);
                                                        }
                                                        else if (gl_state.units[j].arraycomponents == 3)
                                                        {
-                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 3;
+                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + element * 3;
                                                                qglMultiTexCoord3f(GL_TEXTURE0_ARB + j, p[0], p[1], p[2]);
                                                        }
                                                        else if (gl_state.units[j].arraycomponents == 2)
                                                        {
-                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 2;
+                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + element * 2;
                                                                qglMultiTexCoord2f(GL_TEXTURE0_ARB + j, p[0], p[1]);
                                                        }
                                                        else
                                                        {
-                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 1;
+                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + element * 1;
                                                                qglMultiTexCoord1f(GL_TEXTURE0_ARB + j, p[0]);
                                                        }
                                                }
@@ -1184,22 +1207,22 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int numtriangles, const int *
                                                {
                                                        if (gl_state.units[j].arraycomponents == 4)
                                                        {
-                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 4;
+                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + element * 4;
                                                                qglTexCoord4f(p[0], p[1], p[2], p[3]);
                                                        }
                                                        else if (gl_state.units[j].arraycomponents == 3)
                                                        {
-                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 3;
+                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + element * 3;
                                                                qglTexCoord3f(p[0], p[1], p[2]);
                                                        }
                                                        else if (gl_state.units[j].arraycomponents == 2)
                                                        {
-                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 2;
+                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + element * 2;
                                                                qglTexCoord2f(p[0], p[1]);
                                                        }
                                                        else
                                                        {
-                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + elements[i] * 1;
+                                                               p = ((const GLfloat *)(gl_state.units[j].pointer_texcoord)) + element * 1;
                                                                qglTexCoord1f(p[0]);
                                                        }
                                                }
@@ -1207,10 +1230,10 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int numtriangles, const int *
                                }
                                if (gl_state.pointer_color && gl_state.pointer_color_enabled)
                                {
-                                       p = ((const GLfloat *)(gl_state.pointer_color)) + elements[i] * 4;
+                                       p = ((const GLfloat *)(gl_state.pointer_color)) + element * 4;
                                        qglColor4f(p[0], p[1], p[2], p[3]);
                                }
-                               p = ((const GLfloat *)(gl_state.pointer_vertex)) + elements[i] * 3;
+                               p = ((const GLfloat *)(gl_state.pointer_vertex)) + element * 3;
                                qglVertex3f(p[0], p[1], p[2]);
                        }
                        qglEnd();
@@ -1220,24 +1243,74 @@ void R_Mesh_Draw(int firstvertex, int numvertices, int numtriangles, const int *
                {
                        int i;
                        qglBegin(GL_TRIANGLES);
-                       for (i = 0;i < numtriangles * 3;i++)
+                       if (element3i)
+                       {
+                               for (i = 0;i < numtriangles * 3;i++)
+                                       qglArrayElement(element3i[i]);
+                       }
+                       else if (element3s)
                        {
-                               qglArrayElement(elements[i]);
+                               for (i = 0;i < numtriangles * 3;i++)
+                                       qglArrayElement(element3s[i]);
                        }
                        qglEnd();
                        CHECKGLERROR
                }
-               else if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
+               else if (bufferobject3s)
                {
-                       GL_BindEBO(bufferobject);
-                       qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices, numelements, GL_UNSIGNED_INT, bufferobject ? (void *)bufferoffset : elements);
-                       CHECKGLERROR
+                       GL_BindEBO(bufferobject3s);
+                       if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
+                       {
+                               qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
+                               CHECKGLERROR
+                       }
+                       else
+                       {
+                               qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, (void *)(firsttriangle * sizeof(unsigned short[3])));
+                               CHECKGLERROR
+                       }
                }
-               else
+               else if (bufferobject3i)
                {
-                       GL_BindEBO(bufferobject);
-                       qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, bufferobject ? (void *)bufferoffset : elements);
-                       CHECKGLERROR
+                       GL_BindEBO(bufferobject3i);
+                       if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
+                       {
+                               qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
+                               CHECKGLERROR
+                       }
+                       else
+                       {
+                               qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, (void *)(firsttriangle * sizeof(unsigned int[3])));
+                               CHECKGLERROR
+                       }
+               }
+               else if (element3s)
+               {
+                       GL_BindEBO(0);
+                       if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
+                       {
+                               qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices, numelements, GL_UNSIGNED_SHORT, element3s);
+                               CHECKGLERROR
+                       }
+                       else
+                       {
+                               qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_SHORT, element3s);
+                               CHECKGLERROR
+                       }
+               }
+               else if (element3i)
+               {
+                       GL_BindEBO(0);
+                       if (gl_mesh_drawrangeelements.integer && qglDrawRangeElements != NULL)
+                       {
+                               qglDrawRangeElements(GL_TRIANGLES, firstvertex, firstvertex + numvertices, numelements, GL_UNSIGNED_INT, element3i);
+                               CHECKGLERROR
+                       }
+                       else
+                       {
+                               qglDrawElements(GL_TRIANGLES, numelements, GL_UNSIGNED_INT, element3i);
+                               CHECKGLERROR
+                       }
                }
        }
 }
index 8561d82..5ecff60 100644 (file)
@@ -6,9 +6,9 @@
 #define MAX_TEXTUREUNITS 64
 
 #define POLYGONELEMENTS_MAXPOINTS 258
-extern int polygonelements[(POLYGONELEMENTS_MAXPOINTS-2)*3];
+extern unsigned short polygonelements[(POLYGONELEMENTS_MAXPOINTS-2)*3];
 #define QUADELEMENTS_MAXQUADS 128
-extern int quadelements[QUADELEMENTS_MAXQUADS*6];
+extern unsigned short quadelements[QUADELEMENTS_MAXQUADS*6];
 
 void GL_SetupView_Orientation_Identity(void);
 void GL_SetupView_Orientation_FromEntity(const matrix4x4_t *matrix);
@@ -114,7 +114,7 @@ void R_Mesh_TextureState(const rmeshstate_t *m);
 void R_Mesh_ResetTextureState(void);
 
 // renders a mesh
-void R_Mesh_Draw(int firstvertex, int numvertices, int numtriangles, const int *elements, int bufferobject, size_t bufferoffset);
+void R_Mesh_Draw(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int bufferobject3i, int bufferobject3s);
 
 // saves a section of the rendered frame to a .tga or .jpg file
 qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *buffer2, unsigned char *buffer3, int x, int y, int width, int height, qboolean flipx, qboolean flipy, qboolean flipdiagonal, qboolean jpeg, qboolean gammacorrect);
index 01ac77b..cf16422 100644 (file)
--- a/gl_draw.c
+++ b/gl_draw.c
@@ -827,7 +827,7 @@ void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, flo
        floats[3] = floats[6] = x + width;
        floats[7] = floats[10] = y + height;
 
-       R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+       R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
 }
 
 void DrawQ_Fill(float x, float y, float width, float height, float red, float green, float blue, float alpha, int flags)
@@ -848,7 +848,7 @@ void DrawQ_Fill(float x, float y, float width, float height, float red, float gr
        floats[3] = floats[6] = x + width;
        floats[7] = floats[10] = y + height;
 
-       R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+       R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
 }
 
 // color tag printing
@@ -1039,7 +1039,7 @@ float DrawQ_String_Font(float startx, float starty, const char *text, size_t max
                        if (batchcount >= QUADELEMENTS_MAXQUADS)
                        {
                                GL_LockArrays(0, batchcount * 4);
-                               R_Mesh_Draw(0, batchcount * 4, batchcount * 2, quadelements, 0, 0);
+                               R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, NULL, quadelements, 0, 0);
                                GL_LockArrays(0, 0);
                                batchcount = 0;
                                ac = color4f;
@@ -1052,7 +1052,7 @@ float DrawQ_String_Font(float startx, float starty, const char *text, size_t max
        if (batchcount > 0)
        {
                GL_LockArrays(0, batchcount * 4);
-               R_Mesh_Draw(0, batchcount * 4, batchcount * 2, quadelements, 0, 0);
+               R_Mesh_Draw(0, batchcount * 4, 0, batchcount * 2, NULL, quadelements, 0, 0);
                GL_LockArrays(0, 0);
        }
 
@@ -1151,7 +1151,7 @@ void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height
        floats[28] = r4;floats[29] = g4;floats[30] = b4;floats[31] = a4;
        floats[32] = r3;floats[33] = g3;floats[34] = b3;floats[35] = a3;
 
-       R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+       R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
 }
 
 void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags)
@@ -1166,7 +1166,7 @@ void DrawQ_Mesh (drawqueuemesh_t *mesh, int flags)
        R_SetupGenericShader(mesh->texture != NULL);
 
        GL_LockArrays(0, mesh->num_vertices);
-       R_Mesh_Draw(0, mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, 0, 0);
+       R_Mesh_Draw(0, mesh->num_vertices, 0, mesh->num_triangles, NULL, mesh->data_element3s, 0, 0);
        GL_LockArrays(0, 0);
 }
 
@@ -1195,7 +1195,7 @@ void DrawQ_Line (float width, float x1, float y1, float x2, float y2, float r, f
        _DrawQ_ProcessDrawFlag(flags);
 
        R_SetupGenericShader(false);
-       
+
        CHECKGLERROR
        qglLineWidth(width);CHECKGLERROR
 
@@ -1259,7 +1259,7 @@ void R_DrawGamma(void)
                        while (c[0] >= 1.01f || c[1] >= 1.01f || c[2] >= 1.01f)
                        {
                                GL_Color(bound(0, c[0] - 1, 1), bound(0, c[1] - 1, 1), bound(0, c[2] - 1, 1), 1);
-                               R_Mesh_Draw(0, 3, 1, polygonelements, 0, 0);
+                               R_Mesh_Draw(0, 3, 0, 1, NULL, polygonelements, 0, 0);
                                VectorScale(c, 0.5, c);
                        }
                }
@@ -1275,7 +1275,7 @@ void R_DrawGamma(void)
                {
                        GL_BlendFunc(GL_ONE, GL_ONE);
                        GL_Color(c[0], c[1], c[2], 1);
-                       R_Mesh_Draw(0, 3, 1, polygonelements, 0, 0);
+                       R_Mesh_Draw(0, 3, 0, 1, NULL, polygonelements, 0, 0);
                }
        }
 }
index 658858d..7686425 100644 (file)
@@ -3179,7 +3179,7 @@ void R_Bloom_CopyBloomTexture(float colorscale)
        R_SetupGenericShader(true);
        R_Mesh_TexCoordPointer(0, 2, r_bloomstate.screentexcoord2f, 0, 0);
        R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_screen));
-       R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+       R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
        r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
 
        // we now have a bloom image in the framebuffer
@@ -3224,7 +3224,7 @@ void R_Bloom_MakeTexture(void)
                GL_Color(r, r, r, 1);
                R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom));
                R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f, 0, 0);
-               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+               R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
                r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
 
                // copy the vertically blurred bloom view to a texture
@@ -3268,7 +3268,7 @@ void R_Bloom_MakeTexture(void)
                        //r = (dir ? 1.0f : brighten)/(range*2+1);
                        r = (dir ? 1.0f : brighten)/(range*2+1)*(1 - x*x/(float)(range*range));
                        GL_Color(r, r, r, 1);
-                       R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+                       R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
                        r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
                        GL_BlendFunc(GL_ONE, GL_ONE);
                }
@@ -3288,7 +3288,7 @@ void R_Bloom_MakeTexture(void)
                R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom));
                R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f, 0, 0);
                GL_Color(1, 1, 1, 1);
-               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+               R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
                r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
 
                GL_BlendFunc(GL_ONE, GL_ONE);
@@ -3296,7 +3296,7 @@ void R_Bloom_MakeTexture(void)
                R_Mesh_TexBind(0, R_GetTexture(r_texture_white));
                R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f, 0, 0);
                GL_Color(r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 1);
-               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+               R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
                r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight;
                qglBlendEquationEXT(GL_FUNC_ADD_EXT);
 
@@ -3425,7 +3425,7 @@ static void R_BlendView(void)
                        sscanf(r_glsl_postprocess_uservec4.string, "%f %f %f %f", &a, &b, &c, &d);
                        qglUniform4fARB(r_glsl_permutation->loc_UserVec4, a, b, c, d);
                }
-               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+               R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
                r_refdef.stats.bloom_drawpixels += r_refdef.view.width * r_refdef.view.height;
                return;
        }
@@ -3445,7 +3445,7 @@ static void R_BlendView(void)
                GL_BlendFunc(GL_ONE, GL_ONE);
                R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom));
                R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f, 0, 0);
-               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+               R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
                r_refdef.stats.bloom_drawpixels += r_refdef.view.width * r_refdef.view.height;
        }
        else if (r_bloomstate.texture_bloom)
@@ -3474,14 +3474,14 @@ static void R_BlendView(void)
                else
                {
                        R_SetupGenericShader(true);
-                       R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+                       R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
                        r_refdef.stats.bloom_drawpixels += r_refdef.view.width * r_refdef.view.height;
                        // now blend on the bloom texture
                        GL_BlendFunc(GL_ONE, GL_ONE);
                        R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_screen));
                        R_Mesh_TexCoordPointer(0, 2, r_bloomstate.screentexcoord2f, 0, 0);
                }
-               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+               R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
                r_refdef.stats.bloom_drawpixels += r_refdef.view.width * r_refdef.view.height;
        }
        if (r_refdef.viewblend[3] >= (1.0f / 256.0f))
@@ -3493,7 +3493,7 @@ static void R_BlendView(void)
                R_SetupGenericShader(false);
                GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]);
-               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+               R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
        }
 }
 
@@ -3958,7 +3958,7 @@ void R_RenderScene(qboolean addwaterplanes)
        R_ResetViewRendering2D();
 }
 
-static const int bboxelements[36] =
+static const unsigned short bboxelements[36] =
 {
        5, 1, 3, 5, 3, 7,
        6, 2, 0, 6, 0, 4,
@@ -4003,7 +4003,7 @@ void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, floa
        R_Mesh_ColorPointer(color4f, 0, 0);
        R_Mesh_ResetTextureState();
        R_SetupGenericShader(false);
-       R_Mesh_Draw(0, 8, 12, bboxelements, 0, 0);
+       R_Mesh_Draw(0, 8, 0, 12, NULL, bboxelements, 0, 0);
 }
 
 static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
@@ -4058,7 +4058,7 @@ static void R_DrawEntityBBoxes(void)
        SV_VM_End();
 }
 
-int nomodelelements[24] =
+unsigned short nomodelelements[24] =
 {
        5, 2, 0,
        5, 1, 2,
@@ -4146,7 +4146,7 @@ void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight
        else
                R_Mesh_ColorPointer(nomodelcolor4f, 0, 0);
        R_Mesh_ResetTextureState();
-       R_Mesh_Draw(0, 6, 8, nomodelelements, 0, 0);
+       R_Mesh_Draw(0, 6, 0, 8, NULL, nomodelelements, 0, 0);
 }
 
 void R_DrawNoModel(entity_render_t *ent)
@@ -4238,7 +4238,7 @@ void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_
        R_Mesh_TexCoordPointer(0, 2, spritetexcoord2f, 0, 0);
        // FIXME: fixed function path can't properly handle r_refdef.view.colorscale > 1
        GL_Color(cr * fog * r_refdef.view.colorscale, cg * fog * r_refdef.view.colorscale, cb * fog * r_refdef.view.colorscale, ca);
-       R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+       R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
 
        if (blendfunc2 == GL_ONE_MINUS_SRC_ALPHA)
        {
@@ -4246,7 +4246,7 @@ void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_
                GL_BlendFunc(blendfunc1, GL_ONE);
                fog = 1 - fog;
                GL_Color(r_refdef.fogcolor[0] * fog, r_refdef.fogcolor[1] * fog, r_refdef.fogcolor[2] * fog, ca);
-               R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+               R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
        }
 }
 
@@ -4761,7 +4761,9 @@ void RSurf_ActiveWorldEntity(void)
        rsurface.modeltexcoordlightmap2f_bufferobject = model->surfmesh.vbo;
        rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.vbooffset_texcoordlightmap2f;
        rsurface.modelelement3i = model->surfmesh.data_element3i;
-       rsurface.modelelement3i_bufferobject = model->surfmesh.ebo;
+       rsurface.modelelement3s = model->surfmesh.data_element3s;
+       rsurface.modelelement3i_bufferobject = model->surfmesh.ebo3i;
+       rsurface.modelelement3s_bufferobject = model->surfmesh.ebo3s;
        rsurface.modellightmapoffsets = model->surfmesh.data_lightmapoffsets;
        rsurface.modelnum_vertices = model->surfmesh.num_vertices;
        rsurface.modelnum_triangles = model->surfmesh.num_triangles;
@@ -4874,7 +4876,9 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q
        rsurface.modeltexcoordlightmap2f_bufferobject = model->surfmesh.vbo;
        rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.vbooffset_texcoordlightmap2f;
        rsurface.modelelement3i = model->surfmesh.data_element3i;
-       rsurface.modelelement3i_bufferobject = model->surfmesh.ebo;
+       rsurface.modelelement3s = model->surfmesh.data_element3s;
+       rsurface.modelelement3i_bufferobject = model->surfmesh.ebo3i;
+       rsurface.modelelement3s_bufferobject = model->surfmesh.ebo3s;
        rsurface.modellightmapoffsets = model->surfmesh.data_lightmapoffsets;
        rsurface.modelnum_vertices = model->surfmesh.num_vertices;
        rsurface.modelnum_triangles = model->surfmesh.num_triangles;
@@ -5328,7 +5332,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.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle));
+               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject);
        }
        else if (r_batchmode.integer == 2)
        {
@@ -5341,7 +5345,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.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle));
+                               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject);
                                continue;
                        }
                        memcpy(batchelements, rsurface.modelelement3i + 3 * surface->num_firsttriangle, surface->num_triangles * sizeof(int[3]));
@@ -5360,7 +5364,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel
                        }
                        surface2 = texturesurfacelist[j-1];
                        numvertices = endvertex - firstvertex;
-                       R_Mesh_Draw(firstvertex, numvertices, batchtriangles, batchelements, 0, 0);
+                       R_Mesh_Draw(firstvertex, numvertices, 0, batchtriangles, batchelements, NULL, 0, 0);
                }
        }
        else if (r_batchmode.integer == 1)
@@ -5375,7 +5379,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.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle));
+                       R_Mesh_Draw(surface->num_firstvertex, numvertices, surface->num_firsttriangle, numtriangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject);
                }
        }
        else
@@ -5384,7 +5388,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.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle));
+                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject);
                }
        }
 }
@@ -5438,7 +5442,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(int
                                R_Mesh_TexBind(reflectiontexunit, R_GetTexture(r_texture_black));
                }
                GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle));
+               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject);
        }
 }
 
@@ -5459,7 +5463,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.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle));
+               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject);
        }
        else if (r_batchmode.integer == 2)
        {
@@ -5475,7 +5479,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.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle));
+                               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject);
                                continue;
                        }
                        memcpy(batchelements, rsurface.modelelement3i + 3 * surface->num_firsttriangle, surface->num_triangles * sizeof(int[3]));
@@ -5494,7 +5498,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa
                        }
                        surface2 = texturesurfacelist[j-1];
                        numvertices = endvertex - firstvertex;
-                       R_Mesh_Draw(firstvertex, numvertices, batchtriangles, batchelements, 0, 0);
+                       R_Mesh_Draw(firstvertex, numvertices, 0, batchtriangles, batchelements, NULL, 0, 0);
                }
        }
        else if (r_batchmode.integer == 1)
@@ -5528,7 +5532,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.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle));
+                       R_Mesh_Draw(surface->num_firstvertex, numvertices, surface->num_firsttriangle, numtriangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject);
                }
 #if 0
                Con_Printf("\n");
@@ -5543,7 +5547,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.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle));
+                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject);
                }
        }
 }
@@ -5561,7 +5565,7 @@ static void RSurf_DrawBatch_ShowSurfaces(int texturenumsurfaces, msurface_t **te
                        {
                                float f = ((j + surface->num_firsttriangle) & 31) * (1.0f / 31.0f) * r_refdef.view.colorscale;
                                GL_Color(f, f, f, 1);
-                               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, 1, (rsurface.modelelement3i + 3 * (j + surface->num_firsttriangle)), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * (j + surface->num_firsttriangle)));
+                               R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle + j, 1, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject);
                        }
                }
        }
@@ -5573,7 +5577,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_refdef.view.colorscale, ((k >> 4) & 15) * (1.0f / 16.0f) * r_refdef.view.colorscale, ((k >> 8) & 15) * (1.0f / 16.0f) * r_refdef.view.colorscale, 1);
                        GL_LockArrays(surface->num_firstvertex, surface->num_vertices);
-                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle));
+                       R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject);
                }
        }
 }
@@ -6376,7 +6380,7 @@ float locboxvertex3f[6*4*3] =
        1,0,0, 0,0,0, 0,1,0, 1,1,0
 };
 
-int locboxelement3i[6*2*3] =
+unsigned short locboxelements[6*2*3] =
 {
         0, 1, 2, 0, 2, 3,
         4, 5, 6, 4, 6, 7,
@@ -6427,7 +6431,7 @@ void R_DrawLoc_Callback(const entity_render_t *ent, const rtlight_t *rtlight, in
                for (j = 0;j < 3;j++, i++)
                        vertex3f[i] = mins[j] + size[j] * locboxvertex3f[i];
 
-       R_Mesh_Draw(0, 6*4, 6*2, locboxelement3i, 0, 0);
+       R_Mesh_Draw(0, 6*4, 0, 6*2, NULL, locboxelements, 0, 0);
 }
 
 void R_DrawLocs(void)
@@ -6471,7 +6475,7 @@ void R_DrawDebugModel(entity_render_t *ent)
                        {
                                R_Mesh_VertexPointer(brush->colbrushf->points->v, 0, 0);
                                GL_Color((i & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((i >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((i >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value);
-                               R_Mesh_Draw(0, brush->colbrushf->numpoints, brush->colbrushf->numtriangles, brush->colbrushf->elements, 0, 0);
+                               R_Mesh_Draw(0, brush->colbrushf->numpoints, 0, brush->colbrushf->numtriangles, brush->colbrushf->elements, NULL, 0, 0);
                        }
                }
                for (i = 0, surface = model->data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++)
@@ -6480,7 +6484,7 @@ void R_DrawDebugModel(entity_render_t *ent)
                        {
                                R_Mesh_VertexPointer(surface->data_collisionvertex3f, 0, 0);
                                GL_Color((i & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((i >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((i >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value);
-                               R_Mesh_Draw(0, surface->num_collisionvertices, surface->num_collisiontriangles, surface->data_collisionelement3i, 0, 0);
+                               R_Mesh_Draw(0, surface->num_collisionvertices, 0, surface->num_collisiontriangles, surface->data_collisionelement3i, NULL, 0, 0);
                        }
                }
        }
index 416c772..14c2a18 100644 (file)
@@ -348,7 +348,7 @@ static void R_DrawPortal_Callback(const entity_render_t *ent, const rtlight_t *r
                         0.125f);
        for (i = 0, v = vertex3f;i < numpoints;i++, v += 3)
                VectorCopy(portal->points[i].position, v);
-       R_Mesh_Draw(0, numpoints, numpoints - 2, polygonelements, 0, 0);
+       R_Mesh_Draw(0, numpoints, 0, numpoints - 2, NULL, polygonelements, 0, 0);
 }
 
 // LordHavoc: this is just a nice debugging tool, very slow
@@ -1034,7 +1034,7 @@ static void R_Q1BSP_DrawLight_TransparentCallback(const entity_render_t *ent, co
                        if (t != surface->texture)
                                break;
                        RSurf_PrepareVerticesForBatch(true, true, 1, &surface);
-                       R_Shadow_RenderLighting(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, ent->model->surfmesh.data_element3i + surface->num_firsttriangle * 3, ent->model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle));
+                       R_Shadow_RenderLighting(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, ent->model->surfmesh.data_element3i, ent->model->surfmesh.data_element3s, ent->model->surfmesh.ebo3i, ent->model->surfmesh.ebo3s);
                }
        }
        R_Shadow_RenderMode_End();
@@ -1134,9 +1134,9 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface
                                                Mod_VertexRangeFromElements(batchnumtriangles*3, batchelements, &batchfirstvertex, &batchlastvertex);
                                                // use the element buffer if all triangles are consecutive
                                                if (m == batchfirsttriangle + batchnumtriangles)
-                                                       R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, ent->model->surfmesh.ebo, sizeof(int[3]) * batchfirsttriangle);
+                                                       R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchfirsttriangle, batchnumtriangles, ent->model->surfmesh.data_element3i, ent->model->surfmesh.data_element3s, ent->model->surfmesh.ebo3i, ent->model->surfmesh.ebo3s);
                                                else
-                                                       R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, 0, 0);
+                                                       R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, 0, batchnumtriangles, batchelements, NULL, 0, 0);
                                                usebufferobject = true;
                                                batchnumtriangles = 0;
                                                batchfirsttriangle = m;
@@ -1153,9 +1153,9 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, int numsurfaces, const int *surface
                                Mod_VertexRangeFromElements(batchnumtriangles*3, batchelements, &batchfirstvertex, &batchlastvertex);
                                // use the element buffer if all triangles are consecutive
                                if (m == batchfirsttriangle + batchnumtriangles)
-                                       R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, ent->model->surfmesh.ebo, sizeof(int[3]) * batchfirsttriangle);
+                                       R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchfirsttriangle, batchnumtriangles, ent->model->surfmesh.data_element3i, ent->model->surfmesh.data_element3s, ent->model->surfmesh.ebo3i, ent->model->surfmesh.ebo3s);
                                else
-                                       R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, batchnumtriangles, batchelements, 0, 0);
+                                       R_Shadow_RenderLighting(batchfirstvertex, batchlastvertex + 1 - batchfirstvertex, 0, batchnumtriangles, batchelements, NULL, 0, 0);
                        }
                }
        }
index 307da89..77b580e 100644 (file)
@@ -972,6 +972,14 @@ void Mod_IDP0_Load(model_t *mod, void *buffer, void *bufferend)
                loadmodel->surfmesh.data_texcoordtexture2f[i*2+1] = vertst[i*2+1];
        }
 
+       // generate ushort elements array if possible
+       if (loadmodel->surfmesh.num_vertices <= 65536)
+       {
+               loadmodel->surfmesh.data_element3s = (unsigned short *)Mem_Alloc(loadmodel->mempool, sizeof(unsigned short[3]) * loadmodel->surfmesh.num_triangles);
+               for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
+                       loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
+       }
+
 // load the frames
        loadmodel->animscenes = (animscene_t *)Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numframes);
        loadmodel->surfmesh.data_morphmdlvertex = (trivertx_t *)Mem_Alloc(loadmodel->mempool, sizeof(trivertx_t) * loadmodel->surfmesh.num_morphframes * loadmodel->surfmesh.num_vertices);
@@ -1289,6 +1297,14 @@ void Mod_IDP2_Load(model_t *mod, void *buffer, void *bufferend)
        Mem_Free(md2verthash);
        Mem_Free(md2verthashdata);
 
+       // generate ushort elements array if possible
+       if (loadmodel->surfmesh.num_vertices <= 65536)
+       {
+               loadmodel->surfmesh.data_element3s = (unsigned short *)Mem_Alloc(loadmodel->mempool, sizeof(unsigned short[3]) * loadmodel->surfmesh.num_triangles);
+               for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
+                       loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
+       }
+
        // load the frames
        datapointer = (base + LittleLong(pinmodel->ofs_frames));
        for (i = 0;i < loadmodel->surfmesh.num_morphframes;i++)
@@ -1432,7 +1448,7 @@ void Mod_IDP3_Load(model_t *mod, void *buffer, void *bufferend)
        loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
        loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
        loadmodel->num_texturesperskin = loadmodel->num_surfaces;
-       data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + meshtriangles * sizeof(int[3]) + meshvertices * sizeof(float[2]) + meshvertices * loadmodel->numframes * sizeof(md3vertex_t));
+       data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * sizeof(float[2]) + meshvertices * loadmodel->numframes * sizeof(md3vertex_t));
        loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
        loadmodel->surfacelist = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
        loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
@@ -1444,6 +1460,12 @@ void Mod_IDP3_Load(model_t *mod, void *buffer, void *bufferend)
        loadmodel->surfmesh.data_neighbor3i = (int *)data;data += meshtriangles * sizeof(int[3]);
        loadmodel->surfmesh.data_texcoordtexture2f = (float *)data;data += meshvertices * sizeof(float[2]);
        loadmodel->surfmesh.data_morphmd3vertex = (md3vertex_t *)data;data += meshvertices * loadmodel->numframes * sizeof(md3vertex_t);
+       if (meshvertices <= 65536)
+       {
+               loadmodel->surfmesh.data_element3s = (unsigned short *)data;data += meshtriangles * sizeof(unsigned short[3]);
+               for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
+                       loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
+       }
 
        meshvertices = 0;
        meshtriangles = 0;
@@ -1669,7 +1691,7 @@ void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        loadmodel->nummodelsurfaces = loadmodel->num_surfaces;
        loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
        loadmodel->num_texturesperskin = loadmodel->num_surfaces;
-       data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + meshtriangles * sizeof(int[3]) + meshvertices * sizeof(float[14]) + meshvertices * sizeof(int[4]) + meshvertices * sizeof(float[4]) + loadmodel->num_poses * sizeof(float[12]) + loadmodel->num_bones * sizeof(float[12]));
+       data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshvertices * sizeof(float[14]) + meshvertices * sizeof(int[4]) + meshvertices * sizeof(float[4]) + loadmodel->num_poses * sizeof(float[12]) + loadmodel->num_bones * sizeof(float[12]));
        loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
        loadmodel->surfacelist = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
        loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
@@ -1686,6 +1708,12 @@ void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        loadmodel->surfmesh.data_vertexweightinfluence4f = (float *)data;data += meshvertices * sizeof(float[4]);
        loadmodel->data_poses = (float *)data;data += loadmodel->num_poses * sizeof(float[12]);
        loadmodel->data_baseboneposeinverse = (float *)data;data += loadmodel->num_bones * sizeof(float[12]);
+       if (loadmodel->surfmesh.num_vertices <= 65536)
+       {
+               loadmodel->surfmesh.data_element3s = (unsigned short *)data;data += loadmodel->surfmesh.num_triangles * sizeof(unsigned short[3]);
+               for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
+                       loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
+       }
 
        //zymlump_t lump_poses; // float pose[numposes][numbones][3][4]; // animation data
        poses = (float *) (pheader->lump_poses.start + pbase);
@@ -1912,7 +1940,7 @@ void Mod_DARKPLACESMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
        loadmodel->num_texturesperskin = loadmodel->num_surfaces;
        // do most allocations as one merged chunk
-       data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + meshtriangles * sizeof(int[3]) + meshvertices * (sizeof(float[14]) + sizeof(int[4]) + sizeof(float[4])) + loadmodel->num_poses * sizeof(float[12]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t));
+       data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshtriangles * sizeof(int[3]) + meshvertices * (sizeof(float[14]) + sizeof(int[4]) + sizeof(float[4])) + loadmodel->num_poses * sizeof(float[12]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t));
        loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
        loadmodel->surfacelist = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
        loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
@@ -1932,6 +1960,12 @@ void Mod_DARKPLACESMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        loadmodel->skinscenes = (animscene_t *)data;data += loadmodel->numskins * sizeof(animscene_t);
        loadmodel->data_bones = (aliasbone_t *)data;data += loadmodel->num_bones * sizeof(aliasbone_t);
        loadmodel->animscenes = (animscene_t *)data;data += loadmodel->numframes * sizeof(animscene_t);
+       if (meshvertices <= 65536)
+       {
+               loadmodel->surfmesh.data_element3s = (unsigned short *)data;data += meshtriangles * sizeof(unsigned short[3]);
+               for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
+                       loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
+       }
 
        for (i = 0;i < loadmodel->numskins;i++)
        {
@@ -2492,7 +2526,7 @@ void Mod_PSKMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        loadmodel->num_textures = loadmodel->num_surfaces * loadmodel->numskins;
        loadmodel->num_texturesperskin = loadmodel->num_surfaces;
        // do most allocations as one merged chunk
-       data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + meshtriangles * sizeof(int[3]) + meshvertices * (sizeof(float[14]) + sizeof(int[4]) + sizeof(float[4])) + loadmodel->num_poses * sizeof(float[12]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t));
+       data = (unsigned char *)Mem_Alloc(loadmodel->mempool, loadmodel->num_surfaces * sizeof(msurface_t) + loadmodel->num_surfaces * sizeof(int) + loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t) + meshtriangles * sizeof(int[3]) + (meshvertices <= 65536 ? meshtriangles * sizeof(unsigned short[3]) : 0) + meshtriangles * sizeof(int[3]) + meshvertices * (sizeof(float[14]) + sizeof(int[4]) + sizeof(float[4])) + loadmodel->num_poses * sizeof(float[12]) + loadmodel->num_bones * sizeof(float[12]) + loadmodel->numskins * sizeof(animscene_t) + loadmodel->num_bones * sizeof(aliasbone_t) + loadmodel->numframes * sizeof(animscene_t));
        loadmodel->data_surfaces = (msurface_t *)data;data += loadmodel->num_surfaces * sizeof(msurface_t);
        loadmodel->surfacelist = (int *)data;data += loadmodel->num_surfaces * sizeof(int);
        loadmodel->data_textures = (texture_t *)data;data += loadmodel->num_surfaces * loadmodel->numskins * sizeof(texture_t);
@@ -2512,6 +2546,12 @@ void Mod_PSKMODEL_Load(model_t *mod, void *buffer, void *bufferend)
        loadmodel->skinscenes = (animscene_t *)data;data += loadmodel->numskins * sizeof(animscene_t);
        loadmodel->data_bones = (aliasbone_t *)data;data += loadmodel->num_bones * sizeof(aliasbone_t);
        loadmodel->animscenes = (animscene_t *)data;data += loadmodel->numframes * sizeof(animscene_t);
+       if (meshvertices <= 65536)
+       {
+               loadmodel->surfmesh.data_element3s = (unsigned short *)data;data += meshtriangles * sizeof(unsigned short[3]);
+               for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
+                       loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
+       }
 
        for (i = 0;i < loadmodel->numskins;i++)
        {
index 5950251..134b895 100644 (file)
@@ -2452,6 +2452,11 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l)
 
                }
        }
+
+       // generate ushort elements array if possible
+       if (loadmodel->surfmesh.data_element3s)
+               for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
+                       loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
 }
 
 static void Mod_Q1BSP_LoadNodes_RecursiveSetParent(mnode_t *node, mnode_t *parent)
@@ -4884,6 +4889,11 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
        // for per pixel lighting
        Mod_BuildTextureVectorsFromNormals(0, loadmodel->surfmesh.num_vertices, loadmodel->surfmesh.num_triangles, loadmodel->surfmesh.data_vertex3f, loadmodel->surfmesh.data_texcoordtexture2f, loadmodel->surfmesh.data_normal3f, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.data_svector3f, loadmodel->surfmesh.data_tvector3f, true);
 
+       // generate ushort elements array if possible
+       if (loadmodel->surfmesh.data_element3s)
+               for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
+                       loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
+
        // free the no longer needed vertex data
        loadmodel->brushq3.num_vertices = 0;
        if (loadmodel->brushq3.data_vertex3f)
index 3be80ec..3ebd38d 100644 (file)
@@ -159,8 +159,10 @@ void Mod_UnloadModel (model_t *mod)
        strlcpy(name, mod->name, sizeof(name));
        isworldmodel = mod->isworldmodel;
        used = mod->used;
-       if (mod->surfmesh.ebo)
-               R_Mesh_DestroyBufferObject(mod->surfmesh.ebo);
+       if (mod->surfmesh.ebo3i)
+               R_Mesh_DestroyBufferObject(mod->surfmesh.ebo3i);
+       if (mod->surfmesh.ebo3s)
+               R_Mesh_DestroyBufferObject(mod->surfmesh.ebo3s);
        if (mod->surfmesh.vbo)
                R_Mesh_DestroyBufferObject(mod->surfmesh.vbo);
        // free textures/memory attached to the model
@@ -752,7 +754,7 @@ void Mod_BuildTextureVectorsFromNormals(int firstvertex, int numvertices, int nu
 void Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qboolean lightmapoffsets, qboolean vertexcolors, qboolean neighbors)
 {
        unsigned char *data;
-       data = (unsigned char *)Mem_Alloc(mempool, numvertices * (3 + 3 + 3 + 3 + 2 + 2 + (vertexcolors ? 4 : 0)) * sizeof(float) + numvertices * (lightmapoffsets ? 1 : 0) * sizeof(int) + numtriangles * (3 + (neighbors ? 3 : 0)) * sizeof(int));
+       data = (unsigned char *)Mem_Alloc(mempool, numvertices * (3 + 3 + 3 + 3 + 2 + 2 + (vertexcolors ? 4 : 0)) * sizeof(float) + numvertices * (lightmapoffsets ? 1 : 0) * sizeof(int) + numtriangles * (3 + (neighbors ? 3 : 0)) * sizeof(int) + (numvertices <= 65536 ? numtriangles * sizeof(unsigned short[3]) : 0));
        loadmodel->surfmesh.num_vertices = numvertices;
        loadmodel->surfmesh.num_triangles = numtriangles;
        if (loadmodel->surfmesh.num_vertices)
@@ -773,6 +775,8 @@ void Mod_AllocSurfMesh(mempool_t *mempool, int numvertices, int numtriangles, qb
                loadmodel->surfmesh.data_element3i = (int *)data, data += sizeof(int[3]) * loadmodel->surfmesh.num_triangles;
                if (neighbors)
                        loadmodel->surfmesh.data_neighbor3i = (int *)data, data += sizeof(int[3]) * loadmodel->surfmesh.num_triangles;
+               if (loadmodel->surfmesh.num_vertices <= 65536)
+                       loadmodel->surfmesh.data_element3s = (unsigned short *)data, data += sizeof(unsigned short[3]) * loadmodel->surfmesh.num_triangles;
        }
 }
 
@@ -786,6 +790,8 @@ shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtria
        if (light)
                size += maxverts * sizeof(float[11]);
        size += maxtriangles * sizeof(int[3]);
+       if (maxverts <= 65536)
+               size += maxtriangles * sizeof(unsigned short[3]);
        if (neighbors)
                size += maxtriangles * sizeof(int[3]);
        if (expandable)
@@ -818,6 +824,8 @@ shadowmesh_t *Mod_ShadowMesh_Alloc(mempool_t *mempool, int maxverts, int maxtria
                newmesh->vertexhashtable = (shadowmeshvertexhash_t **)data;data += SHADOWMESHVERTEXHASH * sizeof(shadowmeshvertexhash_t *);
                newmesh->vertexhashentries = (shadowmeshvertexhash_t *)data;data += maxverts * sizeof(shadowmeshvertexhash_t);
        }
+       if (maxverts <= 65536)
+               newmesh->element3s = (unsigned short *)data;data += maxtriangles * sizeof(unsigned short[3]);
        return newmesh;
 }
 
@@ -948,7 +956,12 @@ static void Mod_ShadowMesh_CreateVBOs(shadowmesh_t *mesh)
 
        // element buffer is easy because it's just one array
        if (mesh->numtriangles)
-               mesh->ebo = R_Mesh_CreateStaticBufferObject(GL_ELEMENT_ARRAY_BUFFER_ARB, mesh->element3i, mesh->numtriangles * sizeof(int[3]), "shadowmesh");
+       {
+               if (mesh->element3s)
+                       mesh->ebo3s = R_Mesh_CreateStaticBufferObject(GL_ELEMENT_ARRAY_BUFFER_ARB, mesh->element3s, mesh->numtriangles * sizeof(unsigned short[3]), "shadowmesh");
+               else
+                       mesh->ebo3i = R_Mesh_CreateStaticBufferObject(GL_ELEMENT_ARRAY_BUFFER_ARB, mesh->element3i, mesh->numtriangles * sizeof(unsigned int[3]), "shadowmesh");
+       }
 
        // vertex buffer is several arrays and we put them in the same buffer
        //
@@ -988,6 +1001,12 @@ shadowmesh_t *Mod_ShadowMesh_Finish(mempool_t *mempool, shadowmesh_t *firstmesh,
                        newmesh = Mod_ShadowMesh_ReAlloc(mempool, mesh, light, neighbors);
                        newmesh->next = firstmesh;
                        firstmesh = newmesh;
+                       if (newmesh->element3s)
+                       {
+                               int i;
+                               for (i = 0;i < newmesh->numtriangles*3;i++)
+                                       newmesh->element3s[i] = newmesh->element3i[i];
+                       }
                        if (createvbo)
                                Mod_ShadowMesh_CreateVBOs(newmesh);
                }
@@ -1050,8 +1069,10 @@ void Mod_ShadowMesh_Free(shadowmesh_t *mesh)
        shadowmesh_t *nextmesh;
        for (;mesh;mesh = nextmesh)
        {
-               if (mesh->ebo)
-                       R_Mesh_DestroyBufferObject(mesh->ebo);
+               if (mesh->ebo3i)
+                       R_Mesh_DestroyBufferObject(mesh->ebo3i);
+               if (mesh->ebo3s)
+                       R_Mesh_DestroyBufferObject(mesh->ebo3s);
                if (mesh->vbo)
                        R_Mesh_DestroyBufferObject(mesh->vbo);
                nextmesh = mesh->next;
@@ -2057,7 +2078,17 @@ static void Mod_BuildVBOs(void)
 
        // element buffer is easy because it's just one array
        if (loadmodel->surfmesh.num_triangles)
-               loadmodel->surfmesh.ebo = R_Mesh_CreateStaticBufferObject(GL_ELEMENT_ARRAY_BUFFER_ARB, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles * sizeof(int[3]), loadmodel->name);
+       {
+               if (loadmodel->surfmesh.data_element3s)
+               {
+                       int i;
+                       for (i = 0;i < loadmodel->surfmesh.num_triangles*3;i++)
+                               loadmodel->surfmesh.data_element3s[i] = loadmodel->surfmesh.data_element3i[i];
+                       loadmodel->surfmesh.ebo3s = R_Mesh_CreateStaticBufferObject(GL_ELEMENT_ARRAY_BUFFER_ARB, loadmodel->surfmesh.data_element3s, loadmodel->surfmesh.num_triangles * sizeof(unsigned short[3]), loadmodel->name);
+               }
+               else
+                       loadmodel->surfmesh.ebo3i = R_Mesh_CreateStaticBufferObject(GL_ELEMENT_ARRAY_BUFFER_ARB, loadmodel->surfmesh.data_element3i, loadmodel->surfmesh.num_triangles * sizeof(unsigned int[3]), loadmodel->name);
+       }
 
        // vertex buffer is several arrays and we put them in the same buffer
        //
index 30a5b77..598598e 100644 (file)
@@ -91,9 +91,11 @@ typedef struct surfmesh_s
        // triangle data in system memory
        int num_triangles; // number of triangles in the mesh
        int *data_element3i; // int[tris*3] triangles of the mesh, 3 indices into vertex arrays for each
+       unsigned short *data_element3s; // unsigned short[tris*3] triangles of the mesh in unsigned short format (NULL if num_vertices > 65536)
        int *data_neighbor3i; // int[tris*3] neighboring triangle on each edge (-1 if none)
        // element buffer object (stores triangles in video memory)
-       int ebo;
+       int ebo3i; // unsigned int format (only allocated if num_vertices > 65536)
+       int ebo3s; // unsigned short format (only allocated if num_vertices <= 65536)
        // vertex data in system memory
        int num_vertices; // number of vertices in the mesh
        float *data_vertex3f; // float[verts*3] vertex locations
@@ -156,6 +158,7 @@ typedef struct shadowmesh_s
        float *texcoord2f;
        // used always
        int *element3i;
+       unsigned short *element3s;
        // used for shadow mesh (NULL on light mesh)
        int *neighbor3i;
        // these are NULL after Mod_ShadowMesh_Finish is performed, only used
@@ -163,7 +166,8 @@ typedef struct shadowmesh_s
        shadowmeshvertexhash_t **vertexhashtable, *vertexhashentries;
        // element buffer object (stores triangles in video memory)
        // (created by Mod_ShadowMesh_Finish if possible)
-       int ebo;
+       int ebo3i;
+       int ebo3s;
        // vertex buffer object (stores vertices in video memory)
        // (created by Mod_ShadowMesh_Finish if possible)
        int vbo;
index 404a58a..7ebaf1f 100644 (file)
@@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 static int numexplosions = 0;
 
 static float explosiontexcoord2f[EXPLOSIONVERTS][2];
-static int explosiontris[EXPLOSIONTRIS][3];
+static unsigned short explosiontris[EXPLOSIONTRIS][3];
 static int explosionnoiseindex[EXPLOSIONVERTS];
 static vec3_t explosionpoint[EXPLOSIONVERTS];
 
@@ -210,7 +210,7 @@ static void R_DrawExplosion_TransparentCallback(const entity_render_t *ent, cons
                // FIXME: fixed function path can't properly handle r_refdef.view.colorscale > 1
                GL_Color(e->alpha * r_refdef.view.colorscale, e->alpha * r_refdef.view.colorscale, e->alpha * r_refdef.view.colorscale, 1);
                GL_LockArrays(0, numverts);
-               R_Mesh_Draw(0, numverts, numtriangles, explosiontris[0], 0, 0);
+               R_Mesh_Draw(0, numverts, 0, numtriangles, NULL, explosiontris[0], 0, 0);
                GL_LockArrays(0, 0);
        }
 }
index 584a024..ee4cee3 100644 (file)
@@ -14,7 +14,7 @@ rtexture_t *r_lightningbeamtexture;
 rtexture_t *r_lightningbeamqmbtexture;
 rtexturepool_t *r_lightningbeamtexturepool;
 
-int r_lightningbeamelements[18] = {0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11};
+unsigned short r_lightningbeamelements[18] = {0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11};
 
 void r_lightningbeams_start(void)
 {
@@ -339,7 +339,7 @@ void R_DrawLightningBeam_TransparentCallback(const entity_render_t *ent, const r
 
                // draw the 3 polygons as one batch of 6 triangles using the 12 vertices
                GL_LockArrays(0, 12);
-               R_Mesh_Draw(0, 12, 6, r_lightningbeamelements, 0, 0);
+               R_Mesh_Draw(0, 12, 0, 6, NULL, r_lightningbeamelements, 0, 0);
                GL_LockArrays(0, 0);
        }
 }
index d0bba73..2ff6dd6 100644 (file)
@@ -819,24 +819,6 @@ int R_Shadow_ConstructShadowVolume(int innumvertices, int innumtris, const int *
        return outtriangles;
 }
 
-void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, const vec3_t projectdirection, float projectdistance, int nummarktris, const int *marktris)
-{
-       int tris, outverts;
-       if (projectdistance < 0.1)
-       {
-               Con_Printf("R_Shadow_Volume: projectdistance %f\n", projectdistance);
-               return;
-       }
-       if (!numverts || !nummarktris)
-               return;
-       // make sure shadowelements is big enough for this volume
-       if (maxshadowtriangles < nummarktris || maxshadowvertices < numverts)
-               R_Shadow_ResizeShadowArrays((numverts + 255) & ~255, (nummarktris + 255) & ~255);
-       tris = R_Shadow_ConstructShadowVolume(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
-       r_refdef.stats.lights_dynamicshadowtriangles += tris;
-       R_Shadow_RenderVolume(outverts, tris, shadowvertex3f, shadowelements);
-}
-
 void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, const vec3_t projectdirection, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs)
 {
        int t, tend;
@@ -896,7 +878,7 @@ void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *inv
        }
 }
 
-void R_Shadow_RenderVolume(int numvertices, int numtriangles, const float *vertex3f, const int *element3i)
+static void R_Shadow_RenderVolume(int numvertices, int numtriangles, const float *vertex3f, const int *element3i)
 {
        if (r_shadow_compilingrtlight)
        {
@@ -913,16 +895,34 @@ void R_Shadow_RenderVolume(int numvertices, int numtriangles, const float *verte
                // decrement stencil if backface is behind depthbuffer
                GL_CullFace(r_refdef.view.cullface_front);
                qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR
-               R_Mesh_Draw(0, numvertices, numtriangles, element3i, 0, 0);
+               R_Mesh_Draw(0, numvertices, 0, numtriangles, element3i, NULL, 0, 0);
                // increment stencil if frontface is behind depthbuffer
                GL_CullFace(r_refdef.view.cullface_back);
                qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
        }
-       R_Mesh_Draw(0, numvertices, numtriangles, element3i, 0, 0);
+       R_Mesh_Draw(0, numvertices, 0, numtriangles, element3i, NULL, 0, 0);
        GL_LockArrays(0, 0);
        CHECKGLERROR
 }
 
+void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, const vec3_t projectdirection, float projectdistance, int nummarktris, const int *marktris)
+{
+       int tris, outverts;
+       if (projectdistance < 0.1)
+       {
+               Con_Printf("R_Shadow_Volume: projectdistance %f\n", projectdistance);
+               return;
+       }
+       if (!numverts || !nummarktris)
+               return;
+       // make sure shadowelements is big enough for this volume
+       if (maxshadowtriangles < nummarktris || maxshadowvertices < numverts)
+               R_Shadow_ResizeShadowArrays((numverts + 255) & ~255, (nummarktris + 255) & ~255);
+       tris = R_Shadow_ConstructShadowVolume(numverts, numtris, elements, neighbors, invertex3f, &outverts, shadowelements, shadowvertex3f, projectorigin, projectdirection, projectdistance, nummarktris, marktris);
+       r_refdef.stats.lights_dynamicshadowtriangles += tris;
+       R_Shadow_RenderVolume(outverts, tris, shadowvertex3f, shadowelements);
+}
+
 static void R_Shadow_MakeTextures_MakeCorona(void)
 {
        float dx, dy;
@@ -1524,13 +1524,13 @@ static void R_Shadow_GenTexCoords_Specular_NormalCubeMap(int firstvertex, int nu
        }
 }
 
-static void R_Shadow_RenderLighting_VisibleLighting(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
+static void R_Shadow_RenderLighting_VisibleLighting(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
 {
        // used to display how many times a surface is lit for level design purposes
-       R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+       R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 }
 
-static void R_Shadow_RenderLighting_Light_GLSL(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
+static void R_Shadow_RenderLighting_Light_GLSL(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
 {
        // ARB2 GLSL shader path (GFFX5200, Radeon 9500)
        R_SetupSurfaceShader(lightcolorbase, false, ambientscale, diffusescale, specularscale, RSURFPASS_RTLIGHT);
@@ -1561,14 +1561,14 @@ static void R_Shadow_RenderLighting_Light_GLSL(int firstvertex, int numvertices,
        {
                qglDepthFunc(GL_EQUAL);CHECKGLERROR
        }
-       R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+       R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
        if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)
        {
                qglDepthFunc(GL_LEQUAL);CHECKGLERROR
        }
 }
 
-static void R_Shadow_RenderLighting_Light_Dot3_Finalize(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, float r, float g, float b)
+static void R_Shadow_RenderLighting_Light_Dot3_Finalize(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, float r, float g, float b)
 {
        // shared final code for all the dot3 layers
        int renders;
@@ -1576,11 +1576,11 @@ static void R_Shadow_RenderLighting_Light_Dot3_Finalize(int firstvertex, int num
        for (renders = 0;renders < 64 && (r > 0 || g > 0 || b > 0);renders++, r--, g--, b--)
        {
                GL_Color(bound(0, r, 1), bound(0, g, 1), bound(0, b, 1), 1);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
        }
 }
 
-static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, rtexture_t *basetexture, float colorscale)
+static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, const vec3_t lightcolorbase, rtexture_t *basetexture, float colorscale)
 {
        rmeshstate_t m;
        // colorscale accounts for how much we multiply the brightness
@@ -1695,7 +1695,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int
                R_Mesh_TextureState(&m);
                GL_ColorMask(0,0,0,1);
                GL_BlendFunc(GL_ONE, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1716,10 +1716,10 @@ static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int
        }
        // this final code is shared
        R_Mesh_TextureState(&m);
-       R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale);
+       R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale);
 }
 
-static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, rtexture_t *basetexture, rtexture_t *normalmaptexture, float colorscale)
+static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, const vec3_t lightcolorbase, rtexture_t *basetexture, rtexture_t *normalmaptexture, float colorscale)
 {
        rmeshstate_t m;
        // colorscale accounts for how much we multiply the brightness
@@ -1755,7 +1755,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                R_Mesh_TextureState(&m);
                GL_ColorMask(0,0,0,1);
                GL_BlendFunc(GL_ONE, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1786,7 +1786,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                R_Mesh_TextureState(&m);
                GL_ColorMask(0,0,0,1);
                GL_BlendFunc(GL_ONE, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1803,7 +1803,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                m.pointer_texcoord_bufferoffset[1] = 0;
                R_Mesh_TextureState(&m);
                GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1840,7 +1840,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                R_Mesh_TextureState(&m);
                GL_ColorMask(0,0,0,1);
                GL_BlendFunc(GL_ONE, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1884,7 +1884,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                R_Mesh_TextureState(&m);
                GL_ColorMask(0,0,0,1);
                GL_BlendFunc(GL_ONE, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1920,7 +1920,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                R_Mesh_TextureState(&m);
                GL_ColorMask(0,0,0,1);
                GL_BlendFunc(GL_ONE, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1937,7 +1937,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
                m.pointer_texcoord_bufferoffset[1] = 0;
                R_Mesh_TextureState(&m);
                GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second pass
                memset(&m, 0, sizeof(m));
@@ -1958,10 +1958,10 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int
        }
        // this final code is shared
        R_Mesh_TextureState(&m);
-       R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale);
+       R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale);
 }
 
-static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, rtexture_t *glosstexture, rtexture_t *normalmaptexture, float colorscale)
+static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, const vec3_t lightcolorbase, rtexture_t *glosstexture, rtexture_t *normalmaptexture, float colorscale)
 {
        float glossexponent;
        rmeshstate_t m;
@@ -1989,14 +1989,14 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int
                GL_ColorMask(0,0,0,1);
                // this squares the result
                GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second and third pass
                R_Mesh_ResetTextureState();
                // square alpha in framebuffer a few times to make it shiny
                GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
                for (glossexponent = 2;glossexponent * 2 <= r_shadow_glossexponent.value;glossexponent *= 2)
-                       R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+                       R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // fourth pass
                memset(&m, 0, sizeof(m));
@@ -2007,7 +2007,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int
                m.texmatrix[0] = rsurface.entitytoattenuationxyz;
                R_Mesh_TextureState(&m);
                GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // fifth pass
                memset(&m, 0, sizeof(m));
@@ -2044,14 +2044,14 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int
                GL_ColorMask(0,0,0,1);
                // this squares the result
                GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second and third pass
                R_Mesh_ResetTextureState();
                // square alpha in framebuffer a few times to make it shiny
                GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
                for (glossexponent = 2;glossexponent * 2 <= r_shadow_glossexponent.value;glossexponent *= 2)
-                       R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+                       R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // fourth pass
                memset(&m, 0, sizeof(m));
@@ -2085,14 +2085,14 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int
                GL_ColorMask(0,0,0,1);
                // this squares the result
                GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // second and third pass
                R_Mesh_ResetTextureState();
                // square alpha in framebuffer a few times to make it shiny
                GL_BlendFunc(GL_ZERO, GL_DST_ALPHA);
                for (glossexponent = 2;glossexponent * 2 <= r_shadow_glossexponent.value;glossexponent *= 2)
-                       R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+                       R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // fourth pass
                memset(&m, 0, sizeof(m));
@@ -2108,7 +2108,7 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int
                m.texmatrix[1] = rsurface.entitytoattenuationz;
                R_Mesh_TextureState(&m);
                GL_BlendFunc(GL_DST_ALPHA, GL_ZERO);
-               R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
+               R_Mesh_Draw(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject);
 
                // fifth pass
                memset(&m, 0, sizeof(m));
@@ -2129,10 +2129,10 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int
        }
        // this final code is shared
        R_Mesh_TextureState(&m);
-       R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale);
+       R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale);
 }
 
-static void R_Shadow_RenderLighting_Light_Dot3(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
+static void R_Shadow_RenderLighting_Light_Dot3(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
 {
        // ARB path (any Geforce, any Radeon)
        qboolean doambient = ambientscale > 0;
@@ -2142,28 +2142,28 @@ static void R_Shadow_RenderLighting_Light_Dot3(int firstvertex, int numvertices,
                return;
        R_Mesh_ColorPointer(NULL, 0, 0);
        if (doambient)
-               R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, basetexture, ambientscale * r_refdef.view.colorscale);
+               R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, basetexture, ambientscale * r_refdef.view.colorscale);
        if (dodiffuse)
-               R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, basetexture, normalmaptexture, diffusescale * r_refdef.view.colorscale);
+               R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, basetexture, normalmaptexture, diffusescale * r_refdef.view.colorscale);
        if (dopants)
        {
                if (doambient)
-                       R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorpants, pantstexture, ambientscale * r_refdef.view.colorscale);
+                       R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorpants, pantstexture, ambientscale * r_refdef.view.colorscale);
                if (dodiffuse)
-                       R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorpants, pantstexture, normalmaptexture, diffusescale * r_refdef.view.colorscale);
+                       R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorpants, pantstexture, normalmaptexture, diffusescale * r_refdef.view.colorscale);
        }
        if (doshirt)
        {
                if (doambient)
-                       R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorshirt, shirttexture, ambientscale * r_refdef.view.colorscale);
+                       R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorshirt, shirttexture, ambientscale * r_refdef.view.colorscale);
                if (dodiffuse)
-                       R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorshirt, shirttexture, normalmaptexture, diffusescale * r_refdef.view.colorscale);
+                       R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorshirt, shirttexture, normalmaptexture, diffusescale * r_refdef.view.colorscale);
        }
        if (dospecular)
-               R_Shadow_RenderLighting_Light_Dot3_SpecularPass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, glosstexture, normalmaptexture, specularscale * r_refdef.view.colorscale);
+               R_Shadow_RenderLighting_Light_Dot3_SpecularPass(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, glosstexture, normalmaptexture, specularscale * r_refdef.view.colorscale);
 }
 
-void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, vec3_t diffusecolor2, vec3_t ambientcolor2)
+static void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numvertices, int numtriangles, const int *element3i, vec3_t diffusecolor2, vec3_t ambientcolor2)
 {
        int renders;
        int i;
@@ -2174,6 +2174,7 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numvertices,
        int *newe;
        const int *e;
        float *c;
+       int maxtriangles = 4096;
        int newelements[4096*3];
        R_Shadow_RenderLighting_Light_Vertex_Shading(firstvertex, numvertices, numtriangles, element3i, diffusecolor2, ambientcolor2);
        for (renders = 0;renders < 64;renders++)
@@ -2211,9 +2212,9 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numvertices,
                                newe[2] = e[2];
                                newnumtriangles++;
                                newe += 3;
-                               if (newnumtriangles >= (int)(sizeof(newelements)/sizeof(float[3])))
+                               if (newnumtriangles >= maxtriangles)
                                {
-                                       R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, newnumtriangles, newelements, 0, 0);
+                                       R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, 0, newnumtriangles, newelements, NULL, 0, 0);
                                        newnumtriangles = 0;
                                        newe = newelements;
                                        stop = false;
@@ -2222,11 +2223,7 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numvertices,
                }
                if (newnumtriangles >= 1)
                {
-                       // if all triangles are included, use the original array to take advantage of the bufferobject if possible
-                       if (newnumtriangles == numtriangles)
-                               R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset);
-                       else
-                               R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, newnumtriangles, newelements, 0, 0);
+                       R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, 0, newnumtriangles, newelements, NULL, 0, 0);
                        stop = false;
                }
                // if we couldn't find any lit triangles, exit early
@@ -2255,7 +2252,7 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(int firstvertex, int numvertices,
        }
 }
 
-static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
+static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertices, int numtriangles, const int *element3i, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt)
 {
        // OpenGL 1.1 path (anything)
        float ambientcolorbase[3], diffusecolorbase[3];
@@ -2294,21 +2291,21 @@ static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertice
        }
        R_Mesh_TextureState(&m);
        //R_Mesh_TexBind(0, R_GetTexture(basetexture));
-       R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, diffusecolorbase, ambientcolorbase);
+       R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, diffusecolorbase, ambientcolorbase);
        if (dopants)
        {
                R_Mesh_TexBind(0, R_GetTexture(pantstexture));
-               R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, diffusecolorpants, ambientcolorpants);
+               R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, diffusecolorpants, ambientcolorpants);
        }
        if (doshirt)
        {
                R_Mesh_TexBind(0, R_GetTexture(shirttexture));
-               R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, diffusecolorshirt, ambientcolorshirt);
+               R_Shadow_RenderLighting_Light_Vertex_Pass(firstvertex, numvertices, numtriangles, element3i, diffusecolorshirt, ambientcolorshirt);
        }
 }
 
 extern cvar_t gl_lightmaps;
-void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset)
+void R_Shadow_RenderLighting(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject)
 {
        float ambientscale, diffusescale, specularscale;
        vec3_t lightcolorbase, lightcolorpants, lightcolorshirt;
@@ -2356,16 +2353,16 @@ void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles,
                {
                case R_SHADOW_RENDERMODE_VISIBLELIGHTING:
                        GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) && !r_showdisabledepthtest.integer);
-                       R_Shadow_RenderLighting_VisibleLighting(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
+                       R_Shadow_RenderLighting_VisibleLighting(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_GLSL:
-                       R_Shadow_RenderLighting_Light_GLSL(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
+                       R_Shadow_RenderLighting_Light_GLSL(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_DOT3:
-                       R_Shadow_RenderLighting_Light_Dot3(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
+                       R_Shadow_RenderLighting_Light_Dot3(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
-                       R_Shadow_RenderLighting_Light_Vertex(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
+                       R_Shadow_RenderLighting_Light_Vertex(firstvertex, numvertices, numtriangles, element3i + firsttriangle * 3, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt);
                        break;
                default:
                        Con_Printf("R_Shadow_RenderLighting: unknown r_shadow_rendermode %i\n", r_shadow_rendermode);
@@ -2378,16 +2375,16 @@ void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles,
                {
                case R_SHADOW_RENDERMODE_VISIBLELIGHTING:
                        GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) && !r_showdisabledepthtest.integer);
-                       R_Shadow_RenderLighting_VisibleLighting(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
+                       R_Shadow_RenderLighting_VisibleLighting(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_GLSL:
-                       R_Shadow_RenderLighting_Light_GLSL(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
+                       R_Shadow_RenderLighting_Light_GLSL(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_DOT3:
-                       R_Shadow_RenderLighting_Light_Dot3(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
+                       R_Shadow_RenderLighting_Light_Dot3(firstvertex, numvertices, firsttriangle, numtriangles, element3i, element3s, element3i_bufferobject, element3s_bufferobject, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
                        break;
                case R_SHADOW_RENDERMODE_LIGHT_VERTEX:
-                       R_Shadow_RenderLighting_Light_Vertex(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
+                       R_Shadow_RenderLighting_Light_Vertex(firstvertex, numvertices, numtriangles, element3i + firsttriangle * 3, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false);
                        break;
                default:
                        Con_Printf("R_Shadow_RenderLighting: unknown r_shadow_rendermode %i\n", r_shadow_rendermode);
@@ -2752,12 +2749,12 @@ void R_Shadow_DrawWorldShadow(int numsurfaces, int *surfacelist, const unsigned
                                // decrement stencil if backface is behind depthbuffer
                                GL_CullFace(r_refdef.view.cullface_front);
                                qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR
-                               R_Mesh_Draw(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->ebo, 0);
+                               R_Mesh_Draw(0, mesh->numverts, 0, mesh->numtriangles, mesh->element3i, mesh->element3s, mesh->ebo3i, mesh->ebo3s);
                                // increment stencil if frontface is behind depthbuffer
                                GL_CullFace(r_refdef.view.cullface_back);
                                qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR
                        }
-                       R_Mesh_Draw(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->ebo, 0);
+                       R_Mesh_Draw(0, mesh->numverts, 0, mesh->numtriangles, mesh->element3i, mesh->element3s, mesh->ebo3i, mesh->ebo3s);
                        GL_LockArrays(0, 0);
                }
                CHECKGLERROR
@@ -3237,7 +3234,7 @@ void R_DrawModelShadows(void)
        qglStencilFunc(GL_NOTEQUAL, 128, ~0);CHECKGLERROR
 
        // apply the blend to the shadowed areas
-       R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0);
+       R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0);
 
        // restoring the perspective view is done by R_RenderScene
        //R_SetupView(true);
index d868ddd..2a33e8c 100644 (file)
@@ -39,7 +39,7 @@ extern cvar_t gl_ext_stenciltwoside;
 void R_Shadow_Init(void);
 void R_Shadow_VolumeFromList(int numverts, int numtris, const float *invertex3f, const int *elements, const int *neighbors, const vec3_t projectorigin, const vec3_t projectdirection, float projectdistance, int nummarktris, const int *marktris);
 void R_Shadow_MarkVolumeFromBox(int firsttriangle, int numtris, const float *invertex3f, const int *elements, const vec3_t projectorigin, const vec3_t projectdirection, const vec3_t lightmins, const vec3_t lightmaxs, const vec3_t surfacemins, const vec3_t surfacemaxs);
-void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset);
+void R_Shadow_RenderLighting(int firstvertex, int numvertices, int firsttriangle, int numtriangles, const int *element3i, const unsigned short *element3s, int element3i_bufferobject, int element3s_bufferobject);
 void R_Shadow_RenderMode_Begin(void);
 void R_Shadow_RenderMode_ActiveLight(rtlight_t *rtlight);
 void R_Shadow_RenderMode_Reset(void);
@@ -50,7 +50,6 @@ void R_Shadow_RenderMode_VisibleLighting(qboolean stenciltest, qboolean transpar
 void R_Shadow_RenderMode_End(void);
 void R_Shadow_SetupEntityLight(const entity_render_t *ent);
 
-void R_Shadow_RenderVolume(int numvertices, int numtriangles, const float *vertex3f, const int *element3i);
 qboolean R_Shadow_ScissorForBBox(const float *mins, const float *maxs);
 
 // these never change, they are used to create attenuation matrices
diff --git a/r_sky.c b/r_sky.c
index 092fd8b..c5e8425 100644 (file)
--- a/r_sky.c
+++ b/r_sky.c
@@ -252,7 +252,7 @@ static const float skyboxtexcoord2f[6*4*2] =
        0, 0
 };
 
-static const int skyboxelements[6*2*3] =
+static const unsigned short skyboxelements[6*2*3] =
 {
        // skyside[3]
         0,  1,  2,
@@ -294,7 +294,7 @@ static void R_SkyBox(void)
        for (i = 0;i < 6;i++)
        {
                R_Mesh_TexBind(0, R_GetTexture(skyboxside[i]));
-               R_Mesh_Draw(0, 6*4, 2, skyboxelements + i * 6, 0, 0);
+               R_Mesh_Draw(0, 6*4, i*2, 2, NULL, skyboxelements, 0, 0);
        }
 
        if(r_refdef.fogenabled)
@@ -305,7 +305,7 @@ static void R_SkyBox(void)
                for (i = 0;i < 6;i++)
                {
                        R_Mesh_TexBind(0, 0);
-                       R_Mesh_Draw(0, 6*4, 2, skyboxelements + i * 6, 0, 0);
+                       R_Mesh_Draw(0, 6*4, i*2, 2, NULL, skyboxelements, 0, 0);
                }
        }
 
@@ -322,11 +322,12 @@ static void R_SkyBox(void)
 #define skysphere_numtriangles (skygridx * skygridy * 2)
 static float skysphere_vertex3f[skysphere_numverts * 3];
 static float skysphere_texcoord2f[skysphere_numverts * 2];
-static int skysphere_element3i[skysphere_numtriangles * 3];
+static unsigned short skysphere_elements[skysphere_numtriangles * 3];
 
 static void skyspherecalc(void)
 {
-       int i, j, *e;
+       int i, j;
+       unsigned short *e;
        float a, b, x, ax, ay, v[3], length, *vertex3f, *texcoord2f;
        float dx, dy, dz;
        dx = 16;
@@ -354,7 +355,7 @@ static void skyspherecalc(void)
                        *vertex3f++ = v[2];
                }
        }
-       e = skysphere_element3i;
+       e = skysphere_elements;
        for (j = 0;j < skygridy;j++)
        {
                for (i = 0;i < skygridx;i++)
@@ -414,7 +415,7 @@ static void R_SkySphere(void)
                R_Mesh_TexCoordPointer(1, 2, skysphere_texcoord2f, 0, 0);
                R_Mesh_TexMatrix(1, &scroll2matrix);
                GL_LockArrays(0, skysphere_numverts);
-               R_Mesh_Draw(0, skysphere_numverts, skysphere_numtriangles, skysphere_element3i, 0, 0);
+               R_Mesh_Draw(0, skysphere_numverts, 0, skysphere_numtriangles, NULL, skysphere_elements, 0, 0);
                GL_LockArrays(0, 0);
                R_Mesh_TexBind(1, 0);
        }
@@ -423,13 +424,13 @@ static void R_SkySphere(void)
                // two pass
                R_SetupGenericShader(true);
                GL_LockArrays(0, skysphere_numverts);
-               R_Mesh_Draw(0, skysphere_numverts, skysphere_numtriangles, skysphere_element3i, 0, 0);
+               R_Mesh_Draw(0, skysphere_numverts, 0, skysphere_numtriangles, NULL, skysphere_elements, 0, 0);
 
                GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                R_Mesh_TexBind(0, R_GetTexture(r_refdef.scene.worldmodel->brush.alphaskytexture));
                R_Mesh_TexMatrix(0, &scroll2matrix);
                GL_LockArrays(0, skysphere_numverts);
-               R_Mesh_Draw(0, skysphere_numverts, skysphere_numtriangles, skysphere_element3i, 0, 0);
+               R_Mesh_Draw(0, skysphere_numverts, 0, skysphere_numtriangles, NULL, skysphere_elements, 0, 0);
                GL_LockArrays(0, 0);
        }
 
@@ -440,7 +441,7 @@ static void R_SkySphere(void)
                GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                GL_Color(r_refdef.fogcolor[0], r_refdef.fogcolor[1], r_refdef.fogcolor[2], 1 - r_refdef.fogmasktable[FOGMASKTABLEWIDTH-1]);
                GL_LockArrays(0, skysphere_numverts);
-               R_Mesh_Draw(0, skysphere_numverts, skysphere_numtriangles, skysphere_element3i, 0, 0);
+               R_Mesh_Draw(0, skysphere_numverts, 0, skysphere_numtriangles, NULL, skysphere_elements, 0, 0);
                GL_LockArrays(0, 0);
        }
 }
index 5e004ef..c267399 100644 (file)
--- a/render.h
+++ b/render.h
@@ -253,7 +253,9 @@ typedef struct rsurfacestate_s
        int modeltexcoordlightmap2f_bufferobject;
        size_t modeltexcoordlightmap2f_bufferoffset;
        int *modelelement3i;
+       unsigned short *modelelement3s;
        int modelelement3i_bufferobject;
+       int modelelement3s_bufferobject;
        int *modellightmapoffsets;
        int modelnum_vertices;
        int modelnum_triangles;