Support for Vertex Buffer Objects (r_vbos, r_vbocount).

git-svn-id: https://svn.eduke32.com/eduke32@519 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
Plagman 2007-03-08 03:07:10 +00:00
parent 3fda3754cc
commit 3081c87724
11 changed files with 247 additions and 29 deletions

View file

@ -48,6 +48,7 @@ struct glinfo {
char rect;
char multitex;
char envcombine;
char vbos;
};
extern struct glinfo glinfo;
#endif

View file

@ -499,6 +499,8 @@ extern long r_depthpeeling, r_peelscount;
extern long r_detailmapping;
extern long r_glowmapping;
extern long r_vertexarrays;
extern long r_vbos;
extern long r_vbocount;
#endif
void hicinit(void);

View file

@ -163,6 +163,14 @@ extern void (APIENTRY * bglFramebufferTexture2DEXT)(GLenum target, GLenum attach
extern GLenum (APIENTRY * bglCheckFramebufferStatusEXT)(GLenum target);
extern void (APIENTRY * bglDeleteFramebuffersEXT)(GLsizei n, const GLuint *framebuffers);
// Vertex Buffer Objects
extern void (APIENTRY * bglGenBuffersARB)(GLsizei n, GLuint * buffers);
extern void (APIENTRY * bglBindBufferARB)(GLenum target, GLuint buffer);
extern void (APIENTRY * bglDeleteBuffersARB)(GLsizei n, const GLuint * buffers);
extern void (APIENTRY * bglBufferDataARB)(GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage);
extern void* (APIENTRY * bglMapBufferARB)(GLenum target, GLenum access);
extern GLboolean (APIENTRY * bglUnmapBufferARB)(GLenum target);
// GLU
extern void (APIENTRY * bgluTessBeginContour) (GLUtesselator* tess);
extern void (APIENTRY * bgluTessBeginPolygon) (GLUtesselator* tess, GLvoid* data);

View file

@ -28,6 +28,7 @@ struct glinfo glinfo = {
0, // rectangle textures
0, // multitexturing
0, // env_combine
0, // Vertex Buffer Objects
};
#endif
@ -101,6 +102,9 @@ static int osdcmd_glinfo(const osdfuncparm_t *parm)
" Shadow textures: %s\n"
" Frame Buffer Objects: %s\n"
" Rectangle textures: %s\n"
" Multitexturing: %s\n"
" env_combine: %s\n"
" Vertex Buffer Objects: %s\n"
" Extensions:\n",
glinfo.version,
glinfo.vendor,
@ -116,7 +120,10 @@ static int osdcmd_glinfo(const osdfuncparm_t *parm)
glinfo.depthtex ? "supported": "not supported",
glinfo.shadow ? "supported": "not supported",
glinfo.fbos ? "supported": "not supported",
glinfo.rect ? "supported": "not supported"
glinfo.rect ? "supported": "not supported",
glinfo.multitex ? "supported": "not supported",
glinfo.envcombine ? "supported": "not supported",
glinfo.vbos ? "supported": "not supported"
);
s = Bstrdup(glinfo.extensions);

View file

@ -134,6 +134,14 @@ void (APIENTRY * bglFramebufferTexture2DEXT)(GLenum target, GLenum attachment, G
GLenum (APIENTRY * bglCheckFramebufferStatusEXT)(GLenum target);
void (APIENTRY * bglDeleteFramebuffersEXT)(GLsizei n, const GLuint *framebuffers);
// Vertex Buffer Objects
void (APIENTRY * bglGenBuffersARB)(GLsizei n, GLuint * buffers);
void (APIENTRY * bglBindBufferARB)(GLenum target, GLuint buffer);
void (APIENTRY * bglDeleteBuffersARB)(GLsizei n, const GLuint * buffers);
void (APIENTRY * bglBufferDataARB)(GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage);
void* (APIENTRY * bglMapBufferARB)(GLenum target, GLenum access);
GLboolean (APIENTRY * bglUnmapBufferARB)(GLenum target);
// GLU
void (APIENTRY * bgluTessBeginContour) (GLUtesselator* tess);
void (APIENTRY * bgluTessBeginPolygon) (GLUtesselator* tess, GLvoid* data);
@ -367,6 +375,14 @@ int loadglextensions(void)
bglCheckFramebufferStatusEXT = GETPROCEXTSOFT("glCheckFramebufferStatusEXT");
bglDeleteFramebuffersEXT = GETPROCEXTSOFT("glDeleteFramebuffersEXT");
// Vertex Buffer Objects
bglGenBuffersARB = GETPROCEXTSOFT("glGenBuffersARB");
bglBindBufferARB = GETPROCEXTSOFT("glBindBufferARB");
bglDeleteBuffersARB = GETPROCEXTSOFT("glDeleteBuffersARB");
bglBufferDataARB = GETPROCEXTSOFT("glBufferDataARB");
bglMapBufferARB = GETPROCEXTSOFT("glMapBufferARB");
bglUnmapBufferARB = GETPROCEXTSOFT("glUnmapBufferARB");
return err;
}
@ -502,6 +518,14 @@ int unloadgldriver(void)
bglCheckFramebufferStatusEXT = NULL;
bglDeleteFramebuffersEXT = NULL;
// Vertex Buffer Objects
bglGenBuffersARB = NULL;
bglBindBufferARB = NULL;
bglDeleteBuffersARB = NULL;
bglBufferDataARB = NULL;
bglMapBufferARB = NULL;
bglUnmapBufferARB = NULL;
#ifdef RENDERTYPEWIN
bwglCreateContext = NULL;
bwglDeleteContext = NULL;

View file

@ -150,6 +150,7 @@ typedef struct
unsigned short *indexes;
unsigned short *vindexes;
float *maxdepths;
GLuint* vbos;
} md3model;
#define VOXBORDWIDTH 1 //use 0 to save memory, but has texture artifacts; 1 looks better...
@ -196,8 +197,13 @@ static long nummodelsalloced = 0, nextmodelid = 0;
static mdmodel **models = NULL;
static long maxmodelverts = 0, allocmodelverts = 0;
static long maxmodeltris = 0, allocmodeltris = 0;
static point3d *vertlist = NULL; //temp array to store interpolated vertices for drawing
static long allocvbos = 0, curvbo = 0;
static GLuint* vertvbos = NULL;
static GLuint* indexvbos = NULL;
mdmodel *mdload (const char *);
int mddraw (spritetype *);
void mdfree (mdmodel *);
@ -223,6 +229,16 @@ static void freeallmodels ()
free(vertlist);
vertlist = NULL;
allocmodelverts = maxmodelverts = 0;
allocmodeltris = maxmodeltris = 0;
}
if (allocvbos)
{
bglDeleteBuffersARB(allocvbos, indexvbos);
bglDeleteBuffersARB(allocvbos, vertvbos);
free(indexvbos);
free(vertvbos);
allocvbos = 0;
}
}
@ -886,6 +902,24 @@ else { if (i >= j) { i -= j; if (i >= j) i %= j; } }
m->interpol = ((float)(i&65535))/65536.f;
}
// VBO generation and allocation
static void mdloadvbos (md3model *m)
{
int i;
m->vbos = malloc(m->head.numsurfs * sizeof(GLuint));
bglGenBuffersARB(m->head.numsurfs, m->vbos);
i = 0;
while (i < m->head.numsurfs)
{
bglBindBufferARB(GL_ARRAY_BUFFER_ARB, m->vbos[i]);
bglBufferDataARB(GL_ARRAY_BUFFER_ARB, m->head.surfs[i].numverts * sizeof(md3uv_t), m->head.surfs[i].uv, GL_STATIC_DRAW_ARB);
i++;
}
bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
//--------------------------------------- MD2 LIBRARY BEGINS ---------------------------------------
static long long memoryusage = 0;
@ -978,6 +1012,7 @@ m->basepath = (char *)malloc(i+1); if (!m->basepath) { free(m->uv); free(m->tris
if (!m->texid) { free(m->skinfn); free(m->basepath); free(m->uv); free(m->tris); free(m->glcmds); free(m->frames); free(m); return(0); }
maxmodelverts = max(maxmodelverts, m->numverts);
maxmodeltris = max(maxmodeltris, head.numtris);
//return(m);
@ -1096,6 +1131,8 @@ m->basepath = (char *)malloc(i+1); if (!m->basepath) { free(m->uv); free(m->tris
m3->vindexes = malloc(sizeof(unsigned short) * s->numtris * 3);
m3->maxdepths = malloc(sizeof(float) * s->numtris);
m3->vbos = NULL;
// die MD2 ! DIE !
free(m->texid); free(m->skinfn); free(m->basepath); free(m->uv); free(m->tris); free(m->glcmds); free(m->frames); free(m);
@ -1266,6 +1303,7 @@ if ((m->head.id != 0x33504449) && (m->head.vers != 15)) { free(m); return(0); }
}
#endif
maxmodelverts = max(maxmodelverts, s->numverts);
maxmodeltris = max(maxmodeltris, s->numtris);
maxtrispersurf = max(maxtrispersurf, s->numtris);
ofsurf += s->ofsend;
}
@ -1295,6 +1333,8 @@ if ((m->head.id != 0x33504449) && (m->head.vers != 15)) { free(m); return(0); }
m->vindexes = malloc(sizeof(unsigned short) * maxtrispersurf * 3);
m->maxdepths = malloc(sizeof(float) * maxtrispersurf);
m->vbos = NULL;
return(m);
}
@ -1309,7 +1349,12 @@ static int md3draw (md3model *m, spritetype *tspr)
mdskinmap_t *sk;
//PLAG : sorting stuff
unsigned short tempus;
void* vbotemp;
point3d* vertexhandle;
unsigned short* indexhandle;
if (r_vbos && (m->vbos == NULL))
mdloadvbos(m);
// if ((tspr->cstat&48) == 32) return 0;
@ -1475,6 +1520,16 @@ if (tspr->cstat&2) { if (!(tspr->cstat&512)) pc[3] = 0.66; else pc[3] = 0.33; }
v0 = &s->xyzn[m->cframe*s->numverts];
v1 = &s->xyzn[m->nframe*s->numverts];
if (r_vertexarrays && r_vbos)
{
if (++curvbo >= r_vbocount)
curvbo = 0;
bglBindBufferARB(GL_ARRAY_BUFFER_ARB, vertvbos[curvbo]);
vbotemp = bglMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
vertexhandle = (point3d *)vbotemp;
}
for (i=s->numverts-1;i>=0;i--)
{
if (spriteext[tspr->owner].pitch || spriteext[tspr->owner].roll || m->head.flags == 1337)
@ -1501,10 +1556,23 @@ if (tspr->cstat&2) { if (!(tspr->cstat&512)) pc[3] = 0.66; else pc[3] = 0.33; }
fp.y = v0[i].z*m0.z + v1[i].z*m1.z;
fp.x = v0[i].y*m0.y + v1[i].y*m1.y;
}
if (r_vertexarrays && r_vbos)
{
vertexhandle[i].x = fp.x;
vertexhandle[i].y = fp.y;
vertexhandle[i].z = fp.z;
}
vertlist[i].x = fp.x;
vertlist[i].y = fp.y;
vertlist[i].z = fp.z;
}
if (r_vertexarrays && r_vbos)
{
bglUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
bglMatrixMode(GL_MODELVIEW); //Let OpenGL (and perhaps hardware :) handle the matrix rotation
mat[3] = mat[7] = mat[11] = 0.f; mat[15] = 1.f; bglLoadMatrixf(mat);
// PLAG: End
@ -1585,6 +1653,15 @@ if (tspr->cstat&2) { if (!(tspr->cstat&512)) pc[3] = 0.66; else pc[3] = 0.33; }
bglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
}
if (r_vertexarrays && r_vbos)
{
bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexvbos[curvbo]);
vbotemp = bglMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
indexhandle = (unsigned short *)vbotemp;
}
else
indexhandle = m->vindexes;
//PLAG: delayed polygon-level sorted rendering
if (m->usesalpha && !(tspr->cstat & 1024) && !r_depthpeeling)
{
@ -1624,17 +1701,7 @@ if (tspr->cstat&2) { if (!(tspr->cstat&512)) pc[3] = 0.66; else pc[3] = 0.33; }
k = 0;
for (i=s->numtris-1;i>=0;i--)
for (j=0;j<3;j++)
m->vindexes[k++] = s->tris[m->indexes[i]].i[j];
bglVertexPointer(3, GL_FLOAT, 0, &(vertlist[0].x));
l = GL_TEXTURE0_ARB;
while (l <= texunits)
{
bglClientActiveTextureARB(l++);
bglEnableClientState(GL_TEXTURE_COORD_ARRAY);
bglTexCoordPointer(2, GL_FLOAT, 0, &(s->uv[0].u));
}
bglDrawElements(GL_TRIANGLES, s->numtris * 3, GL_UNSIGNED_SHORT, m->vindexes);
indexhandle[k++] = s->tris[m->indexes[i]].i[j];
}
else
{
@ -1663,17 +1730,7 @@ if (tspr->cstat&2) { if (!(tspr->cstat&512)) pc[3] = 0.66; else pc[3] = 0.33; }
k = 0;
for (i=s->numtris-1;i>=0;i--)
for (j=0;j<3;j++)
m->vindexes[k++] = s->tris[i].i[j];
bglVertexPointer(3, GL_FLOAT, 0, &(vertlist[0].x));
l = GL_TEXTURE0_ARB;
while (l <= texunits)
{
bglClientActiveTextureARB(l++);
bglEnableClientState(GL_TEXTURE_COORD_ARRAY);
bglTexCoordPointer(2, GL_FLOAT, 0, &(s->uv[0].u));
}
bglDrawElements(GL_TRIANGLES, s->numtris * 3, GL_UNSIGNED_SHORT, m->vindexes);
indexhandle[k++] = s->tris[i].i[j];
}
else
{
@ -1696,6 +1753,50 @@ if (tspr->cstat&2) { if (!(tspr->cstat&512)) pc[3] = 0.66; else pc[3] = 0.33; }
}
}
if (r_vertexarrays && r_vbos)
{
bglUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
if (r_vertexarrays)
{
if (r_vbos)
bglBindBufferARB(GL_ARRAY_BUFFER_ARB, m->vbos[surfi]);
l = GL_TEXTURE0_ARB;
while (l <= texunits)
{
bglClientActiveTextureARB(l++);
bglEnableClientState(GL_TEXTURE_COORD_ARRAY);
if (r_vbos)
bglTexCoordPointer(2, GL_FLOAT, 0, 0);
else
bglTexCoordPointer(2, GL_FLOAT, 0, &(s->uv[0].u));
}
if (r_vbos)
{
bglBindBufferARB(GL_ARRAY_BUFFER_ARB, vertvbos[curvbo]);
bglVertexPointer(3, GL_FLOAT, 0, 0);
}
else
bglVertexPointer(3, GL_FLOAT, 0, &(vertlist[0].x));
if (r_vbos)
{
bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexvbos[curvbo]);
bglDrawElements(GL_TRIANGLES, s->numtris * 3, GL_UNSIGNED_SHORT, 0);
}
else
bglDrawElements(GL_TRIANGLES, s->numtris * 3, GL_UNSIGNED_SHORT, m->vindexes);
if (r_vbos)
{
bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
}
while (texunits > GL_TEXTURE0_ARB)
{
bglMatrixMode(GL_TEXTURE);
@ -1773,6 +1874,12 @@ static void md3free (md3model *m)
if (m->vindexes) free(m->vindexes);
if (m->maxdepths) free(m->maxdepths);
if (r_vbos && m->vbos)
{
bglDeleteBuffersARB(m->head.numsurfs, m->vbos);
free(m->vbos);
}
free(m);
}
@ -2609,12 +2716,38 @@ int mddraw (spritetype *tspr)
{
mdanim_t *anim;
mdmodel *vm;
int i;
if (r_vbos && (r_vbocount > allocvbos))
{
indexvbos = realloc(indexvbos, sizeof(GLuint) * r_vbocount);
vertvbos = realloc(vertvbos, sizeof(GLuint) * r_vbocount);
bglGenBuffersARB(r_vbocount - allocvbos, &(indexvbos[allocvbos]));
bglGenBuffersARB(r_vbocount - allocvbos, &(vertvbos[allocvbos]));
i = allocvbos;
while (i < r_vbocount)
{
bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexvbos[i]);
bglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, maxmodeltris * 3 * sizeof(unsigned short), NULL, GL_STREAM_DRAW_ARB);
bglBindBufferARB(GL_ARRAY_BUFFER_ARB, vertvbos[i]);
bglBufferDataARB(GL_ARRAY_BUFFER_ARB, maxmodelverts * sizeof(point3d), NULL, GL_STREAM_DRAW_ARB);
i++;
}
bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
allocvbos = r_vbocount;
}
if (maxmodelverts > allocmodelverts)
{
point3d *vl = (point3d *)realloc(vertlist,sizeof(point3d)*maxmodelverts);
if (!vl) { OSD_Printf("ERROR: Not enough memory to allocate %d vertices!\n",maxmodelverts); return 0; }
vertlist = vl; allocmodelverts = maxmodelverts;
vertlist = vl;
allocmodelverts = maxmodelverts;
}
vm = models[tile2model[tspr->picnum].modelid];

View file

@ -158,6 +158,10 @@ long r_glowmapping = 1;
// Vertex Array model drawing cvar
long r_vertexarrays = 1;
// Vertex Buffer Objects model drawing cvars
long r_vbos = 1;
long r_vbocount = 1;
static float fogresult, ofogresult, fogcol[4];
@ -733,6 +737,12 @@ void polymost_glinit()
r_glowmapping = 0;
}
if (r_vbos && (!glinfo.vbos))
{
OSD_Printf("Your OpenGL implementation doesn't support Vertex Buffer Objects. Disabling...\n");
r_vbos = 0;
}
//depth peeling initialization
if (r_depthpeeling)
{
@ -5346,6 +5356,25 @@ static int osdcmd_polymostvars(const osdfuncparm_t *parm)
else r_vertexarrays = (val != 0);
return OSDCMD_OK;
}
else if (!Bstrcasecmp(parm->name, "r_vbos")) {
if (showval) { OSD_Printf("r_vbos is %d\n", r_vbos); }
else {
if (!glinfo.vbos)
{
OSD_Printf("Your OpenGL implementation doesn't support Vertex Buffer Objects.\n");
r_vbos = 0;
return OSDCMD_OK;
}
r_vbos = (val != 0);
}
return OSDCMD_OK;
}
else if (!Bstrcasecmp(parm->name, "r_vbocount")) {
if (showval) { OSD_Printf("r_vbocount is %d\n", r_vbocount); }
else if (val < 1) { OSD_Printf("Value out of range.\n"); }
else r_vbocount = val;
return OSDCMD_OK;
}
else if (!Bstrcasecmp(parm->name, "glpolygonmode")) {
if (showval) { OSD_Printf("glpolygonmode is %d\n", glpolygonmode); }
else glpolygonmode = val;
@ -5433,6 +5462,8 @@ void polymost_initosdfuncs(void)
OSD_RegisterFunction("r_detailmapping","r_detailmapping: enable/disable detail mapping",osdcmd_polymostvars);
OSD_RegisterFunction("r_glowmapping","r_glowmapping: enable/disable glow mapping",osdcmd_polymostvars);
OSD_RegisterFunction("r_vertexarrays","r_vertexarrays: enable/disable using vertex arrays when drawing models",osdcmd_polymostvars);
OSD_RegisterFunction("r_vbos","r_vbos: enable/disable using Vertex Buffer Objects when drawing models",osdcmd_polymostvars);
OSD_RegisterFunction("r_vbocount","r_vbocount: sets the number of Vertex Buffer Objects to use when drawing models",osdcmd_polymostvars);
#endif
OSD_RegisterFunction("usemodels","usemodels: enable/disable model rendering in >8-bit mode",osdcmd_polymostvars);
OSD_RegisterFunction("usehightile","usehightile: enable/disable hightile texture rendering in >8-bit mode",osdcmd_polymostvars);

View file

@ -1078,6 +1078,10 @@ int setvideomode(int x, int y, int c, int fs)
{
glinfo.envcombine = 1;
}
else if (!Bstrcmp((char *)p2, "GL_ARB_vertex_buffer_object"))
{
glinfo.vbos = 1;
}
}
Bfree(p);
}

View file

@ -2961,6 +2961,10 @@ static int SetupOpenGL(int width, int height, int bitspp)
{
glinfo.envcombine = 1;
}
else if (!Bstrcmp((char *)p2, "GL_ARB_vertex_buffer_object"))
{
glinfo.vbos = 1;
}
}
Bfree(p);
}

View file

@ -694,11 +694,11 @@
>
</File>
<File
RelativePath=".\source\develop.h"
RelativePath=".\source\jmact\develop.h"
>
</File>
<File
RelativePath=".\source\jmact\develop.h"
RelativePath=".\source\develop.h"
>
</File>
<File

View file

@ -682,6 +682,8 @@ int32 CONFIG_ReadSetup(void)
SCRIPT_GetNumber(scripthandle, "Screen Setup", "GLDetailMapping", &r_detailmapping);
SCRIPT_GetNumber(scripthandle, "Screen Setup", "GLGlowMapping", &r_glowmapping);
SCRIPT_GetNumber(scripthandle, "Screen Setup", "GLVertexArrays", &r_vertexarrays);
SCRIPT_GetNumber(scripthandle, "Screen Setup", "GLVBOs", &r_vbos);
SCRIPT_GetNumber(scripthandle, "Screen Setup", "GLVBOCount", &r_vbocount);
dummy = usemodels;
SCRIPT_GetNumber(scripthandle, "Screen Setup", "UseModels",&dummy);
@ -840,6 +842,8 @@ void CONFIG_WriteSetup(void)
SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLDetailMapping", r_detailmapping,false,false);
SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLGlowMapping", r_glowmapping,false,false);
SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLVertexArrays", r_vertexarrays,false,false);
SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLVBOs", r_vbos,false,false);
SCRIPT_PutNumber(scripthandle, "Screen Setup", "GLVBOCount", r_vbocount,false,false);
#endif
#ifdef RENDERTYPEWIN
SCRIPT_PutNumber(scripthandle, "Screen Setup", "MaxRefreshFreq",maxrefreshfreq,false,false);