3d:: shader acceleration for 3D ball and 3D halfspace

This commit is contained in:
Zeno Rogue 2019-03-20 19:53:59 +01:00
parent fbefc50775
commit bc3e7f2e95
4 changed files with 68 additions and 26 deletions

View File

@ -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; a<DIM; a++)
conformal::apply_orientation(s[a][1], s[a][0]);
if(DIM == 3) for(int a=0; a<DIM; a++)
conformal::apply_orientation_yz(s[a][2], s[a][1]);
return s;
}
@ -214,22 +216,27 @@ void display_data::set_projection(int ed, bool apply_models) {
DEBB(DF_GRAPH, (debugfile,"current_display->set_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));

View File

@ -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;

View File

@ -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));
}

View File

@ -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(