diff --git a/polymer/build/include/baselayer.h b/polymer/build/include/baselayer.h
index 74854c8d3..c463952a8 100644
--- a/polymer/build/include/baselayer.h
+++ b/polymer/build/include/baselayer.h
@@ -48,6 +48,7 @@ struct glinfo {
char rect;
char multitex;
char envcombine;
+ char vbos;
};
extern struct glinfo glinfo;
#endif
diff --git a/polymer/build/include/build.h b/polymer/build/include/build.h
index 2de68fe4e..b5c760713 100644
--- a/polymer/build/include/build.h
+++ b/polymer/build/include/build.h
@@ -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);
diff --git a/polymer/build/include/glbuild.h b/polymer/build/include/glbuild.h
index 5e2491fca..269bf6033 100644
--- a/polymer/build/include/glbuild.h
+++ b/polymer/build/include/glbuild.h
@@ -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);
diff --git a/polymer/build/src/baselayer.c b/polymer/build/src/baselayer.c
index d7e4bd6f8..cef10ece1 100644
--- a/polymer/build/src/baselayer.c
+++ b/polymer/build/src/baselayer.c
@@ -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);
diff --git a/polymer/build/src/glbuild.c b/polymer/build/src/glbuild.c
index 235169a9c..a6acae4cc 100644
--- a/polymer/build/src/glbuild.c
+++ b/polymer/build/src/glbuild.c
@@ -133,6 +133,14 @@ void (APIENTRY * bglBindFramebufferEXT)(GLenum target, GLuint framebuffer);
void (APIENTRY * bglFramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
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);
@@ -366,7 +374,15 @@ int loadglextensions(void)
bglFramebufferTexture2DEXT = GETPROCEXTSOFT("glFramebufferTexture2DEXT");
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;
}
@@ -501,6 +517,14 @@ int unloadgldriver(void)
bglFramebufferTexture2DEXT = NULL;
bglCheckFramebufferStatusEXT = NULL;
bglDeleteFramebuffersEXT = NULL;
+
+ // Vertex Buffer Objects
+ bglGenBuffersARB = NULL;
+ bglBindBufferARB = NULL;
+ bglDeleteBuffersARB = NULL;
+ bglBufferDataARB = NULL;
+ bglMapBufferARB = NULL;
+ bglUnmapBufferARB = NULL;
#ifdef RENDERTYPEWIN
bwglCreateContext = NULL;
diff --git a/polymer/build/src/mdsprite.c b/polymer/build/src/mdsprite.c
index e77fd28f6..03e7f7196 100644
--- a/polymer/build/src/mdsprite.c
+++ b/polymer/build/src/mdsprite.c
@@ -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];
diff --git a/polymer/build/src/polymost.c b/polymer/build/src/polymost.c
index 0c94fef8d..ab61a249d 100644
--- a/polymer/build/src/polymost.c
+++ b/polymer/build/src/polymost.c
@@ -156,7 +156,11 @@ long r_detailmapping = 1;
long r_glowmapping = 1;
// Vertex Array model drawing cvar
-long r_vertexarrays = 1;
+long r_vertexarrays = 1;
+
+// Vertex Buffer Objects model drawing cvars
+long r_vbos = 1;
+long r_vbocount = 1;
static float fogresult, ofogresult, fogcol[4];
@@ -413,7 +417,7 @@ pthtyp * gltexcache (long dapicnum, long dapalnum, long dameth)
memcpy(pth, pth2, sizeof(pthtyp));
pth->picnum = dapicnum;
pth->flags = ((dameth&4)>>2) + 2 + ((drawingskybox>0)<<2);
- if (pth2->flags & 8) pth->flags |= 8; //hasalpha
+ if (pth2->flags & 8) pth->flags |= 8; //hasalpha
pth->hicr = si;
pth->next = gltexcachead[j];
gltexcachead[j] = pth;
@@ -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);
diff --git a/polymer/build/src/sdlayer.c b/polymer/build/src/sdlayer.c
index 23c07ea07..88a723510 100644
--- a/polymer/build/src/sdlayer.c
+++ b/polymer/build/src/sdlayer.c
@@ -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);
}
diff --git a/polymer/build/src/winlayer.c b/polymer/build/src/winlayer.c
index 1eef6594e..f1d8ad970 100644
--- a/polymer/build/src/winlayer.c
+++ b/polymer/build/src/winlayer.c
@@ -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);
}
diff --git a/polymer/eduke32/eduke32.vcproj b/polymer/eduke32/eduke32.vcproj
index bdd5ce292..22dcdee1c 100644
--- a/polymer/eduke32/eduke32.vcproj
+++ b/polymer/eduke32/eduke32.vcproj
@@ -694,11 +694,11 @@
>