diff --git a/source/src/cube.h b/source/src/cube.h index e80ab70a..29962db1 100644 --- a/source/src/cube.h +++ b/source/src/cube.h @@ -86,7 +86,7 @@ extern bool minimap, reflecting, refracting; extern bool demoplayback; extern bool intermission; extern int maxclients; -extern bool hasTE, hasMT; +extern bool hasTE, hasMT, hasMDA; extern int VIRTW; // virtual screen size for text & HUD #define VIRTH 1800 diff --git a/source/src/protos.h b/source/src/protos.h index ad248a93..32bc1b67 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -1,5 +1,14 @@ // protos for ALL external functions in cube... +// GL_ARB_multitexture +extern PFNGLACTIVETEXTUREARBPROC glActiveTexture_; +extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTexture_; +extern PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2f_; +extern PFNGLMULTITEXCOORD3FARBPROC glMultiTexCoord3f_; + +// GL_EXT_multi_draw_arrays +extern PFNGLMULTIDRAWARRAYSEXTPROC glMultiDrawArrays_; + // command extern bool persistidents; extern int variable(char *name, int min, int cur, int max, int *storage, void (*fun)(), bool persist); @@ -342,12 +351,6 @@ extern bool intersect(entity *e, vec &from, vec &to, vec *end=NULL); // rndmap extern void perlinarea(block &b, int scale, int seed, int psize); -// GL_ARB_multitexture -extern PFNGLACTIVETEXTUREARBPROC glActiveTexture_; -extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTexture_; -extern PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2f_; -extern PFNGLMULTITEXCOORD3FARBPROC glMultiTexCoord3f_; - // doc extern void renderdoc(int x, int y); extern void renderdocmenu(void *menu, bool init); diff --git a/source/src/rendercubes.cpp b/source/src/rendercubes.cpp index ba9e3567..580df5d4 100644 --- a/source/src/rendercubes.cpp +++ b/source/src/rendercubes.cpp @@ -20,26 +20,36 @@ void setupstrips() glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), &buf->u); } -struct strip { int type, start, num; }; +struct strips { vector first; vector count; }; struct stripbatch { int tex; - vector strips; + strips tris, tristrips, quads; }; -vector skystrips; +stripbatch skystrips = { DEFAULT_SKY }; stripbatch stripbatches[256]; uchar renderedtex[256]; int renderedtexs = 0; +#define RENDERSTRIPS(strips, type) \ + if(strips.first.length()) \ + { \ + if(hasMDA) glMultiDrawArrays_(type, strips.first.getbuf(), strips.count.getbuf(), strips.first.length()); \ + else loopv(strips.first) glDrawArrays(type, strips.first[i], strips.count[i]); \ + strips.first.setsizenodelete(0); \ + strips.count.setsizenodelete(0); \ + } + void renderstripssky() { - if(skystrips.empty()) return; + if(skystrips.tris.first.empty() && skystrips.tristrips.first.empty() && skystrips.quads.first.empty()) return; int xs, ys; glBindTexture(GL_TEXTURE_2D, lookuptexture(DEFAULT_SKY, xs, ys)); - loopv(skystrips) glDrawArrays(skystrips[i].type, skystrips[i].start, skystrips[i].num); - skystrips.setsizenodelete(0); + RENDERSTRIPS(skystrips.tris, GL_TRIANGLES); + RENDERSTRIPS(skystrips.tristrips, GL_TRIANGLE_STRIP); + RENDERSTRIPS(skystrips.quads, GL_QUADS); } void renderstrips() @@ -49,8 +59,9 @@ void renderstrips() { stripbatch &sb = stripbatches[j]; glBindTexture(GL_TEXTURE_2D, lookuptexture(sb.tex, xs, ys)); - loopv(sb.strips) glDrawArrays(sb.strips[i].type, sb.strips[i].start, sb.strips[i].num); - sb.strips.setsizenodelete(0); + RENDERSTRIPS(sb.tris, GL_TRIANGLES); + RENDERSTRIPS(sb.tristrips, GL_TRIANGLE_STRIP); + RENDERSTRIPS(sb.quads, GL_QUADS); } renderedtexs = 0; @@ -61,36 +72,29 @@ void renderstrips() void addstrip(int type, int tex, int start, int n) { - vector *strips; - + stripbatch *sb = NULL; if(tex==DEFAULT_SKY) { if(minimap) return; - strips = &skystrips; + sb = &skystrips; } else { - stripbatch *sb = &stripbatches[renderedtex[tex]]; + sb = &stripbatches[renderedtex[tex]]; if(sb->tex!=tex || sb>=&stripbatches[renderedtexs]) { sb = &stripbatches[renderedtex[tex] = renderedtexs++]; sb->tex = tex; } - strips = &sb->strips; } - if(type!=GL_TRIANGLE_STRIP && !strips->empty()) + strips &s = (type==GL_QUADS ? sb->quads : (type==GL_TRIANGLE_STRIP ? sb->tristrips : sb->tris)); + if(type!=GL_TRIANGLE_STRIP && s.first.length() && s.first.last()+s.count.last() == start) { - strip &last = strips->last(); - if(last.type==type && last.start+last.num==start) - { - last.num += n; - return; - } + s.count.last() += n; + return; } - strip &s = strips->add(); - s.type = type; - s.start = start; - s.num = n; + s.first.add(start); + s.count.add(n); } // generating the actual vertices is done dynamically every frame and sits at the diff --git a/source/src/rendergl.cpp b/source/src/rendergl.cpp index 24700bda..0e296c89 100644 --- a/source/src/rendergl.cpp +++ b/source/src/rendergl.cpp @@ -3,7 +3,7 @@ #include "cube.h" #include "bot/bot.h" -bool hasTE = false, hasMT = false; +bool hasTE = false, hasMT = false, hasMDA = false; // GL_ARB_multitexture PFNGLACTIVETEXTUREARBPROC glActiveTexture_ = NULL; @@ -11,6 +11,9 @@ PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTexture_ = NULL; PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2f_ = NULL; PFNGLMULTITEXCOORD3FARBPROC glMultiTexCoord3f_ = NULL; +// GL_EXT_multi_draw_arrays +PFNGLMULTIDRAWARRAYSEXTPROC glMultiDrawArrays_ = NULL; + void *getprocaddress(const char *name) { return SDL_GL_GetProcAddress(name); @@ -60,6 +63,12 @@ void gl_init(int w, int h, int bpp, int depth, int fsaa) hasMT = true; } + if(strstr(exts, "GL_EXT_multi_draw_arrays")) + { + glMultiDrawArrays_ = (PFNGLMULTIDRAWARRAYSEXTPROC)getprocaddress("glMultiDrawArraysEXT"); + hasMDA = true; + } + if(fsaa) glEnable(GL_MULTISAMPLE); inittmus();