From 78fc8e04b0cd141d39533e74f1fd5b9202e0cc91 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Tue, 4 Sep 2018 23:27:51 +0200 Subject: [PATCH] faster text with MINIMIZE_GL_CALLS --- basegraph.cpp | 169 +++++++++++++++++++++++++++----------------------- nofont.cpp | 1 + polygons.cpp | 37 ++++++++--- rogueviz.cpp | 2 +- 4 files changed, 121 insertions(+), 88 deletions(-) diff --git a/basegraph.cpp b/basegraph.cpp index ce7868ee..e8fdb970 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -323,69 +323,67 @@ inline int next_p2 (int a ) #if CAP_GLFONT +#define CHARS (128+NUMEXTRA) + struct glfont_t { - GLuint * textures; // Holds The Texture Id's + GLuint texture; // Holds The Texture Id //GLuint list_base; // Holds The First Display List ID - int widths[128+NUMEXTRA]; - int heights[128+NUMEXTRA]; - float tx[128+NUMEXTRA]; - float ty[128+NUMEXTRA]; + int widths[CHARS]; + int heights[CHARS]; + float tx0[CHARS], tx1[CHARS], ty0[CHARS], ty1[CHARS]; }; glfont_t *glfont[256]; +#if CAP_TABFONT +typedef int texturepixel; +#else +typedef Uint16 texturepixel; +#endif + +#define FONTTEXTURESIZE 2048 + +int curx = 0, cury = 0, theight = 0; +texturepixel fontdata[FONTTEXTURESIZE][FONTTEXTURESIZE]; + void sdltogl(SDL_Surface *txt, glfont_t& f, int ch) { #if CAP_TABFONT + if(ch < 32) return; int otwidth, otheight, tpix[3000], tpixindex = 0; loadCompressedChar(otwidth, otheight, tpix); #else + if(!txt) return; int otwidth = txt->w; int otheight = txt->h; #endif - int twidth = next_p2( otwidth ); - int theight = next_p2( otheight ); - + if(otwidth+curx > FONTTEXTURESIZE) curx = 0, cury += theight, theight = 0; + + theight = max(theight, otheight); + + for(int j=0; j expanded_data(twidth * theight); + (i>=otwidth || j>=otheight) ? 0 : tpix[tpixindex++]; #else - std::vector expanded_data(twidth * theight); -#endif - - for(int j=0; j =otwidth || j>=otheight) ? 0 : tpix[tpixindex++]; -#else - expanded_data[(i+j*twidth)] = - ((i>=txt->w || j>=txt->h) ? 0 : ((qpixel(txt, i, j)>>24)&0xFF) * 0x100) | 0x00FF; + ((i>=txt->w || j>=txt->h) ? 0 : ((qpixel(txt, i, j)>>24)&0xFF) * 0x100) | 0x00FF; #endif } f.widths[ch] = otwidth; f.heights[ch] = otheight; - glBindTexture( GL_TEXTURE_2D, f.textures[ch]); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, twidth, theight, 0, -#if CAP_TABFONT - GL_RGBA, GL_UNSIGNED_BYTE, -#else - GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, -#endif - expanded_data.data() ); - - float x=(float)otwidth / (float)twidth; - float y=(float)otheight / (float)theight; - f.tx[ch] = x; - f.ty[ch] = y; + f.tx0[ch] = (float) curx / (float) FONTTEXTURESIZE; + f.tx1[ch] = (float) (curx+otwidth) / (float) FONTTEXTURESIZE; + f.ty0[ch] = (float) cury; + f.ty1[ch] = (float) (cury+otheight); + curx += otwidth; } void init_glfont(int size) { if(glfont[size]) return; DEBB(DF_INIT, (debugfile,"init GL font: %d\n", size)); - + #if !CAP_TABFONT loadfont(size); if(!font[size]) return; @@ -395,11 +393,8 @@ void init_glfont(int size) { glfont_t& f(*(glfont[size])); - f.textures = new GLuint[128+NUMEXTRA]; //f.list_base = glGenLists(128); - glGenTextures( 128+NUMEXTRA, f.textures ); - if(0) for(int i=0; i<128+NUMEXTRA; i++) - printf("texture %d = %d\n", i, f.textures[i]); + glGenTextures(1, &f.texture ); #if !CAP_TABFONT char str[2]; str[1] = 0; @@ -410,11 +405,9 @@ void init_glfont(int size) { // glListBase(0); -#if CAP_TABFONT - resetTabFont(); -#endif - - for(int ch=1;ch<128+NUMEXTRA;ch++) { + curx = 0, cury = 0, theight = 0; + + for(int ch=1;ch tver(4); +vector tver; + +glhr::textured_vertex charvertex(int x1, int y1, ld tx, ld ty) { + glhr::textured_vertex res; + res.coords[0] = x1; + res.coords[1] = y1; + res.coords[2] = 0; + res.texture[0] = tx; + res.texture[1] = ty; + res.texture[2] = 0; + return res; + } bool gl_print(int x, int y, int shift, int size, const char *s, color_t color, int align) { int gsiz = size; @@ -504,10 +524,6 @@ bool gl_print(int x, int y, int shift, int size, const char *s, color_t color, i glfont_t& f(*glfont[gsiz]); - glhr::be_textured(); - - glhr::color2((color << 8) | 0xFF); - int tsize = 0; for(int i=0; s[i];) { @@ -520,43 +536,42 @@ bool gl_print(int x, int y, int shift, int size, const char *s, color_t color, i bool clicked = (mousex >= x && mousey <= y && mousex <= x+tsize && mousey >= y-ysiz); - glhr::set_depthtest(false); + color_t icolor = (color << 8) | 0xFF; + if(icolor != text_color || f.texture != text_texture || shift != text_shift || shapes_merged) { + glflush(); + text_color = icolor; + text_texture = f.texture; + text_shift = shift; + } + texts_merged++; + + auto& tver = text_vertices; + + glBindTexture(GL_TEXTURE_2D, f.texture); for(int i=0; s[i];) { int tabid = getnext(s,i); - float fx=f.tx[tabid]; - float fy=f.ty[tabid]; int wi = f.widths[tabid] * size/gsiz; int hi = f.heights[tabid] * size/gsiz; GLERR("pre-print"); - - for(int ed = (stereo::active() && shift)?-1:0; ed<2; ed+=2) { - glhr::set_modelview(glhr::translate(x-ed*shift-vid.xcenter,y-vid.ycenter, stereo::scrdist_text)); - stereo::set_mask(ed); - glBindTexture(GL_TEXTURE_2D, f.textures[tabid]); - - tver[0].coords[1] = -hi; - tver[3].coords[1] = -hi; - tver[2].coords[0] = wi; - tver[3].coords[0] = wi; - tver[1].texture[1] = fy; - tver[2].texture[1] = fy; - tver[2].texture[0] = fx; - tver[3].texture[0] = fx; + + glhr::textured_vertex t00 = charvertex(x, y-hi, f.tx0[tabid], f.ty0[tabid]); + glhr::textured_vertex t01 = charvertex(x, y, f.tx0[tabid], f.ty1[tabid]); + glhr::textured_vertex t11 = charvertex(x+wi, y, f.tx1[tabid], f.ty1[tabid]); + glhr::textured_vertex t10 = charvertex(x+wi, y-hi, f.tx1[tabid], f.ty0[tabid]); + + tver.push_back(t00); + tver.push_back(t01); + tver.push_back(t10); + tver.push_back(t10); + tver.push_back(t01); + tver.push_back(t11); - glhr::prepare(tver); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - } - - if(stereo::active() && shift) stereo::set_mask(0); - - GLERR("print"); - - x += wi; + x += wi; } - + return clicked; } diff --git a/nofont.cpp b/nofont.cpp index 1611d78d..9fa313f0 100644 --- a/nofont.cpp +++ b/nofont.cpp @@ -113,6 +113,7 @@ unsigned char fonttable[] = { 255 }; +#undef NUMEXTRA #define NUMEXTRA 7 unsigned char *ftv = fonttable; diff --git a/polygons.cpp b/polygons.cpp index 693e5c3e..c56194d4 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -358,15 +358,18 @@ void drawTexturedTriangle(SDL_Surface *s, int *px, int *py, glvertex *tv, color_ void glapplymatrix(const transmatrix& V); #if MINIMIZE_GL_CALLS -color_t triangle_color, line_color, text_color; +color_t triangle_color, line_color; vector triangle_vertices; vector line_vertices; #endif +color_t text_color; +int text_shift; +GLuint text_texture; +int texts_merged; int shapes_merged; -/* vector text_vertices; -int texts_merged; */ +vector text_vertices; void glflush() { #if MINIMIZE_GL_CALLS @@ -395,15 +398,29 @@ void glflush() { } shapes_merged = 0; #endif -/* if(isize(text_vertices)) { - printf("%08X | %d texts, %d vertices\n", text_color, isize(text_vertices)); + + if(isize(text_vertices)) { + // printf("%08X | %d texts, %d vertices\n", text_color, texts_merged, isize(text_vertices)); + glhr::be_textured(); + glBindTexture(GL_TEXTURE_2D, text_texture); 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]); + for(int ed = (stereo::active() && text_shift)?-1:0; ed<2; ed+=2) { + glhr::set_modelview(glhr::translate(-ed*text_shift-vid.xcenter,-vid.ycenter, stereo::scrdist_text)); + stereo::set_mask(ed); + + glhr::current_vertices = NULL; + glhr::prepare(text_vertices); + glDrawArrays(GL_TRIANGLES, 0, isize(text_vertices)); + + GLERR("print"); + } + if(stereo::active() && text_shift) stereo::set_mask(0); + texts_merged = 0; - } */ + text_vertices.clear(); + } } void glapplymatrix(const transmatrix& V) { @@ -429,7 +446,7 @@ void dqi_poly::gldraw() { #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) { + if(color != triangle_color || outline != line_color || texts_merged) { glflush(); triangle_color = color; line_color = outline; @@ -475,7 +492,7 @@ void dqi_poly::gldraw() { offset = 0; #endif } - + for(int ed = stereo::active() ? -1 : 0; ed<2; ed+=2) { if(ed) stereo::set_projection(ed), stereo::set_viewport(ed); bool draw = color; diff --git a/rogueviz.cpp b/rogueviz.cpp index 0989af2e..e03588a7 100644 --- a/rogueviz.cpp +++ b/rogueviz.cpp @@ -1233,7 +1233,7 @@ bool drawVertex(const transmatrix &V, cell *c, shmup::monster *m) { if(doshow && !behindsphere(V2)) { auto info = vd.info; if(info) queueaction(PPR::MONSTER_HEAD, [info] () { svg::link = *info; }); - queuestr(V2, (svg::in ? .28 : .2) * crossf / hcrossf, vd.name, backcolor ? 0x000000 : 0xFFFF00, svg::in ? 0 : 1); + queuestr(V2, (svg::in ? .28 : .2) * crossf / hcrossf, vd.name, backcolor ? 0x000000 : 0xFFFF00, (svg::in || ISWEB) ? 0 : 1); if(info) queueaction(PPR::MONSTER_HEAD, [info] () { svg::link = ""; }); } }