]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
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 4b4cd1d7f1f7891fe675a902b89d113161c69007..71071548787f3db028cd036f8972cc9bc15f1530 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 d3794fb6dfe6f09fccddad52e14ba5d1cbb6f764..6a127f5d77a230a623bff5c0adc824b649365e2c 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 67a219b8f07b52d4541317a0f22edfcaf49410b0..b14caee93abb8642b3bdd08b537cc8a4a3032f91 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 992fc3d70500c69efefe107faec1f19d8847bbd0..17c366bc8d975f8d7ed34e591c52c0f68ee9af33 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 fc9f71887fdc0441e92a45ee3060fec35d5461a0..871a6a09b196c34f723f74de718ce54b0bbc6309 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 8561d82cf5fb16380ccd8204f3e94b308f04c551..5ecff60fd7c8abb6e3c89991f6211fdd3aa659b5 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 01ac77bed7366928cbf66267b7ef9b351c4b2225..cf16422b51a836a0fa52c248d9d45e1359327105 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 658858daa3687618a1f8ca42833e5ed3e458024b..768642586dbf945d82aff8ab81537fbfc988d419 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 416c772097ed79a43117d4a2dab434517624d8a7..14c2a187acbd6ae17e1091083941e98b03f62da2 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 307da894d8ab32409934613e16eff4a71b6e675a..77b580efaacfdf27b2058aa9fadd40e35f80843a 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 59502511fe4cf557a87df48b0aec87d04a5e3f80..134b89597dfb091582726447a58192db2173dad7 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 3be80ec94b72ae96bf19ae35acad9571ee5370d7..3ebd38d5cb112deb033e135d28dab4ebaee20c40 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 30a5b771f0cc3b28cae66daa64b4c24cc5973d15..598598e87287e888c836b3153f9bcf29cbeab570 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 404a58af986ff89e76b91b59c3f5bd20969b0704..7ebaf1f9ba0fd5ce281c8e04b69651ab58b87ddc 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 584a02413782af5a7ca9406c9a1b1807e30e5e1f..ee4cee39da77fe8bcfad2a46386d1d0c8989cfda 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 d0bba73792f5c45cb7ef6fa34804f75a7d5a4212..2ff6dd64a35561560aa2763da3a7be40823279a5 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 d868dddf2103d5ec368aee53e7403d1c51dfb112..2a33e8c7f9476b15382e87e362c844ad4da71102 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 092fd8b13f7480763bdabfd6eedda6fcd5701b50..c5e842598de8a1859bd64e0cdff49f26de3f2c33 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 5e004ef9d4fbddde45c1d882203a403889a56d9f..c267399d28c2b416f5702843faec0f3277a55f19 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;