diff --git a/basegraph.cpp b/basegraph.cpp index 56343fa9..e2cef035 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -199,6 +199,13 @@ void eyewidth_translate(int ed) { if(ed) glhr::projection_multiply(glhr::translate(-ed * current_display->eyewidth(), 0, 0)); } +glhr::glmatrix model_orientation_gl() { + glhr::glmatrix s = glhr::id; + for(int a=0; a<2; a++) + conformal::apply_orientation(s[a][1], s[a][0]); + return s; + } + void display_data::set_projection(int ed, bool apply_models) { DEBB(DF_GRAPH, (debugfile,"current_display->set_projection\n")); @@ -207,8 +214,10 @@ void display_data::set_projection(int ed, bool apply_models) { if(vid.consider_shader_projection) { if(pmodel == mdDisk && !spherespecial && !(hyperbolic && vid.alpha <= -1)) shaderside_projection = true; - if(pmodel == mdBand && hyperbolic && apply_models && !inHighQual) + if(pmodel == mdBand && hyperbolic && apply_models) shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::band; + if(pmodel == mdHalfplane && hyperbolic && apply_models) + shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::halfplane; } start_projection(ed, shaderside_projection); @@ -249,11 +258,16 @@ void display_data::set_projection(int ed, bool apply_models) { if(glhr::new_shader_projection == glhr::shader_projection::band) { glhr::projection_multiply(glhr::scale(2 / M_PI, 2 / M_PI,1)); - glhr::glmatrix s = glhr::id; - for(int a=0; a<2; a++) - conformal::apply_orientation(s[a][1], s[a][0]); - glhr::projection_multiply(s); + glhr::projection_multiply(model_orientation_gl()); } + + if(glhr::new_shader_projection == glhr::shader_projection::halfplane) { + glhr::projection_multiply(glhr::translate(0, 1, 0)); + glhr::projection_multiply(glhr::scale(-1, 1, 1)); + glhr::projection_multiply(glhr::scale(conformal::halfplane_scale, conformal::halfplane_scale, 1)); + glhr::projection_multiply(model_orientation_gl()); + glhr::projection_multiply(glhr::translate(0, 0.5, 0)); + } } cameraangle_on = false; diff --git a/hyper.h b/hyper.h index 9609e88c..852174de 100644 --- a/hyper.h +++ b/hyper.h @@ -3647,7 +3647,7 @@ namespace glhr { const GLfloat* as_array() const { return a[0]; } }; - enum class shader_projection { standard, band, MAX }; + enum class shader_projection { standard, band, halfplane, MAX }; extern shader_projection new_shader_projection; diff --git a/polygons.cpp b/polygons.cpp index 82f4c3f6..caf8d022 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -475,7 +475,7 @@ void glapplymatrix(const transmatrix& V) { } mat[12] = 0; mat[13] = 0; - mat[14] = (glhr::current_shader_projection == glhr::shader_projection::standard) ? GLfloat(vid.alpha) : 0; + mat[14] = (glhr::current_shader_projection != glhr::shader_projection::band) ? GLfloat(vid.alpha) : 0; mat[15] = 1; if(vid.stretch != 1) mat[1] *= vid.stretch, mat[5] *= vid.stretch, mat[9] *= vid.stretch, mat[13] *= vid.stretch; diff --git a/shaders.cpp b/shaders.cpp index 03cc4cdb..651185f4 100644 --- a/shaders.cpp +++ b/shaders.cpp @@ -488,6 +488,7 @@ void init() { bool mps = j != 0; bool band = (sp == shader_projection::band); + bool hp = (sp == shader_projection::halfplane); programs[i][j] = new GLprogram(stringbuilder( @@ -532,16 +533,21 @@ void init() { lfog, "vColor = vColor * clamp(1.0 + aPosition.z * uFog, 0.0, 1.0);", !mps, "gl_Position = uMVP * aPosition;", mps&&!band,"gl_Position = uP * (uMV * aPosition);", - band, "vec4 t = uMV * aPosition;", - - band, "float zlev = zlevel(t);", - band, "t /= zlev;", + + band||hp, "vec4 t = uMV * aPosition;", + band||hp, "float zlev = zlevel(t);", + band||hp, "t /= zlev;", band, "float ty = asinh(t.y);", band, "float tx = asinh(t.x / cosh(ty));", band, "ty = 2.0 * atan(tanh(ty/2.0));", band, "t[0] = tx; t[1] = ty; t[2] = 1.0; t[3] = 1.0;", - band, "gl_Position = uP * t;", + + hp, "t.x /= t.z; t.y /= t.z; t.y = t.y + 1.0; ", + hp, "float rads = t.x * t.x + t.y * t.y; ", + hp, "t.x /= -rads; t.y /= -rads; t.z = 1.0; t[3] = 1.0;", + + band || hp,"gl_Position = uP * t;", 1, "}"), stringbuilder(