diff --git a/polymer/build/include/glbuild.h b/polymer/build/include/glbuild.h index 629bb95ed..a2e7b2706 100644 --- a/polymer/build/include/glbuild.h +++ b/polymer/build/include/glbuild.h @@ -175,6 +175,7 @@ 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 * bglBufferSubDataARB)(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data); extern void* (APIENTRY * bglMapBufferARB)(GLenum target, GLenum access); extern GLboolean (APIENTRY * bglUnmapBufferARB)(GLenum target); diff --git a/polymer/build/include/polymer.h b/polymer/build/include/polymer.h index 82377bfb0..d4c9b387d 100644 --- a/polymer/build/include/polymer.h +++ b/polymer/build/include/polymer.h @@ -1,22 +1,19 @@ // here lies the GREAT JUSTICE RENDERER // TODO : // - CORE STUFF -// o put all the sector/wall geometry in VBOs +// o use BufferData only once for VBOs // o there's also the texture alignment problem Hunter reported (san andreas fault) // o also sliding doors are still fucked up sometimes (like under the bar in E1L2) // o port glowmaps and detail maps from hacked polymost (:( // o shading needs a lot of work // o remove all the IM matrix crap and write real functions now that it works -// o polymer.c possibly needs to be split in several source files -// o some crap really needs factorization -// o ... possibly more important stuff I don't have in mind right now // - SPRITES // o port sprite panning and fullbrights from hacked polymost (:( // - SKIES // o figure a better way to handle ART skies - maybe add symetric caps that would fade to black like a big gem or something wow this is a long column lol ;0) // o implement polymost skyboxes // - MDSPRITES -// o need to reimplement them - hopefully the loader can be reused without too much hassle +// o need to truly convert MD2s to MD3s with proper scale offset to just dump the data into VRAM // o need full translation and rotation support from CON to attach to game world or tags // o need to put frames into VBOs and blend between them // @@ -41,6 +38,7 @@ extern int pr_fov; extern int pr_billboardingmode; extern int pr_verbosity; extern int pr_wireframe; +extern int pr_vbos; extern int glerror; @@ -91,6 +89,7 @@ typedef struct s_prwall { // stuff GLfloat* bigportal; GLfloat* cap; + GLuint stuffvbo; // build wall data short cstat, nwallcstat; short picnum, overpicnum, nwallpicnum; diff --git a/polymer/build/src/glbuild.c b/polymer/build/src/glbuild.c index aa52d701b..9cb99e8b3 100644 --- a/polymer/build/src/glbuild.c +++ b/polymer/build/src/glbuild.c @@ -140,6 +140,7 @@ 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 * bglBufferSubDataARB)(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data); void* (APIENTRY * bglMapBufferARB)(GLenum target, GLenum access); GLboolean(APIENTRY * bglUnmapBufferARB)(GLenum target); @@ -402,6 +403,7 @@ int loadglextensions(void) bglBindBufferARB = GETPROCEXTSOFT("glBindBufferARB"); bglDeleteBuffersARB = GETPROCEXTSOFT("glDeleteBuffersARB"); bglBufferDataARB = GETPROCEXTSOFT("glBufferDataARB"); + bglBufferSubDataARB = GETPROCEXTSOFT("glBufferSubDataARB"); bglMapBufferARB = GETPROCEXTSOFT("glMapBufferARB"); bglUnmapBufferARB = GETPROCEXTSOFT("glUnmapBufferARB"); @@ -560,6 +562,7 @@ int unloadgldriver(void) bglBindBufferARB = NULL; bglDeleteBuffersARB = NULL; bglBufferDataARB = NULL; + bglBufferSubDataARB = NULL; bglMapBufferARB = NULL; bglUnmapBufferARB = NULL; diff --git a/polymer/build/src/polymer.c b/polymer/build/src/polymer.c index 7c98aba2b..ac87bd798 100644 --- a/polymer/build/src/polymer.c +++ b/polymer/build/src/polymer.c @@ -10,10 +10,13 @@ int pr_fov = 426; // appears to be the classic setting. int pr_billboardingmode = 1; int pr_verbosity = 1; // 0: silent, 1: errors and one-times, 2: multiple-times, 3: flood int pr_wireframe = 0; +int pr_vbos = 0; int pr_mirrordepth = 1; int glerror; +GLenum mapvbousage = GL_STREAM_DRAW_ARB; + // DATA _prsector *prsectors[MAXSECTORS]; _prwall *prwalls[MAXWALLS]; @@ -716,18 +719,19 @@ static void polymer_displayrooms(short dacursectnum) (polymer_portalinfrustum(nextwal->nextwall, frustum)))) { w = prwalls[nextwal->nextwall]; - bglVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), w->mask.buffer); + + if (pr_vbos > 0) + { + bglBindBufferARB(GL_ARRAY_BUFFER_ARB, w->stuffvbo); + bglVertexPointer(3, GL_FLOAT, 0, NULL); + } + else + bglVertexPointer(3, GL_FLOAT, 0, w->bigportal); + bglDrawArrays(GL_QUADS, 0, 4); - if ((w->underover & 1) && (w->underover & 4)) - { - bglVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), w->wall.buffer); - bglDrawArrays(GL_QUADS, 0, 4); - } - if ((w->underover & 2) && (w->underover & 8)) - { - bglVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), w->over.buffer); - bglDrawArrays(GL_QUADS, 0, 4); - } + + if (pr_vbos > 0) + bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); } j++; @@ -772,13 +776,26 @@ static void polymer_displayrooms(short dacursectnum) } } +#define OMGDRAWSHITVBO \ + bglBindBufferARB(GL_ARRAY_BUFFER_ARB, plane->vbo); \ + bglVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), NULL); \ + bglTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), (GLfloat*)(3 * sizeof(GLfloat))); \ + if (!plane->indices) \ + bglDrawArrays(GL_QUADS, 0, 4); \ + else \ + { \ + bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, plane->ivbo); \ + bglDrawElements(GL_TRIANGLES, indicecount, GL_UNSIGNED_SHORT, NULL); \ + } \ + bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); \ + bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0) -#define OMGDRAWSHIT \ - bglVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), plane->buffer); \ - bglTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), &plane->buffer[3]); \ - if (!plane->indices) \ - bglDrawArrays(GL_QUADS, 0, 4); \ - else \ +#define OMGDRAWSHIT \ + bglVertexPointer(3, GL_FLOAT, 5 * sizeof(GLfloat), plane->buffer); \ + bglTexCoordPointer(2, GL_FLOAT, 5 * sizeof(GLfloat), &plane->buffer[3]); \ + if (!plane->indices) \ + bglDrawArrays(GL_QUADS, 0, 4); \ + else \ bglDrawElements(GL_TRIANGLES, indicecount, GL_UNSIGNED_SHORT, plane->indices) static void polymer_drawplane(short sectnum, short wallnum, _prplane* plane, int indicecount) @@ -800,7 +817,12 @@ static void polymer_drawplane(short sectnum, short wallnum, _prplane* pl bglStencilOp(GL_KEEP, GL_KEEP, GL_INCR); bglStencilFunc(GL_EQUAL, 0, 0xffffffff); - OMGDRAWSHIT; + if (plane->vbo && (pr_vbos > 0)) { + OMGDRAWSHITVBO; + } else { + OMGDRAWSHIT; + } + bglDepthMask(GL_TRUE); // set the depth to 1 where we put the stencil by drawing a screen aligned quad @@ -889,7 +911,11 @@ static void polymer_drawplane(short sectnum, short wallnum, _prplane* pl bglColor4f(plane->color[0], plane->color[1], plane->color[2], plane->color[3]); bglBindTexture(GL_TEXTURE_2D, plane->glpic); - OMGDRAWSHIT; + if (plane->vbo && (pr_vbos > 0)) { + OMGDRAWSHITVBO; + } else { + OMGDRAWSHIT; + } if ((depth < 1) && (plane->plane != NULL) && (wallnum >= 0) && (wall[wallnum].overpicnum == 560)) // insert mirror condition here @@ -1152,12 +1178,12 @@ static int polymer_updatesector(short sectnum) i = -1; attributes: - if ((i == -1) || (wallinvalidate)) + if ((pr_vbos > 0) && ((i == -1) || (wallinvalidate))) { bglBindBufferARB(GL_ARRAY_BUFFER_ARB, s->floor.vbo); - bglBufferDataARB(GL_ARRAY_BUFFER_ARB, sec->wallnum * sizeof(GLfloat) * 5, s->floor.buffer, GL_STATIC_DRAW_ARB); + bglBufferDataARB(GL_ARRAY_BUFFER_ARB, sec->wallnum * sizeof(GLfloat) * 5, s->floor.buffer, mapvbousage); bglBindBufferARB(GL_ARRAY_BUFFER_ARB, s->ceil.vbo); - bglBufferDataARB(GL_ARRAY_BUFFER_ARB, sec->wallnum * sizeof(GLfloat) * 5, s->ceil.buffer, GL_STATIC_DRAW_ARB); + bglBufferDataARB(GL_ARRAY_BUFFER_ARB, sec->wallnum * sizeof(GLfloat) * 5, s->ceil.buffer, mapvbousage); bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); } @@ -1230,11 +1256,13 @@ finish: if (needfloor) { polymer_buildfloor(sectnum); - bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, s->floor.ivbo); - bglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, s->indicescount * sizeof(GLushort), s->floor.indices, GL_STATIC_DRAW_ARB); - bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, s->ceil.ivbo); - bglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, s->indicescount * sizeof(GLushort), s->ceil.indices, GL_STATIC_DRAW_ARB); - bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + if ((pr_vbos > 0)) { + bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, s->floor.ivbo); + bglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, s->indicescount * sizeof(GLushort), s->floor.indices, mapvbousage); + bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, s->ceil.ivbo); + bglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, s->indicescount * sizeof(GLushort), s->ceil.indices, mapvbousage); + bglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + } } if (wallinvalidate) @@ -1380,6 +1408,12 @@ static int polymer_initwall(short wallnum) if (w->cap == NULL) w->cap = calloc(4, sizeof(GLfloat) * 3); + bglGenBuffersARB(1, &w->wall.vbo); + bglGenBuffersARB(1, &w->over.vbo); + bglGenBuffersARB(1, &w->mask.vbo); + + bglGenBuffersARB(1, &w->stuffvbo); + w->controlstate = 2; prwalls[wallnum] = w; @@ -1837,6 +1871,21 @@ static void polymer_updatewall(short wallnum) memcpy(w->over.plane, w->wall.plane, sizeof(w->wall.plane)); memcpy(w->mask.plane, w->wall.plane, sizeof(w->wall.plane)); + if ((pr_vbos > 0)) + { + bglBindBufferARB(GL_ARRAY_BUFFER_ARB, w->wall.vbo); + bglBufferDataARB(GL_ARRAY_BUFFER_ARB, 4 * sizeof(GLfloat) * 5, w->wall.buffer, mapvbousage); + bglBindBufferARB(GL_ARRAY_BUFFER_ARB, w->over.vbo); + bglBufferDataARB(GL_ARRAY_BUFFER_ARB, 4 * sizeof(GLfloat) * 5, w->over.buffer, mapvbousage); + bglBindBufferARB(GL_ARRAY_BUFFER_ARB, w->mask.vbo); + bglBufferDataARB(GL_ARRAY_BUFFER_ARB, 4 * sizeof(GLfloat) * 5, w->mask.buffer, mapvbousage); + bglBindBufferARB(GL_ARRAY_BUFFER_ARB, w->stuffvbo); + bglBufferDataARB(GL_ARRAY_BUFFER_ARB, 8 * sizeof(GLfloat) * 3, NULL, mapvbousage); + bglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, 4 * sizeof(GLfloat) * 3, w->bigportal); + bglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 4 * sizeof(GLfloat) * 3, 4 * sizeof(GLfloat) * 3, w->cap); + bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } + w->controlstate = 1; if (pr_verbosity >= 3) OSD_Printf("PR : Updated wall %i.\n", wallnum); @@ -1865,8 +1914,20 @@ static void polymer_drawwall(short sectnum, short wallnum) !(sector[wall[wallnum].nextsector].ceilingstat & 1))) { bglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - bglVertexPointer(3, GL_FLOAT, 0, w->cap); + + if (pr_vbos) + { + bglBindBufferARB(GL_ARRAY_BUFFER_ARB, w->stuffvbo); + bglVertexPointer(3, GL_FLOAT, 0, (const GLvoid*)(4 * sizeof(GLfloat) * 3)); + } + else + bglVertexPointer(3, GL_FLOAT, 0, w->cap); + bglDrawArrays(GL_QUADS, 0, 4); + + if (pr_vbos) + bglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + bglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); } diff --git a/polymer/eduke32/source/osdcmds.c b/polymer/eduke32/source/osdcmds.c index 15043f9e5..ec5dfff0b 100644 --- a/polymer/eduke32/source/osdcmds.c +++ b/polymer/eduke32/source/osdcmds.c @@ -701,6 +701,7 @@ cvar[] = { "pr_billboardingmode", "pr_billboardingmode: face sprite display method. 0: classic mode; 1: polymost mode", (void*)&pr_billboardingmode, CVAR_INT, 0, 0, 1 }, { "pr_verbosity", "pr_verbosity: verbosity level of the polymer renderer", (void*)&pr_verbosity, CVAR_INT, 0, 0, 3 }, { "pr_wireframe", "pr_wireframe: toggles wireframe mode", (void*)&pr_wireframe, CVAR_INT, 0, 0, 1 }, + { "pr_vbos", "pr_vbos: contols Vertex Buffer Object usage. 0: no VBOs. 1: VBOs for map data. 2: VBOs for model data.", (void*)&pr_vbos, CVAR_INT, 0, 0, 2 }, #endif #endif { "r_precache", "r_precache: enable/disable the pre-level caching routine", (void*)&ud.config.useprecache, CVAR_BOOL, 0, 0, 1 },