From 680dca90c84f064e07d403e7d60c4002e2ad1a9f Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sat, 17 Nov 2018 17:59:57 +0100 Subject: [PATCH] shaderside projection --- basegraph.cpp | 19 ++++--- graph.cpp | 2 +- hud.cpp | 4 +- hyper.h | 11 +++-- polygons.cpp | 32 +++++++----- rogueviz-banachtarski.cpp | 4 +- rug.cpp | 6 +-- shaders.cpp | 101 +++++++++++++++++++++++++++++--------- 8 files changed, 127 insertions(+), 52 deletions(-) diff --git a/basegraph.cpp b/basegraph.cpp index 6664c88d..e3fb935a 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -174,11 +174,11 @@ void setcameraangle(bool b) { } } -bool using_perspective; +bool shaderside_projection; void start_projection(int ed, bool perspective) { glhr::new_projection(); - using_perspective = perspective; + shaderside_projection = perspective; if(ed && stereo::mode == stereo::sLR) { glhr::projection_multiply(glhr::translate(ed, 0, 0)); @@ -192,12 +192,19 @@ void eyewidth_translate(int ed) { if(ed) glhr::projection_multiply(glhr::translate(-ed * stereo::eyewidth(), 0, 0)); } -void stereo::set_projection(int ed) { +void stereo::set_projection(int ed, bool apply_models) { DEBB(DF_GRAPH, (debugfile,"stereo::set_projection\n")); - start_projection(ed, pmodel == mdDisk && !spherespecial && !(hyperbolic && vid.alpha <= -1)); + shaderside_projection = false; + glhr::new_shader_projection = glhr::shader_projection::standard; + if(pmodel == mdDisk && !spherespecial && !(hyperbolic && vid.alpha <= -1)) + shaderside_projection = true; + if(pmodel == mdBand && hyperbolic && apply_models && !inHighQual) + shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::band; + + start_projection(ed, shaderside_projection); - if(!using_perspective) { + if(!shaderside_projection) { glhr::projection_multiply(glhr::ortho(vid.xres/2, -vid.yres/2, abs(stereo::scrdist) + 30000)); if(ed) { glhr::glmatrix m = glhr::id; @@ -308,7 +315,7 @@ void setGLProjection(color_t col) { GLERR("setGLProjection"); - stereo::set_projection(0); + stereo::set_projection(0, true); GLERR("after set_projection"); } diff --git a/graph.cpp b/graph.cpp index 7498d054..f7236ffa 100644 --- a/graph.cpp +++ b/graph.cpp @@ -2407,7 +2407,7 @@ void drawaura() { } } glflush(); - glhr::switch_mode(glhr::gmVarColored); + glhr::switch_mode(glhr::gmVarColored, glhr::shader_projection::standard); glhr::id_modelview(); glhr::prepare(auravertices); glhr::set_depthtest(false); diff --git a/hud.cpp b/hud.cpp index a6cc1b10..4f19b411 100644 --- a/hud.cpp +++ b/hud.cpp @@ -355,7 +355,7 @@ void drawStats() { dynamicval v(vid, vid); vid.alpha = vid.scale = 1; calcparam(); - stereo::set_projection(0); + stereo::set_projection(0, false); if(haveMobileCompass()) { initquickqueue(); @@ -476,7 +476,7 @@ void drawStats() { } } } - calcparam(); stereo::set_projection(0); + calcparam(); stereo::set_projection(0, false); string s0; if(!peace::on) { diff --git a/hyper.h b/hyper.h index d44b5517..01e8a34c 100644 --- a/hyper.h +++ b/hyper.h @@ -3307,7 +3307,7 @@ namespace stereo { bool in_anaglyph(); void set_viewport(int ed); - void set_projection(int ed); + void set_projection(int ed, bool apply_models); void set_mask(int ed); } @@ -3630,10 +3630,15 @@ namespace glhr { const GLfloat* as_array() const { return a[0]; } }; + enum class shader_projection { standard, band, MAX }; + + extern shader_projection new_shader_projection; + void set_depthtest(bool b); glmatrix translate(ld x, ld y, ld z); void color2(color_t color, ld part = 1); - void be_textured(); + void be_nontextured(shader_projection sp = new_shader_projection); + void be_textured(shader_projection sp = new_shader_projection); void set_modelview(const glmatrix& m); hyperpoint gltopoint(const glvertex& t); glvertex pointtogl(const hyperpoint& t); @@ -4010,7 +4015,7 @@ extern ld hexshift; extern bool noshadow, bright, nohelp, dont_face_pc; extern void switchHardcore(); -extern bool using_perspective; +extern bool shaderside_projection; void generateAlts(heptagon *h, int levs = IRREGULAR ? 1 : S3-3, bool link_cdata = true); diff --git a/polygons.cpp b/polygons.cpp index ab665f06..05fbc7af 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -439,6 +439,7 @@ void glflush() { if(isize(text_vertices)) { // printf("%08X | %d texts, %d vertices\n", text_color, texts_merged, isize(text_vertices)); + stereo::set_projection(0, false); glhr::be_textured(); glBindTexture(GL_TEXTURE_2D, text_texture); glhr::color2(text_color); @@ -478,6 +479,10 @@ void glapplymatrix(const transmatrix& V) { mat[15] = 1; if(vid.stretch != 1) mat[1] *= vid.stretch, mat[5] *= vid.stretch, mat[9] *= vid.stretch, mat[13] *= vid.stretch; + + if(conformal::model_has_orientation()) + for(int a=0; a<4; a++) + conformal::apply_orientation(mat[a*4], mat[a*4+1]); glhr::set_modelview(glhr::as_glmatrix(mat)); } @@ -535,10 +540,13 @@ void dqi_poly::gldraw() { } for(int ed = stereo::active() ? -1 : 0; ed<2; ed+=2) { - if(ed) stereo::set_projection(ed), stereo::set_viewport(ed); + if(ed) stereo::set_projection(ed, true), stereo::set_viewport(ed); bool draw = color; - if(using_perspective) glapplymatrix(V); + if(shaderside_projection) { + if(glhr::current_shader_projection == glhr::shader_projection::band && V[2][2] > 1e8) continue; + glapplymatrix(V); + } if(draw) { if(true) { @@ -560,7 +568,7 @@ void dqi_poly::gldraw() { glStencilFunc( GL_NOTEQUAL, 1, 1); GLfloat xx = vid.xres; GLfloat yy = vid.yres; - GLfloat dist = using_perspective ? stereo::scrdist : 0; + GLfloat dist = shaderside_projection ? stereo::scrdist : 0; vector scr = { make_array(-xx, -yy, dist), make_array(+xx, -yy, dist), @@ -571,7 +579,7 @@ void dqi_poly::gldraw() { glhr::id_modelview(); glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, 0, 4); glhr::vertices(v); - if(using_perspective) glapplymatrix(V); + if(shaderside_projection) glapplymatrix(V); } else { glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO); @@ -595,7 +603,7 @@ void dqi_poly::gldraw() { } } - if(stereo::active()) stereo::set_projection(0), stereo::set_viewport(0), stereo::set_mask(0); + if(stereo::active()) stereo::set_projection(0, true), stereo::set_viewport(0), stereo::set_mask(0); } #endif @@ -946,7 +954,7 @@ void dqi_poly::draw() { } */ #if CAP_GL - if(vid.usingGL && using_perspective) { + if(vid.usingGL && shaderside_projection) { glLineWidth(get_width(this)); flags &= ~POLY_INVERSE; gldraw(); @@ -1219,7 +1227,7 @@ int curvestart = 0; bool keep_curvedata = false; void queuereset(eModel m, PPR prio) { - queueaction(prio, [m] () { pmodel = m; stereo::set_projection(0); }); + queueaction(prio, [m] () { pmodel = m; stereo::set_projection(0, true); }); } void dqi_line::draw() { @@ -1266,7 +1274,7 @@ void sortquickqueue() { } void quickqueue() { - spherespecial = 0; stereo::set_projection(0); + spherespecial = 0; stereo::set_projection(0, true); int siz = isize(ptds); setcameraangle(false); for(int i=0; idraw(); @@ -1402,7 +1410,7 @@ void drawqueue() { spherespecial = 0; spherephase = 0; - stereo::set_projection(0); + stereo::set_projection(0, true); for(auto& ptd: ptds) if(ptd->prio == PPR::OUTCIRCLE) ptd->draw(); @@ -1418,7 +1426,7 @@ void drawqueue() { } spherespecial = sphereflipped() ? 1 : -1; - stereo::set_projection(0); + stereo::set_projection(0, true); reverse_side_priorities(); for(int i=ptds.size()-1; i>=0; i--) @@ -1429,7 +1437,7 @@ void drawqueue() { reverse_side_priorities(); spherespecial *= -1; spherephase = 1; - stereo::set_projection(0); + stereo::set_projection(0, true); } for(auto& ptd: ptds) if(ptd->prio != PPR::OUTCIRCLE) { @@ -1440,7 +1448,7 @@ void drawqueue() { #if CAP_GL if(vid.usingGL) - stereo::set_projection(0), stereo::set_mask(0), stereo::set_viewport(0); + stereo::set_projection(0, true), stereo::set_mask(0), stereo::set_viewport(0); #endif #if CAP_SDL diff --git a/rogueviz-banachtarski.cpp b/rogueviz-banachtarski.cpp index 5b772267..98f49307 100644 --- a/rogueviz-banachtarski.cpp +++ b/rogueviz-banachtarski.cpp @@ -301,7 +301,7 @@ void bantar_frame() { cci.second.c->wparam = cci.second.gid; calcparam(); - stereo::set_projection(0); + stereo::set_projection(0, true); vector> subscr[4]; @@ -407,7 +407,7 @@ void bantar_frame() { vid.xposition = (!(i&2)) ? xdst : -xdst; vid.yposition = (!(i&1)) ? ydst : -ydst; calcparam(); - stereo::set_projection(0); + stereo::set_projection(0, true); drawqueue(); } diff --git a/rug.cpp b/rug.cpp index 353b6028..552cf7da 100644 --- a/rug.cpp +++ b/rug.cpp @@ -1235,7 +1235,7 @@ void prepareTexture() { glbuf->enable(); stereo::set_viewport(0); - stereo::set_projection(0); + stereo::set_projection(0, true); stereo::set_mask(0); glbuf->clear(0); @@ -1283,7 +1283,7 @@ void drawRugScene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_BLEND); - glhr::switch_mode(glhr::gmLightFog); + glhr::switch_mode(glhr::gmLightFog, glhr::shader_projection::standard); glhr::set_depthtest(true); glDepthFunc(invert_depth ? GL_GREATER : GL_LESS); @@ -1351,7 +1351,7 @@ void drawRugScene() { glEnable(GL_BLEND); stereo::set_mask(0), stereo::set_viewport(0); - stereo::set_projection(0); + stereo::set_projection(0, true); if(rug_failure) { rug::close(); diff --git a/shaders.cpp b/shaders.cpp index fbb00c2a..2568eaf0 100644 --- a/shaders.cpp +++ b/shaders.cpp @@ -42,7 +42,9 @@ flagtype flags[gmMAX] = { 0, GF_TEXTURE, GF_VARCOLOR, GF_TEXTURE | GF_LIGHTFOG | eMode mode; -void switch_mode(eMode m); +shader_projection current_shader_projection, new_shader_projection; + +void switch_mode(eMode m, shader_projection sp); void display(const glmatrix& m) { for(int i=0; i<4; i++) { @@ -200,7 +202,7 @@ struct GLprogram { GLuint _program; GLuint vertShader, fragShader; - GLint uMVP, uFog, uColor, tTexture; + GLint uMVP, uFog, uColor, tTexture, uMV, uProjection; GLprogram(string vsh, string fsh) { _program = glCreateProgram(); @@ -247,6 +249,8 @@ struct GLprogram { // glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); ?? // glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); ?? + uMV = glGetUniformLocation(_program, "uMV"); + uProjection = glGetUniformLocation(_program, "uP"); uMVP = glGetUniformLocation(_program, "uMVP"); uFog = glGetUniformLocation(_program, "uFog"); uColor = glGetUniformLocation(_program, "uColor"); @@ -274,7 +278,7 @@ struct GLprogram { }; -GLprogram *programs[gmMAX]; +GLprogram *programs[gmMAX][int(shader_projection::MAX)]; string stringbuilder() { return ""; } @@ -287,7 +291,7 @@ template string stringbuilder(bool i, const string& s, T... t) { else return stringbuilder(t...); } -glmatrix current_matrix; +glmatrix current_matrix, current_modelview, current_projection; bool operator == (const glmatrix& m1, const glmatrix& m2) { for(int i=0; i<4; i++) @@ -296,18 +300,35 @@ bool operator == (const glmatrix& m1, const glmatrix& m2) { return true; } +bool operator != (const glmatrix& m1, const glmatrix& m2) { + return !(m1 == m2); + } + 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()); + if(current_shader_projection != shader_projection::standard) { + if(modelview != current_modelview) { + current_modelview = modelview; + glUniformMatrix4fv(current->uMV, 1, 0, modelview.as_array()); + } + if(projection != current_projection) { + current_projection = projection; + glUniformMatrix4fv(current->uProjection, 1, 0, projection.as_array()); + } + } + else { + 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(current_shader_projection != shader_projection::standard) { set_modelview(id); return; } #if MINIMIZE_GL_CALLS if(projection == current_matrix) return; current_matrix = projection; @@ -334,14 +355,14 @@ void colorClear(color_t color) { glClearColor(c[3] / 255.0, c[2] / 255.0, c[1]/255.0, c[0] / 255.0); } -void be_nontextured() { switch_mode(gmColored); } -void be_textured() { switch_mode(gmTextured); } +void be_nontextured(shader_projection sp) { switch_mode(gmColored, sp); } +void be_textured(shader_projection sp) { switch_mode(gmTextured, sp); } -void switch_mode(eMode m) { - if(m == mode) return; +void switch_mode(eMode m, shader_projection sp) { + if(m == mode && current_shader_projection == sp) return; GLERR("pre_switch_mode"); #if CAP_SHADER - programs[m]->enable(); + programs[m][int(sp)]->enable(); GLERR("after_enable"); #endif flagtype newflags = flags[m] &~ flags[mode]; @@ -421,9 +442,12 @@ void switch_mode(eMode m) { #endif } mode = m; + current_shader_projection = sp; GLERR("after_switch_mode"); current_vertices = NULL; current_matrix[0][0] = -1e8; // invalid + current_modelview[0][0] = -1e8; + current_projection[0][0] = -1e8; id_modelview(); } @@ -452,14 +476,20 @@ void init() { #if CAP_SHADER projection = id; - for(int i=0; i<4; i++) { + for(int i=0; ienable(); + switch_mode(gmColored, shader_projection::standard); + programs[gmColored][0]->enable(); #endif #if !CAP_SHADER - switch_mode(gmColored); + switch_mode(gmColored, 0); #endif #if CAP_SHADER