From 3c9e4db46e63ab9c31e114189ee185dbfa335c5d Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Tue, 23 Apr 2019 15:03:17 +0200 Subject: [PATCH] major cleanup of projection setting --- basegraph.cpp | 61 ++++++++++++++++++++++----------------- classes.h | 2 +- conformal.cpp | 2 -- floorshapes.cpp | 4 +-- graph.cpp | 14 ++------- hud.cpp | 7 ++--- hyper.h | 7 ++++- hypgraph.cpp | 2 +- polygons.cpp | 32 +++++++------------- renderbuffer.cpp | 4 +++ rogueviz-banachtarski.cpp | 2 -- rogueviz-staircase.cpp | 1 - rogueviz-video.cpp | 2 -- rug.cpp | 10 ++----- shaders.cpp | 1 + 15 files changed, 67 insertions(+), 84 deletions(-) diff --git a/basegraph.cpp b/basegraph.cpp index 71d0b79d..98026997 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -164,27 +164,6 @@ color_t darkena(color_t c, int lev, int a) { void setcameraangle(bool b) { } #else -bool cameraangle_on; - -void setcameraangle(bool b) { - if(cameraangle_on != b) { - cameraangle_on = b; - ld cam = vid.camera_angle * degree; - - GLfloat cc = cos(cam); - GLfloat ss = sin(cam * (b?1:-1)); - - GLfloat yzspin[16] = { - 1, 0, 0, 0, - 0, cc, ss, 0, - 0, -ss, cc, 0, - 0, 0, 0, 1 - }; - - glhr::projection_multiply(glhr::as_glmatrix(yzspin)); - } - } - bool shaderside_projection; void start_projection(int ed, bool perspective) { @@ -216,10 +195,26 @@ glhr::glmatrix model_orientation_gl() { return s; } -void display_data::set_projection(int ed, bool apply_models) { +tuple last_projection; +bool new_projection_needed; + +void display_data::set_all(int ed) { + auto t = this; + auto current_projection = tie(ed, pmodel, t, current_rbuffer); + if(new_projection_needed || last_projection != current_projection) { + last_projection = current_projection; + set_projection(ed); + set_mask(ed); + set_viewport(ed); + new_projection_needed = false; + } + } + +void display_data::set_projection(int ed) { DEBB(DF_GRAPH, (debugfile,"current_display->set_projection\n")); bool pers3 = false; + bool apply_models = !among(pmodel, mdText, mdRug); shaderside_projection = false; glhr::new_shader_projection = glhr::shader_projection::standard; @@ -248,6 +243,7 @@ void display_data::set_projection(int ed, bool apply_models) { } start_projection(ed, shaderside_projection); + if(pmodel == mdRug) return; auto cd = current_display; @@ -326,7 +322,21 @@ void display_data::set_projection(int ed, bool apply_models) { } } - cameraangle_on = false; + if(vid.camera_angle && !among(pmodel, mdText, mdUnchanged, mdRug)) { + ld cam = vid.camera_angle * degree; + + GLfloat cc = cos(cam); + GLfloat ss = sin(cam); + + GLfloat yzspin[16] = { + 1, 0, 0, 0, + 0, cc, ss, 0, + 0, -ss, cc, 0, + 0, 0, 0, 1 + }; + + glhr::projection_multiply(glhr::as_glmatrix(yzspin)); + } } void display_data::set_mask(int ed) { @@ -406,10 +416,7 @@ void setGLProjection(color_t col) { glhr::set_depthtest(false); GLERR("setGLProjection"); - - current_display->set_projection(0, true); - - GLERR("after set_projection"); + reset_projection(); } inline int next_p2 (int a ) diff --git a/classes.h b/classes.h index 08d6633a..83fe2382 100644 --- a/classes.h +++ b/classes.h @@ -261,7 +261,7 @@ enum eModel { mdFisheye, mdJoukowsky, mdJoukowskyInverted, mdRotatedHyperboles, mdSpiral, mdPerspective, mdEquivolume, - mdGUARD, mdUnchanged, mdHyperboloidFlat, mdPolynomial + mdGUARD, mdUnchanged, mdHyperboloidFlat, mdPolynomial, mdText, mdRug }; typedef unsigned long long flagtype; diff --git a/conformal.cpp b/conformal.cpp index b001f803..ccafc45a 100644 --- a/conformal.cpp +++ b/conformal.cpp @@ -520,7 +520,6 @@ namespace conformal { vid.xres = vid.yres = bandfull; glbuf.enable(); current_display->radius = bandhalf; calcparam(); - current_display->set_viewport(0); ld xpos = 0; @@ -610,7 +609,6 @@ namespace conformal { } rbuf.reset(); - current_display->set_viewport(0); if(includeHistory) restoreBack(); diff --git a/floorshapes.cpp b/floorshapes.cpp index bfd82407..d9a32c2e 100644 --- a/floorshapes.cpp +++ b/floorshapes.cpp @@ -820,9 +820,6 @@ void make_floor_textures() { cd->radius = cd->scrsize * vid.scale; floor_textures->enable(); - current_display->set_viewport(0); - current_display->set_projection(0, true); - current_display->set_mask(0); floor_textures->clear(0); // 0xE8E8E8 = 1 // gradient vertices @@ -836,6 +833,7 @@ void make_floor_textures() { gv.emplace_back(-1, +1, 1, 1, 1); glhr::switch_mode(glhr::gmVarColored, glhr::shader_projection::standard); + current_display->set_all(0); glhr::new_projection(); glhr::id_modelview(); glhr::prepare(gv); diff --git a/graph.cpp b/graph.cpp index 088724c7..f036c106 100644 --- a/graph.cpp +++ b/graph.cpp @@ -2657,8 +2657,6 @@ void drawaura() { #endif #if CAP_GL - setcameraangle(true); - float cx[AURA+1][11][5]; double facs[11] = {1, 1.01, 1.02, 1.04, 1.08, 1.70, 1.95, 1.5, 2, 6, 10}; @@ -2717,16 +2715,13 @@ void drawaura() { } } glflush(); - current_display->set_projection(0, false); - setcameraangle(true); + dynamicval p(pmodel, DIM == 2 && pmodel == mdDisk ? mdDisk : mdText); + current_display->set_all(0); glhr::switch_mode(glhr::gmVarColored, glhr::shader_projection::standard); glhr::id_modelview(); glhr::prepare(auravertices); glhr::set_depthtest(false); glDrawArrays(GL_TRIANGLES, 0, isize(auravertices)); - - - setcameraangle(false); #endif } @@ -6336,6 +6331,7 @@ void calcparam() { cd->scrdist_text = cd->scrdist; callhooks(hooks_calcparam); + reset_projection(); } function wrap_drawfullmap = drawfullmap; @@ -6404,15 +6400,11 @@ void gamescreen(int _darken) { if(subscreens::split([=] () { calcparam(); - current_display->set_projection(0, false); - current_display->set_viewport(0); compute_graphical_distance(); gamescreen(_darken); })) { if(racing::on) return; // create the gmatrix - current_display->set_projection(0, false); - current_display->set_viewport(0); View = subscreens::player_displays[0].view_matrix; viewctr = subscreens::player_displays[0].view_center; just_gmatrix = true; diff --git a/hud.cpp b/hud.cpp index 91e1f9fa..b309bcd4 100644 --- a/hud.cpp +++ b/hud.cpp @@ -351,7 +351,6 @@ bool nofps = false; void draw_radar(bool cornermode) { dynamicval g(geometry, gEuclid); initquickqueue(); - current_display->set_projection(0, false); int rad = vid.radarsize; ld cx = cornermode ? rad+2 : vid.xres-rad-2; @@ -373,6 +372,7 @@ void draw_radar(bool cornermode) { queueline(atscreenpos(cx+rad * r.h[0], cy - rad * r.h[2]/3 + rad * r.h[1]*2/3, 0)*C0, atscreenpos(cx+rad*r.h[0], cy - rad*r.h[2]/3, 0)*C0, r.line, -1); } + dynamicval pm(pmodel, mdText); quickqueue(); for(auto& r: radarpoints) @@ -395,8 +395,7 @@ void drawStats() { dynamicval va(vid.alpha, 1); dynamicval vs(vid.scale, 1); - calcparam(); - current_display->set_projection(0, false); + calcparam(); bool cornermode = (vid.xres > vid.yres * 85/100 && vid.yres > vid.xres * 85/100); @@ -535,7 +534,7 @@ void drawStats() { } } } - calcparam(); current_display->set_projection(0, false); + calcparam(); string s0; if(racing::on) { diff --git a/hyper.h b/hyper.h index 0343e686..c4db7ab3 100644 --- a/hyper.h +++ b/hyper.h @@ -1182,8 +1182,10 @@ struct display_data { bool in_anaglyph(); void set_viewport(int ed); - void set_projection(int ed, bool apply_models); + void set_projection(int ed); void set_mask(int ed); + + void set_all(int ed); }; extern display_data default_display; @@ -5022,5 +5024,8 @@ const int TEXTURE_STEP_3D=8; void set_euland3(cell *c, int co0, int co1, int alt, int hash); extern bool first_cell_to_draw; +extern int current_rbuffer; +extern bool new_projection_needed; +inline void reset_projection() { new_projection_needed = true; } } diff --git a/hypgraph.cpp b/hypgraph.cpp index 3a6db4c1..e422ca4c 100644 --- a/hypgraph.cpp +++ b/hypgraph.cpp @@ -654,7 +654,7 @@ void applymodel(hyperpoint H, hyperpoint& ret) { } } - case mdGUARD: break; + case mdGUARD: case mdRug: case mdText: break; } ghcheck(ret,H_orig); diff --git a/polygons.cpp b/polygons.cpp index 4949ba7f..2f8a9503 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -184,8 +184,9 @@ void glflush() { if(isize(text_vertices)) { // printf("%08X | %d texts, %d vertices\n", text_color, texts_merged, isize(text_vertices)); - if(!svg::in) current_display->set_projection(0, false); glhr::be_textured(); + dynamicval pm(pmodel, mdText); + if(!svg::in) current_display->set_all(0); glBindTexture(GL_TEXTURE_2D, text_texture); glhr::color2(text_color); glhr::set_depthtest(false); @@ -606,7 +607,6 @@ void dqi_poly::gldraw() { #if CAP_TEXTURE glhr::be_textured(); glBindTexture(GL_TEXTURE_2D, tinf->texture_id); - current_display->set_projection(0, true); glhr::vertices_texture(v, tinf->tvertices, offset, offset_texture); ioffset = 0; #endif @@ -629,7 +629,7 @@ void dqi_poly::gldraw() { for(int ed = current_display->stereo_active() ? -1 : 0; ed<2; ed+=2) { if(global_projection && global_projection != ed) continue; - if(ed) current_display->set_projection(ed, true), current_display->set_viewport(ed); + current_display->set_all(ed); bool draw = color; if(shaderside_projection) { @@ -691,8 +691,6 @@ void dqi_poly::gldraw() { glDrawArrays(GL_LINE_STRIP, offset, cnt); } } - - if(current_display->stereo_active()) current_display->set_projection(0, true), current_display->set_viewport(0), current_display->set_mask(0); } #endif @@ -1301,7 +1299,7 @@ int curvestart = 0; bool keep_curvedata = false; void queuereset(eModel m, PPR prio) { - queueaction(prio, [m] () { pmodel = m; current_display->set_projection(0, true); }); + queueaction(prio, [m] () { pmodel = m; }); } void dqi_line::draw() { @@ -1350,9 +1348,9 @@ void sortquickqueue() { } void quickqueue() { - spherespecial = 0; current_display->set_projection(0, true); + spherespecial = 0; + reset_projection(); current_display->set_all(0); int siz = isize(ptds); - setcameraangle(false); for(int i=0; idraw(); ptds.clear(); } @@ -1451,7 +1449,7 @@ void draw_backside() { } spherespecial = sphereflipped() ? 1 : -1; - current_display->set_projection(0, true); + reset_projection(); if(pmodel == mdRotatedHyperboles) { for(auto& ptd: ptds) @@ -1471,7 +1469,7 @@ void draw_backside() { spherespecial *= -1; spherephase = 1; - current_display->set_projection(0, true); + reset_projection(); } extern bool lshiftclick, lctrlclick; @@ -1499,7 +1497,6 @@ void draw_main() { glClear(GL_DEPTH_BUFFER_BIT); glhr::be_nontextured(); spherephase = p; - current_display->set_projection(0, true); for(auto& ptd: ptds) ptd->draw(); if(elliptic) { spherephase = p - 2; @@ -1524,9 +1521,9 @@ void draw_main() { void drawqueue() { callhooks(hook_drawqueue); + reset_projection(); current_display->set_all(0); + // reset_projection() is not sufficient here, because we need to know shaderside_projection - setcameraangle(true); - #if CAP_GL if(vid.usingGL) glClear(GL_STENCIL_BUFFER_BIT); @@ -1573,8 +1570,7 @@ void drawqueue() { spherespecial = 0; spherephase = 0; - current_display->set_projection(0, true); - setcameraangle(true); + reset_projection(); if(model_needs_depth() && current_display->stereo_active()) { global_projection = -1; @@ -1587,11 +1583,6 @@ void drawqueue() { draw_main(); } -#if CAP_GL - if(vid.usingGL) - current_display->set_projection(0, true), current_display->set_mask(0), current_display->set_viewport(0); -#endif - #if CAP_SDL if(vid.stereo_mode == sAnaglyph && !vid.usingGL) { int qty = s->w * s->h; @@ -1614,7 +1605,6 @@ void drawqueue() { } #endif - setcameraangle(false); if(!keep_curvedata) { curvedata.clear(); curvestart = 0; } diff --git a/renderbuffer.cpp b/renderbuffer.cpp index 93407d0d..7acf5fd4 100644 --- a/renderbuffer.cpp +++ b/renderbuffer.cpp @@ -126,11 +126,14 @@ SDL_Surface *renderbuffer::render() { } #endif +int current_rbuffer = -1; + void renderbuffer::enable() { #if CAP_GL if(FramebufferName) { GLERR("prebind"); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); + current_rbuffer = FramebufferName; GLERR("bind"); vid.usingGL = true; return; @@ -210,6 +213,7 @@ resetbuffer::resetbuffer() { void resetbuffer::reset() { #if CAP_GL glBindFramebuffer(GL_FRAMEBUFFER, drawFboId); + current_rbuffer = drawFboId; #endif #if CAP_SDL s = sreset; diff --git a/rogueviz-banachtarski.cpp b/rogueviz-banachtarski.cpp index 328be2ec..23c7f6d2 100644 --- a/rogueviz-banachtarski.cpp +++ b/rogueviz-banachtarski.cpp @@ -301,7 +301,6 @@ void bantar_frame() { cci.second.c->wparam = cci.second.gid; calcparam(); - current_display->set_projection(0, true); vector> subscr[4]; @@ -407,7 +406,6 @@ void bantar_frame() { vid.xposition = (!(i&2)) ? xdst : -xdst; vid.yposition = (!(i&1)) ? ydst : -ydst; calcparam(); - current_display->set_projection(0, true); drawqueue(); } diff --git a/rogueviz-staircase.cpp b/rogueviz-staircase.cpp index d981fdde..76fcb4e0 100644 --- a/rogueviz-staircase.cpp +++ b/rogueviz-staircase.cpp @@ -118,7 +118,6 @@ bool on; void make_staircase() { // vid.stereo_mode = current_display->sODS; - // current_display->set_viewport(0); rug::no_fog = true; printf("scurvature = %lf progress = %lf strafe=%lf,%lf\n", scurvature, progress, strafex, strafey); diff --git a/rogueviz-video.cpp b/rogueviz-video.cpp index 04eb485a..bca99daf 100644 --- a/rogueviz-video.cpp +++ b/rogueviz-video.cpp @@ -194,7 +194,6 @@ void staircase_video(int from, int num, int step) { dynamicval vy(vid.yres, TSIZE); dynamicval vxc(current_display->xcenter, TSIZE/2); dynamicval vyc(current_display->ycenter, TSIZE/2); - current_display->set_viewport(0); printf("draw scene\n"); rug::drawRugScene(); @@ -224,7 +223,6 @@ void bantar_record() { rbuf.enable(); vid.xres = vid.yres = TSIZE; - current_display->set_viewport(0); banachtarski::bantar_frame(); IMAGESAVE(rbuf.render(), ("bantar/" + its05(fr) + IMAGEEXT).c_str()); diff --git a/rug.cpp b/rug.cpp index f669eaef..5779050d 100644 --- a/rug.cpp +++ b/rug.cpp @@ -1284,9 +1284,6 @@ void prepareTexture() { conformal::configure(); glbuf->enable(); - current_display->set_viewport(0); - current_display->set_projection(0, true); - current_display->set_mask(0); glbuf->clear(0); ptds.clear(); @@ -1349,11 +1346,11 @@ void drawRugScene() { use_precompute = false; ct_array.clear(); cp_array.clear(); - current_display->set_mask(ed), current_display->set_viewport(ed); if(ed == 1 && vid.stereo_mode == sAnaglyph) glClear(GL_DEPTH_BUFFER_BIT); - start_projection(ed, true); + dynamicval p(pmodel, mdRug); + current_display->set_all(ed); eyewidth_translate(ed); if(vid.stereo_mode == sODS) { @@ -1418,9 +1415,6 @@ void drawRugScene() { glEnable(GL_BLEND); - current_display->set_mask(0), current_display->set_viewport(0); - current_display->set_projection(0, true); - if(rug_failure) { rug::close(); rug::clear_model(); diff --git a/shaders.cpp b/shaders.cpp index 497347ae..18cc4e7c 100644 --- a/shaders.cpp +++ b/shaders.cpp @@ -363,6 +363,7 @@ void be_textured(shader_projection sp) { switch_mode(gmTextured, sp); } void switch_mode(eMode m, shader_projection sp) { if(m == mode && current_shader_projection == sp) return; + reset_projection(); GLERR("pre_switch_mode"); #if CAP_SHADER programs[m][int(sp)]->enable();