diff --git a/basegraph.cpp b/basegraph.cpp index bea99ccc..7fe46831 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -222,8 +222,13 @@ void display_data::set_projection(int ed, bool apply_models) { shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::standardH3; if(DIM == 3 && euclid) shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::standardR3; - if(DIM == 3 && sphere) - shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::standardS3; + if(DIM == 3 && sphere) { + shaderside_projection = true; + if(spherephase == 0) glhr::new_shader_projection = glhr::shader_projection::standardS30; + if(spherephase == 1) glhr::new_shader_projection = glhr::shader_projection::standardS31; + if(spherephase == 2) glhr::new_shader_projection = glhr::shader_projection::standardS32; + if(spherephase == 3) glhr::new_shader_projection = glhr::shader_projection::standardS33; + } } start_projection(ed, shaderside_projection); diff --git a/hyper.h b/hyper.h index ed1f0fd3..e5a98f99 100644 --- a/hyper.h +++ b/hyper.h @@ -3801,7 +3801,9 @@ namespace glhr { const GLfloat* as_array() const { return a[0]; } }; - enum class shader_projection { standard, band, halfplane, standardH3, standardR3, standardS3, MAX }; + enum class shader_projection { standard, band, halfplane, standardH3, standardR3, + standardS30, standardS31, standardS32, standardS33, MAX + }; extern shader_projection new_shader_projection; diff --git a/polygons.cpp b/polygons.cpp index fb597a97..2d1f4c01 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -1396,6 +1396,41 @@ void reverse_side_priorities() { PPR::LAKEWALL, PPR::INLAKEWALL, PPR::BELOWBOTTOM}) reverse_priority(p); } + +// on the sphere, parts on the back are drawn first +void draw_backside() { + if(pmodel == mdHyperboloid && hyperbolic) { + dynamicval dv (pmodel, mdHyperboloidFlat); + for(auto& ptd: ptds) + if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE)) + ptd->draw(); + } + + spherespecial = sphereflipped() ? 1 : -1; + current_display->set_projection(0, true); + + if(pmodel == mdRotatedHyperboles) { + for(auto& ptd: ptds) + if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE)) + ptd->draw(); + glflush(); + } + else { + reverse_side_priorities(); + for(int i=ptds.size()-1; i>=0; i--) + if(!among(ptds[i]->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE)) + ptds[i]->draw_back(); + + glflush(); + reverse_side_priorities(); + } + + spherespecial *= -1; + spherephase = 1; + current_display->set_projection(0, true); + } + +extern bool lshiftclick, lctrlclick; void drawqueue() { callhooks(hook_drawqueue); @@ -1445,48 +1480,44 @@ void drawqueue() { current_display->set_projection(0, true); setcameraangle(true); - for(auto& ptd: ptds) if(ptd->prio == PPR::OUTCIRCLE) - ptd->draw(); - - // on the sphere, parts on the back are drawn first - if(two_sided_model()) { - - if(pmodel == mdHyperboloid && hyperbolic) { - dynamicval dv (pmodel, mdHyperboloidFlat); - for(auto& ptd: ptds) - if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE)) - ptd->draw(); + if(sphere && DIM == 3) { + for(int p: {0, 1, 2, 3}) { + if(p == 1 || p == 3) { + #ifdef GL_ES + glClearDepthf(1.0f); + #else + glClearDepth(1.0f); + #endif + glDepthFunc(GL_LEQUAL); + } + else { + #ifdef GL_ES + glClearDepthf(0.0f); + #else + glClearDepth(0.0f); + #endif + glDepthFunc(GL_GEQUAL); + } + glClear(GL_DEPTH_BUFFER_BIT); + glhr::be_nontextured(); + spherephase = p; + current_display->set_projection(0, true); + for(auto& ptd: ptds) ptd->draw(); + // glflush(); } - - spherespecial = sphereflipped() ? 1 : -1; - current_display->set_projection(0, true); - - if(pmodel == mdRotatedHyperboles) { - for(auto& ptd: ptds) - if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE)) - ptd->draw(); - glflush(); - } - else { - reverse_side_priorities(); - for(int i=ptds.size()-1; i>=0; i--) - if(!among(ptds[i]->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE)) - ptds[i]->draw_back(); - - glflush(); - reverse_side_priorities(); - } - - spherespecial *= -1; - spherephase = 1; - current_display->set_projection(0, true); } + else { + for(auto& ptd: ptds) if(ptd->prio == PPR::OUTCIRCLE) + ptd->draw(); + + if(two_sided_model()) draw_backside(); - for(auto& ptd: ptds) if(ptd->prio != PPR::OUTCIRCLE) { - dynamicval ss(spherespecial, among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE) ? 0 : spherespecial); - ptd->draw(); + for(auto& ptd: ptds) if(ptd->prio != PPR::OUTCIRCLE) { + dynamicval ss(spherespecial, among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE) ? 0 : spherespecial); + ptd->draw(); + } + glflush(); } - glflush(); #if CAP_GL if(vid.usingGL) diff --git a/shaders.cpp b/shaders.cpp index d8a5ce0f..48ccd973 100644 --- a/shaders.cpp +++ b/shaders.cpp @@ -493,7 +493,11 @@ void init() { bool hp = (sp == shader_projection::halfplane); bool sh3 = (sp == shader_projection::standardH3); bool sr3 = (sp == shader_projection::standardR3); - bool ss3 = (sp == shader_projection::standardS3); + bool ss30 = (sp == shader_projection::standardS30); + bool ss31 = (sp == shader_projection::standardS31); + bool ss32 = (sp == shader_projection::standardS32); + bool ss33 = (sp == shader_projection::standardS33); + bool ss3 = ss30 || ss31 || ss32 || ss33; bool s3 = (sh3 || sr3 || ss3); @@ -561,7 +565,11 @@ void init() { s3, "vec4 t = uMV * aPosition;", sh3, "vColor.xyz = vColor.xyz * (1.0 - acosh(t[3]) / uFog);", sr3, "vColor.xyz = vColor.xyz * (1.0 - sqrt(t[0]*t[0] + t[1]*t[1] + t[2]*t[2]) / 7.);", - ss3, "vColor.xyz = vColor.xyz * (1.0 - acos(t[3]) / 1.6);", + + ss30, "vColor.xyz = vColor.xyz * (acos(t[3]) / 6.3); t = -t; ", + ss31, "vColor.xyz = vColor.xyz * (acos(t[3]) / 6.3); t.xyz = -t.xyz; ", + ss32, "vColor.xyz = vColor.xyz * (1.0 - acos(t[3]) / 6.3); t.w = -t.w; ", + ss33, "vColor.xyz = vColor.xyz * (1.0 - acos(t[3]) / 6.3); ", sh3 || sr3,"t[3] = 1.0;", band || hp || s3,"gl_Position = uP * t;",