faster graphics with MINIMIZE_GL_CALLS

This commit is contained in:
Zeno Rogue 2018-09-04 23:27:27 +02:00
parent 5680ef3788
commit 35353fe70e
7 changed files with 133 additions and 29 deletions

View File

@ -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();

View File

@ -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];

View File

@ -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

View File

@ -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];

View File

@ -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<glvertex> triangle_vertices;
vector<glvertex> line_vertices;
#endif
int shapes_merged;
/* vector<glhr::textured_vertex> 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<glvertex> v2(cnt+1);
for(int i=0; i<cnt+1; i++) v2[i] = glhr::pointtogl( V * glhr::gltopoint( v[offset+i-1] ) );
if(color) for(int i=0; i<cnt; i++) triangle_vertices.push_back(v2[0]), triangle_vertices.push_back(v2[i]), triangle_vertices.push_back(v2[i+1]);
for(int i=1; i<cnt; i++) line_vertices.push_back(v2[i]), line_vertices.push_back(v2[i+1]);
}
else {
vector<glvertex> v2(cnt);
for(int i=0; i<cnt; i++) v2[i] = glhr::pointtogl( V * glhr::gltopoint( v[offset+i] ) );
if(color) for(int i=2; i<cnt-1; i++) triangle_vertices.push_back(v2[0]), triangle_vertices.push_back(v2[i-1]), triangle_vertices.push_back(v2[i]);
for(int i=1; i<cnt; i++) line_vertices.push_back(v2[i-1]), line_vertices.push_back(v2[i]);
}
return;
}
else glflush();
#endif
if(tinf) {
#if CAP_TEXTURE
glhr::be_textured();
@ -413,17 +483,7 @@ void dqi_poly::gldraw() {
if(using_perspective) glapplymatrix(V);
if(draw) {
if((flags & POLY_VCONVEX) && MINIMIZE_GL_CALLS) {
glhr::vertices(v);
glhr::color2(color);
glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, offset, cnt);
}
else if((flags & POLY_CCONVEX) && MINIMIZE_GL_CALLS) {
glhr::vertices(v);
glhr::color2(color);
glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, offset-1, cnt+1);
}
else {
if(true) {
glEnable(GL_STENCIL_TEST);
glColorMask( GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE );
@ -1108,11 +1168,22 @@ void sort_drawqueue() {
int siz = isize(ptds);
for(int i = 0; i<siz; i++) {
int pd = ptds[i]->prio - PPR::ZERO;
#if MINIMIZE_GL_CALLS
unordered_map<color_t, vector<unique_ptr<drawqueueitem>>> 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)

View File

@ -287,14 +287,31 @@ template<class... T> 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();
}

View File

@ -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