quick hack to test 16-bit indices

This commit is contained in:
Eric Wasylishen 2014-10-26 23:50:36 -06:00
parent 6763f8138c
commit d0c1e85375
3 changed files with 94 additions and 49 deletions

View file

@ -157,7 +157,8 @@ typedef struct msurface_s
mtexinfo_t *texinfo;
int vbo_firstvert; // index of this surface's first vert in the VBO
GLuint vbo;
unsigned short vbo_firstvert; // index of this surface's first vert in the VBO
// lighting info
int dlightframe;

View file

@ -959,7 +959,11 @@ void GL_BuildLightmaps (void)
=============================================================
*/
static GLuint gl_bmodel_vbo = 0;
#define MAX_BMODEL_VBOS 32
static GLuint gl_bmodel_vbos[MAX_BMODEL_VBOS];
/* 1.7MB */
#define VBO_SIZE (65536 * VERTEXSIZE * sizeof(float))
/*
==================
@ -971,36 +975,23 @@ surfaces from world + all brush models
*/
void GL_BuildVBOs (void)
{
unsigned int numverts, varray_bytes, varray_index;
unsigned int varray_index, varray_bytes, current_vbo_index;
int i, j;
qmodel_t *m;
float *varray;
unsigned char *varray;
if (!(gl_vbo_able && gl_mtexable && gl_max_texture_units >= 3))
return;
// ask GL for a name for our VBO
GL_DeleteBuffersFunc (1, &gl_bmodel_vbo);
GL_GenBuffersFunc (1, &gl_bmodel_vbo);
// count all verts in all models
numverts = 0;
for (j=1 ; j<MAX_MODELS ; j++)
{
m = cl.model_precache[j];
if (!m || m->name[0] == '*' || m->type != mod_brush)
continue;
GL_DeleteBuffersFunc (MAX_BMODEL_VBOS, gl_bmodel_vbos);
GL_GenBuffersFunc (MAX_BMODEL_VBOS, gl_bmodel_vbos);
for (i=0 ; i<m->numsurfaces ; i++)
{
numverts += m->surfaces[i].numedges;
}
}
// build vertex array
varray_bytes = VERTEXSIZE * sizeof(float) * numverts;
varray = (float *) malloc (varray_bytes);
// build vertex array
varray = (unsigned char *) malloc (VBO_SIZE);
varray_bytes = 0;
varray_index = 0;
current_vbo_index = 0;
for (j=1 ; j<MAX_MODELS ; j++)
{
@ -1008,36 +999,54 @@ void GL_BuildVBOs (void)
if (!m || m->name[0] == '*' || m->type != mod_brush)
continue;
// sort by texture
R_ClearTextureChains(m, chain_world);
for (i=0 ; i<m->numsurfaces ; i++)
{
msurface_t *s = &m->surfaces[i];
s->vbo_firstvert = varray_index;
memcpy (&varray[VERTEXSIZE * varray_index], s->polys->verts, VERTEXSIZE * sizeof(float) * s->numedges);
varray_index += s->numedges;
R_ChainSurface(&m->surfaces[i], chain_world);
}
// add the sorted surfaces
for (i=0 ; i<m->numtextures ; i++)
{
texture_t *t;
msurface_t *s;
t = m->textures[i];
if (!t) continue;
for (s = t->texturechains[chain_world]; s; s = s->texturechain)
{
const int surf_bytes = VERTEXSIZE * sizeof(float) * s->numedges;
if (varray_bytes + surf_bytes > VBO_SIZE)
{
// start a new vbo
GL_BindBufferFunc (GL_ARRAY_BUFFER, gl_bmodel_vbos[current_vbo_index]);
GL_BufferDataFunc (GL_ARRAY_BUFFER, varray_bytes, varray, GL_STATIC_DRAW);
current_vbo_index++;
varray_bytes = 0;
varray_index = 0;
// fixme: check for out of vbo's
}
s->vbo = gl_bmodel_vbos[current_vbo_index];
s->vbo_firstvert = varray_index; // todo: rewrite so it's clear this will fit in unsigned short?
memcpy (varray + varray_bytes, s->polys->verts, surf_bytes);
varray_bytes += surf_bytes;
varray_index += s->numedges;
}
}
}
// upload to GPU
GL_BindBufferFunc (GL_ARRAY_BUFFER, gl_bmodel_vbo);
// upload last VBO
GL_BindBufferFunc (GL_ARRAY_BUFFER, gl_bmodel_vbos[current_vbo_index]);
GL_BufferDataFunc (GL_ARRAY_BUFFER, varray_bytes, varray, GL_STATIC_DRAW);
// clean up
GL_BindBufferFunc (GL_ARRAY_BUFFER, 0);
free (varray);
// setup vertex array. this will need to move if we use vertex arrays for other things
glVertexPointer (3, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0));
glEnableClientState (GL_VERTEX_ARRAY);
GL_ClientActiveTextureFunc (GL_TEXTURE0_ARB);
glTexCoordPointer (2, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0) + 3);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
GL_ClientActiveTextureFunc (GL_TEXTURE1_ARB);
glTexCoordPointer (2, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0) + 5);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
// TMU 2 is for fullbrights; same texture coordinates as TMU 0
GL_ClientActiveTextureFunc (GL_TEXTURE2_ARB);
glTexCoordPointer (2, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0) + 3);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
}
/*

View file

@ -441,7 +441,7 @@ Writes out the triangle indices needed to draw s as a triangle list.
The number of indices it will write is given by R_NumTriangleIndicesForSurf.
================
*/
static void R_TriangleIndicesForSurf (msurface_t *s, unsigned int *dest)
static void R_TriangleIndicesForSurf (msurface_t *s, unsigned short *dest)
{
int i;
for (i=2; i<s->numedges; i++)
@ -454,8 +454,9 @@ static void R_TriangleIndicesForSurf (msurface_t *s, unsigned int *dest)
#define MAX_BATCH_SIZE 4096
static unsigned int vbo_indices[MAX_BATCH_SIZE];
static unsigned short vbo_indices[MAX_BATCH_SIZE];
static unsigned int num_vbo_indices;
static GLuint bound_vbo;
/*
================
@ -478,11 +479,13 @@ static void R_FlushBatch ()
{
if (num_vbo_indices > 0)
{
glDrawElements (GL_TRIANGLES, num_vbo_indices, GL_UNSIGNED_INT, vbo_indices);
glDrawElements (GL_TRIANGLES, num_vbo_indices, GL_UNSIGNED_SHORT, vbo_indices);
num_vbo_indices = 0;
}
}
static int bufferbindings = 0;
/*
================
R_BatchSurface
@ -495,6 +498,32 @@ static void R_BatchSurface (msurface_t *s)
{
int num_surf_indices;
if (s->vbo != bound_vbo)
{
R_FlushBatch();
bufferbindings ++;
GL_BindBufferFunc(GL_ARRAY_BUFFER, s->vbo);
bound_vbo = s->vbo;
// setup vertex array. this will need to move if we use vertex arrays for other things
glVertexPointer (3, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0));
glEnableClientState (GL_VERTEX_ARRAY);
GL_ClientActiveTextureFunc (GL_TEXTURE0_ARB);
glTexCoordPointer (2, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0) + 3);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
GL_ClientActiveTextureFunc (GL_TEXTURE1_ARB);
glTexCoordPointer (2, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0) + 5);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
// TMU 2 is for fullbrights; same texture coordinates as TMU 0
GL_ClientActiveTextureFunc (GL_TEXTURE2_ARB);
glTexCoordPointer (2, GL_FLOAT, VERTEXSIZE * sizeof(float), ((float *)0) + 3);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
}
num_surf_indices = R_NumTriangleIndicesForSurf (s);
if (num_vbo_indices + num_surf_indices > MAX_BATCH_SIZE)
@ -796,6 +825,11 @@ void R_DrawTextureChains_Multitexture_VBO (qmodel_t *model, entity_t *ent, texch
int lastlightmap;
gltexture_t *fullbright = NULL;
// ensure we bind to a vbo for the first surface
bound_vbo = 0;
bufferbindings = 0;
// Setup TMU 1 (lightmap)
GL_SelectTexture (GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
@ -862,6 +896,7 @@ void R_DrawTextureChains_Multitexture_VBO (qmodel_t *model, entity_t *ent, texch
glDisable (GL_ALPHA_TEST); // Flip alpha test back off
}
// Reset TMU states
GL_SelectTexture (GL_TEXTURE2_ARB);
glDisable (GL_TEXTURE_2D);