diff --git a/basegraph.cpp b/basegraph.cpp index d3768b92..ee2a41ff 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -205,8 +205,10 @@ void eyewidth_translate(int ed) { glhr::glmatrix model_orientation_gl() { glhr::glmatrix s = glhr::id; - for(int a=0; a<2; a++) + for(int a=0; aset_projection\n")); bool dim3 = false; + bool pers3 = false; shaderside_projection = false; glhr::new_shader_projection = glhr::shader_projection::standard; if(vid.consider_shader_projection) { if(pmodel == mdDisk && !spherespecial && !(hyperbolic && vid.alpha <= -1) && DIM == 2) shaderside_projection = true; + if(pmodel == mdDisk && !spherespecial && !(hyperbolic && vid.alpha <= -1) && DIM == 3 && apply_models) + shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::ball; if(pmodel == mdBand && hyperbolic && apply_models && DIM == 2) shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::band; if(pmodel == mdHalfplane && hyperbolic && apply_models && DIM == 2) shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::halfplane; + if(pmodel == mdHalfplane && hyperbolic && apply_models && DIM == 3 && vid.alpha == 1) + shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::halfplane3; if(DIM == 3 && hyperbolic && apply_models && pmodel == mdPerspective) - shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::standardH3; + shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::standardH3, pers3 = true; if(DIM == 3 && euclid && apply_models && pmodel == mdPerspective) - shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::standardR3; + shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::standardR3, pers3 = true; if(DIM == 3 && sphere && apply_models && pmodel == mdPerspective) { - shaderside_projection = true; + shaderside_projection = true; pers3 = 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; @@ -264,11 +271,15 @@ void display_data::set_projection(int ed, bool apply_models) { eyewidth_translate(ed); - if(dim3) { + if(pers3) { glhr::projection_multiply(glhr::frustum(current_display->tanfov, current_display->tanfov * cd->ysize / cd->xsize)); glhr::projection_multiply(glhr::scale(1, -1, -1)); current_display->scrdist_text = cd->ysize; } + else if(DIM == 3) { + glhr::projection_multiply(glhr::ortho(cd->xsize/current_display->radius/2, -cd->ysize/current_display->radius/2, 10)); + current_display->scrdist_text = 0; + } else { glhr::projection_multiply(glhr::frustum(cd->xsize / cd->ysize, 1)); GLfloat sc = current_display->radius / (cd->ysize/2.); @@ -280,16 +291,19 @@ void display_data::set_projection(int ed, bool apply_models) { if(ed) glhr::projection_multiply(glhr::translate(vid.ipd * ed/2, 0, 0)); - if(dim3) { + if(pers3) { glhr::fog_max(1/sightranges[geometry]); } + if(glhr::new_shader_projection == glhr::shader_projection::ball) + glhr::set_ualpha(vid.alpha); + if(glhr::new_shader_projection == glhr::shader_projection::band) { glhr::projection_multiply(model_orientation_gl()); glhr::projection_multiply(glhr::scale(2 / M_PI, 2 / M_PI,1)); } - if(glhr::new_shader_projection == glhr::shader_projection::halfplane) { + if(among(glhr::new_shader_projection, glhr::shader_projection::halfplane, glhr::shader_projection::halfplane3)) { glhr::projection_multiply(model_orientation_gl()); glhr::projection_multiply(glhr::translate(0, 1, 0)); glhr::projection_multiply(glhr::scale(-1, 1, 1)); diff --git a/hyper.h b/hyper.h index 797a2d69..3632082d 100644 --- a/hyper.h +++ b/hyper.h @@ -3885,7 +3885,9 @@ namespace glhr { }; enum class shader_projection { standard, band, halfplane, standardH3, standardR3, - standardS30, standardS31, standardS32, standardS33, MAX + standardS30, standardS31, standardS32, standardS33, + ball, halfplane3, + MAX }; extern shader_projection new_shader_projection; diff --git a/polygons.cpp b/polygons.cpp index 7edb458d..a561dfea 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -511,20 +511,32 @@ void glapplymatrix(const transmatrix& V) { return; } - for(int y=0; y<3; y++) { - for(int x=0; x<3; x++) mat[id++] = V[x][y]; - mat[id++] = 0; + if(DIM == 3) { + for(int y=0; y<4; y++) + for(int x=0; x<4; x++) mat[id++] = V[x][y]; + } + else { + for(int y=0; y<3; y++) { + for(int x=0; x<3; x++) mat[id++] = V[x][y]; + mat[id++] = 0; + } + mat[12] = 0; + mat[13] = 0; + if(glhr::current_shader_projection != glhr::shader_projection::band) + mat[14] = GLfloat(vid.alpha); + else + mat[14] = 0; + mat[15] = 1; } - mat[12] = 0; - mat[13] = 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; - if(conformal::model_has_orientation()) + if(conformal::model_has_orientation()) { for(int a=0; a<4; a++) conformal::apply_orientation(mat[a*4], mat[a*4+1]); + if(DIM == 3) for(int a=0; a<4; a++) + conformal::apply_orientation_yz(mat[a*4+2], mat[a*4+2]); + } glhr::set_modelview(glhr::as_glmatrix(mat)); } diff --git a/shaders.cpp b/shaders.cpp index 212b0fb4..76b42dc0 100644 --- a/shaders.cpp +++ b/shaders.cpp @@ -202,7 +202,7 @@ struct GLprogram { GLuint _program; GLuint vertShader, fragShader; - GLint uMVP, uFog, uColor, tTexture, uMV, uProjection; + GLint uMVP, uFog, uColor, tTexture, uMV, uProjection, uAlpha; GLprogram(string vsh, string fsh) { _program = glCreateProgram(); @@ -253,6 +253,7 @@ struct GLprogram { uProjection = glGetUniformLocation(_program, "uP"); uMVP = glGetUniformLocation(_program, "uMVP"); uFog = glGetUniformLocation(_program, "uFog"); + uAlpha = glGetUniformLocation(_program, "uAlpha"); uColor = glGetUniformLocation(_program, "uColor"); tTexture = glGetUniformLocation(_program, "tTexture"); @@ -461,6 +462,10 @@ void fog_max(ld fogmax) { #endif } +void set_ualpha(ld alpha) { + glUniform1f(current->uAlpha, alpha); + } + void init() { #if CAP_GLEW if(!glew) { @@ -490,7 +495,7 @@ void init() { bool mps = j != 0; bool band = (sp == shader_projection::band); - bool hp = (sp == shader_projection::halfplane); + bool hp = among(sp, shader_projection::halfplane, shader_projection::halfplane3); bool sh3 = (sp == shader_projection::standardH3); bool sr3 = (sp == shader_projection::standardR3); bool ss30 = (sp == shader_projection::standardS30); @@ -500,6 +505,9 @@ void init() { bool ss3 = ss30 || ss31 || ss32 || ss33; bool s3 = (sh3 || sr3 || ss3); + bool dim3 = s3 || among(sp, shader_projection::ball, shader_projection::halfplane3); + bool dim2 = !dim3; + bool ball = (sp == shader_projection::ball); programs[i][j] = new GLprogram(stringbuilder( @@ -515,6 +523,7 @@ void init() { mps, "uniform mediump mat4 uMV;", mps, "uniform mediump mat4 uP;", 1, "uniform mediump float uFog;", + ball, "uniform mediump float uAlpha;", !varcol, "uniform mediump vec4 uColor;", 1, "float sinh(float x) {", @@ -547,20 +556,25 @@ void init() { !varcol, "vColor = uColor;", 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);", + ball, "vec4 t = uMV * aPosition; t /= (t[3] + uAlpha); ", + mps&&!(band||hp||s3||ball),"gl_Position = uP * (uMV * aPosition);", band||hp, "vec4 t = uMV * aPosition;", - band||hp, "float zlev = zlevel(t);", - band||hp, "t /= zlev;", + (band||hp) && dim2, "float zlev = zlevel(t);", + (band||hp) && dim2, "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;", - 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;", + hp && dim2, "t.x /= t.z; t.y /= t.z; t.y = t.y + 1.0; ", + hp && dim2, "float rads = t.x * t.x + t.y * t.y; ", + hp && dim2, "t.x /= -rads; t.y /= -rads; t.z = 1.0; t[3] = 1.0;", + + hp && dim3, "t.x /= (1.0+t.w); t.y /= (1.0+t.w); t.z /= (1.0+t.w); t.y = t.y + 1.0; ", + hp && dim3, "float rads = t.x * t.x + t.y * t.y + t.z * t.z; ", + hp && dim3, "t.x /= -rads; t.y /= -rads; t.z /= -rads; t[3] = 1.0;", s3, "vec4 t = uMV * aPosition;", sh3, "vColor.xyz = vColor.xyz * (1.0 - acosh(t[3]) / uFog);", @@ -570,9 +584,9 @@ void init() { ss31, "vColor.xyz = vColor.xyz * (1.0 - (6.284 - acos(t[3])) / uFog); t.xyz = -t.xyz; ", ss32, "vColor.xyz = vColor.xyz * (1.0 - acos(t[3]) / uFog); t.w = -t.w; ", // 2pi ss33, "vColor.xyz = vColor.xyz * (1.0 - acos(t[3]) / uFog); ", - sh3 || sr3,"t[3] = 1.0;", + sh3 || sr3 || ball,"t[3] = 1.0;", - band || hp || s3,"gl_Position = uP * t;", + band || hp || s3 || ball,"gl_Position = uP * t;", 1, "}"), stringbuilder(