diff --git a/basegraph.cpp b/basegraph.cpp index 067acc84..ce7868ee 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -901,6 +901,7 @@ void drawCircle(int x, int y, int size, color_t color) { if(size < 0) size = -size; #if CAP_GL if(vid.usingGL) { + glflush(); glhr::be_nontextured(); glhr::id_modelview(); glcoords.clear(); diff --git a/control.cpp b/control.cpp index dad030a9..56da91cb 100644 --- a/control.cpp +++ b/control.cpp @@ -508,12 +508,6 @@ void mainloopiter() { if(cwt.mirrored) playerV = playerV * Mirror; } -#if ISWEB - if(playermoved && vid.sspeed > -4.99 && !outoffocus) { - centerpc((ticks - lastt) / 1000.0 * exp(vid.sspeed)); - } - if(!outoffocus) drawscreen(); -#else if(timetowait > 0) SDL_Delay(timetowait); else { @@ -521,8 +515,10 @@ void mainloopiter() { if(cmode & sm::CENTER) { if(playermoved && vid.sspeed > -4.99 && !outoffocus) centerpc((ticks - lastt) / 1000.0 * exp(vid.sspeed)); +#if CAP_SDLJOY if(panjoyx || panjoyy) checkpanjoy((ticks - lastt) / 1000.0); +#endif } tortoise::updateVals(ticks - lastt); frames++; @@ -531,7 +527,6 @@ void mainloopiter() { } lastt = ticks; } -#endif Uint8 *keystate = SDL_GetKeyState(NULL); rightclick = keystate[SDLK_RCTRL]; diff --git a/graph.cpp b/graph.cpp index 3f43aadd..5d73e927 100644 --- a/graph.cpp +++ b/graph.cpp @@ -2352,6 +2352,7 @@ void drawaura() { ); } } + glflush(); glhr::switch_mode(glhr::gmVarColored); glhr::id_modelview(); glhr::prepare(auravertices); @@ -5788,6 +5789,7 @@ void drawscreen() { // SDL_UnlockSurface(s); + glflush(); DEBT("swapbuffers"); #if CAP_SDL #if CAP_GL diff --git a/hyper.h b/hyper.h index 75a19cbd..141a5ddf 100644 --- a/hyper.h +++ b/hyper.h @@ -2538,6 +2538,7 @@ struct drawqueueitem { virtual void draw_pre() {} virtual ~drawqueueitem() {} void draw_darker(); + virtual color_t outline_group() = 0; }; struct dqi_poly : drawqueueitem { @@ -2551,6 +2552,7 @@ struct dqi_poly : drawqueueitem { void draw(); void gldraw(); void draw_back(); + virtual color_t outline_group() { return outline; } }; struct dqi_line : drawqueueitem { @@ -2559,6 +2561,7 @@ struct dqi_line : drawqueueitem { double width; void draw(); void draw_back(); + virtual color_t outline_group() { return color; } }; struct dqi_string : drawqueueitem { @@ -2566,11 +2569,13 @@ struct dqi_string : drawqueueitem { int x, y, shift, size, frame; int align; void draw(); + virtual color_t outline_group() { return 1; } }; struct dqi_circle : drawqueueitem { int x, y, size; void draw(); + virtual color_t outline_group() { return 2; } }; struct dqi_boundary_circle : dqi_circle { @@ -2582,6 +2587,7 @@ struct dqi_action : drawqueueitem { reaction_t action; dqi_action(const reaction_t& a) : action(a) {} void draw() { action(); } + virtual color_t outline_group() { return 2; } }; extern int emeraldtable[100][7]; diff --git a/polygons.cpp b/polygons.cpp index 4ce795fc..693e5c3e 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -354,6 +354,58 @@ void drawTexturedTriangle(SDL_Surface *s, int *px, int *py, glvertex *tv, color_ #endif #if CAP_GL + +void glapplymatrix(const transmatrix& V); + +#if MINIMIZE_GL_CALLS +color_t triangle_color, line_color, text_color; +vector triangle_vertices; +vector line_vertices; +#endif + +int shapes_merged; + +/* vector text_vertices; +int texts_merged; */ + +void glflush() { + #if MINIMIZE_GL_CALLS + if(isize(triangle_vertices)) { + // printf("%08X %08X | %d shapes, %d/%d vertices\n", triangle_color, line_color, shapes_merged, isize(triangle_vertices), isize(line_vertices)); + if(triangle_color) { + glhr::be_nontextured(); + glapplymatrix(Id); + glhr::current_vertices = NULL; + glhr::vertices(triangle_vertices); + glhr::color2(triangle_color); + glDrawArrays(GL_TRIANGLES, 0, isize(triangle_vertices)); + } + triangle_vertices.clear(); + } + if(isize(line_vertices)) { + if(line_color) { + glhr::be_nontextured(); + glapplymatrix(Id); + glhr::current_vertices = NULL; + glhr::vertices(line_vertices); + glhr::color2(line_color); + glDrawArrays(GL_LINES, 0, isize(line_vertices)); + } + line_vertices.clear(); + } + shapes_merged = 0; + #endif +/* if(isize(text_vertices)) { + printf("%08X | %d texts, %d vertices\n", text_color, isize(text_vertices)); + glhr::color2(text_color); + glhr::set_depthtest(false); + glhr::set_modelview(glhr::translate(x-ed*shift-vid.xcenter,y-vid.ycenter, stereo::scrdist_text)); + glBindTexture(GL_TEXTURE_2D, f.textures[tabid]); + + texts_merged = 0; + } */ + } + void glapplymatrix(const transmatrix& V) { GLfloat mat[16]; int id = 0; @@ -372,17 +424,35 @@ void glapplymatrix(const transmatrix& V) { glhr::set_modelview(glhr::as_glmatrix(mat)); } -#ifndef MINIMIZE_GL_CALLS -#ifdef EMSCRIPTEN -#define MINIMIZE_GL_CALLS 1 -#else -#define MINIMIZE_GL_CALLS 0 -#endif -#endif - void dqi_poly::gldraw() { auto& v = *tab; +#if MINIMIZE_GL_CALLS + if(stereo::active() == 0 && !tinf && (color == 0 || ((flags & (POLY_VCONVEX | POLY_CCONVEX)) && !(flags & POLY_INVERSE)))) { + if(color != triangle_color || outline != line_color) { + glflush(); + triangle_color = color; + line_color = outline; + } + shapes_merged++; + + if((flags & POLY_CCONVEX) && !(flags & POLY_VCONVEX)) { + vector v2(cnt+1); + for(int i=0; i v2(cnt); + for(int i=0; iprio - PPR::ZERO; + #if MINIMIZE_GL_CALLS + unordered_map>> subqueue; + for(auto& p: ptds) subqueue[p->outline_group()].push_back(move(p)); + ptds.clear(); + for(auto& p: subqueue) for(auto& r: p.second) ptds.push_back(move(r)); + subqueue.clear(); + for(auto& p: ptds) subqueue[p->color].push_back(move(p)); + ptds.clear(); + for(auto& p: subqueue) for(auto& r: p.second) ptds.push_back(move(r)); + #endif + + for(auto& p: ptds) { + int pd = p->prio - PPR::ZERO; if(pd < 0 || pd >= PMAX) { printf("Illegal priority %d\n", pd); - ptds[i]->prio = PPR(rand() % int(PPR::MAX)); + p->prio = PPR(rand() % int(PPR::MAX)); } qp[pd]++; } @@ -1199,6 +1270,7 @@ void drawqueue() { reverse_side_priorities(); for(int i=ptds.size()-1; i>=0; i--) ptds[i]->draw_back(); + glflush(); reverse_side_priorities(); spherespecial *= -1; spherephase = 1; @@ -1206,6 +1278,7 @@ void drawqueue() { } for(auto& ptd: ptds) ptd->draw(); + glflush(); #if CAP_GL if(vid.usingGL) diff --git a/shaders.cpp b/shaders.cpp index 5f0b68ad..fbb00c2a 100644 --- a/shaders.cpp +++ b/shaders.cpp @@ -287,14 +287,31 @@ template string stringbuilder(bool i, const string& s, T... t) { else return stringbuilder(t...); } +glmatrix current_matrix; + +bool operator == (const glmatrix& m1, const glmatrix& m2) { + for(int i=0; i<4; i++) + for(int j=0; j<4; j++) + if(m1[i][j] != m2[i][j]) return false; + return true; + } + void set_modelview(const glmatrix& modelview) { glmatrix mvp = modelview * projection; + #if MINIMIZE_GL_CALLS + if(mvp == current_matrix) return; + current_matrix = mvp; + #endif glUniformMatrix4fv(current->uMVP, 1, 0, mvp.as_array()); // glmatrix nm = modelview; // glUniformMatrix3fv(current->uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, nm[0]); } void id_modelview() { + #if MINIMIZE_GL_CALLS + if(projection == current_matrix) return; + current_matrix = projection; + #endif glUniformMatrix4fv(current->uMVP, 1, 0, projection.as_array()); } @@ -406,6 +423,7 @@ void switch_mode(eMode m) { mode = m; GLERR("after_switch_mode"); current_vertices = NULL; + current_matrix[0][0] = -1e8; // invalid id_modelview(); } diff --git a/sysconfig.h b/sysconfig.h index 30833d1d..9993f1be 100644 --- a/sysconfig.h +++ b/sysconfig.h @@ -416,3 +416,12 @@ union SDL_Event; #if ISWINDOWS #undef hyper // avoid "hyper" typedef in <_mingw.h> #endif + +#ifndef MINIMIZE_GL_CALLS +#ifdef EMSCRIPTEN +#define MINIMIZE_GL_CALLS 1 +#else +#define MINIMIZE_GL_CALLS 0 +#endif +#endif +