new renderer for Solv

This commit is contained in:
Zeno Rogue 2019-07-30 12:56:18 +02:00
parent 8bc15578b4
commit 60778a6896
3 changed files with 98 additions and 51 deletions

View File

@ -275,16 +275,15 @@ void display_data::set_projection(int ed) {
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
// unsigned int loc = glGetUniformLocation(_program, "inv_exp_table");
// glUniform4fv(loc, PRECX*PRECX*PRECZ, &(xbuffer[0]));
auto xbuffer = new glvertex[PRECZ][PRECX][PRECX];
auto xbuffer = new glvertex[PRECZ*PRECY*PRECX];
// for(int y=0; y<PRECX*PRECX*PRECZ; y++) xbuffer[y] = glvertex({inv_exp_table[0][0][y][0]/64, inv_exp_table[0][0][y][1]/64, inv_exp_table[0][0][y][2]/64, 1});
for(int z=0; z<PRECZ; z++)
for(int y=0; y<PRECX; y++)
for(int x=0; x<PRECX; x++)
xbuffer[z][y][x] = glhr::makevertex(inverse_exp_table[z][y][x][0], inverse_exp_table[z][y][x][1], inverse_exp_table[z][y][x][2]);
ld maxd = 0;
for(int z=0; z<PRECZ*PRECY*PRECX; z++) {
auto& t = inverse_exp_table[z];
xbuffer[z] = glhr::makevertex(t[0], t[1], t[2]);
}
println(hlog, "maxd = ", maxd);
glTexImage3D(GL_TEXTURE_3D, 0, 34836 /*GL_RGBA32F*/, PRECX, PRECX, PRECZ, 0, GL_RGBA, GL_FLOAT, xbuffer);
delete[] xbuffer;
@ -297,6 +296,10 @@ void display_data::set_projection(int ed) {
glBindTexture(GL_TEXTURE_3D, invexpid);
glActiveTexture(GL_TEXTURE0 + 0);
glUniform1f(glhr::current->uPRECX, solv::PRECX);
glUniform1f(glhr::current->uPRECY, solv::PRECY);
glUniform1f(glhr::current->uPRECZ, solv::PRECZ);
}
auto cd = current_display;

View File

@ -218,7 +218,7 @@ struct GLprogram {
GLuint _program;
GLuint vertShader, fragShader;
GLint uMVP, uFog, uFogColor, uColor, tTexture, tInvExpTable, uMV, uProjection, uAlpha, uFogBase, uILP;
GLint uMVP, uFog, uFogColor, uColor, tTexture, tInvExpTable, uMV, uProjection, uAlpha, uFogBase, uILP, uPRECX, uPRECY, uPRECZ;
GLprogram(string vsh, string fsh) {
_program = glCreateProgram();
@ -276,6 +276,10 @@ struct GLprogram {
uILP = glGetUniformLocation(_program, "uILP");
tTexture = glGetUniformLocation(_program, "tTexture");
tInvExpTable = glGetUniformLocation(_program, "tInvExpTable");
uPRECX = glGetUniformLocation(_program, "PRECX");
uPRECY = glGetUniformLocation(_program, "PRECY");
uPRECZ = glGetUniformLocation(_program, "PRECZ");
#if DEBUG_GL
printf("uniforms: %d %d %d %d\n", uMVP, uFog, uColor, tTexture);
@ -651,9 +655,13 @@ void init() {
s3, "vec4 t = uMV * aPosition;",
ssol, "t = inverse_exp(uILP * t);",
ssol, "float d = sqrt(t[0] * t[0] + t[1] * t[1] + t[2] * t[2]);",
ssol, "float ad = (d == 0.) ? 0. : (d < 1.) ? min(atanh(d), 10.) : 10.; ",
ssol, "float m = ad / d / 11.; t[0] *= m; t[1] *= m; t[2] *= m; ",
sh3, "float fogs = (uFogBase - acosh(t[3]) / uFog);",
sr3, "float fogs = (uFogBase - sqrt(t[0]*t[0] + t[1]*t[1] + t[2]*t[2]) / uFog);",
ssol, "float fogs = (uFogBase - sqrt(t[0]*t[0] + t[1]*t[1] + t[2]*t[2]) / uFog);",
ssol, "float fogs = (uFogBase - ad / uFog);",
ss30, "float fogs = (uFogBase - (6.284 - acos(t[3])) / uFog); t = -t; ",
ss31, "float fogs = (uFogBase - (6.284 - acos(t[3])) / uFog); t.xyz = -t.xyz; ",

118
sol.cpp
View File

@ -7,26 +7,31 @@ namespace hr {
namespace solv {
const int PRECX = 64;
const int PRECZ = 32;
const ld SXY = 32.;
const ld SZ = 8.;
int PRECX, PRECY, PRECZ;
typedef hyperpoint pt;
typedef array<float, 3> ptlow;
ptlow inverse_exp_table[PRECZ][PRECX][PRECX];
vector<ptlow> inverse_exp_table;
bool table_loaded;
string solfname = "soltable-final.dat";
pt inverse_exp(pt h);
void load_table() {
if(table_loaded) return;
FILE *f = fopen("soltable.dat", "rb");
if(!f) f = fopen("/usr/lib/soltable.dat", "rb");
FILE *f = fopen(solfname.c_str(), "rb");
// if(!f) f = fopen("/usr/lib/soltable.dat", "rb");
if(!f) { addMessage(XLAT("geodesic table missing")); pmodel = mdPerspective; return; }
fread(inverse_exp_table, sizeof(inverse_exp_table), 1, f);
fread(&PRECX, 4, 1, f);
fread(&PRECY, 4, 1, f);
fread(&PRECZ, 4, 1, f);
inverse_exp_table.resize(PRECX * PRECY * PRECZ);
fread(&inverse_exp_table[0], sizeof(ptlow) * PRECX * PRECY * PRECZ, 1, f);
fclose(f);
table_loaded = true;
table_loaded = true;
}
void step2(ld& x, ld &y, ld &z, ld &vx, ld &vy, ld &vz) {
@ -57,7 +62,11 @@ namespace solv {
}
pt direct_exp(pt v, int steps) {
pt at = hpxy(0, 0);
pt at;
at[0] = 0;
at[1] = 0;
at[2] = 0;
at[3] = 1;
v[0] /= steps;
v[1] /= steps;
v[2] /= steps;
@ -88,20 +97,35 @@ namespace solv {
}
return hpxy3(x, y, z);
}
ld x_to_ix(ld u) {
if(u == 0.) return 0.;
ld diag = u*u/2.;
ld x = diag;
ld y = u;
ld z = diag+1.;
x /= (1.+z);
y /= (1.+z);
return 0.5 - atan((0.5-x) / y) / M_PI;
}
pt inverse_exp(pt h) {
load_table();
ld sx = 1, sy = 1;
bool nz = false;
ld ix = h[0] >= 0. ? x_to_ix(h[0]) : -x_to_ix(-h[0]);
ld iy = h[1] >= 0. ? x_to_ix(h[1]) : -x_to_ix(-h[1]);
ld iz = tanh(h[2]);
ld ix = asinh(h[0]) * SXY;
ld iy = asinh(h[1]) * SXY;
ld iz = h[2] * SZ / log(2);
if(ix < 0) ix = -ix, sx = -sx;
if(iy < 0) iy = -iy, sy = -sy;
if(iz < 0) iz = -iz, nz = true, swap(ix, iy);
if(ix < 0.) ix = -ix;
if(iy < 0.) iy = -iy;
if(iz < 0.) { iz = -iz; ld s = ix; ix = iy; iy = s; }
ix *= PRECX-1;
iy *= PRECY-1;
iz *= PRECZ-1;
if(ix >= PRECX-1) ix = PRECX-2;
if(iy >= PRECX-1) iy = PRECX-2;
@ -112,26 +136,23 @@ namespace solv {
int az = iz, bz = az+1;
pt res;
// println(hlog, "inv_table", make_tuple(iz,iy,ix), " = ", make_tuple(inverse_exp_table[z][y][x][0], inverse_exp_table[z][y][x][1], inverse_exp_table[z][y][x][2]));
#define S0(x,y,z) inverse_exp_table[z][y][x][t]
#define S0(x,y,z) inverse_exp_table[(z*PRECY+y)*PRECX+x][t]
#define S1(x,y) (S0(x,y,az) * (bz-iz) + S0(x,y,bz) * (iz-az))
#define S2(x) (S1(x,ay) * (by-iy) + S1(x,by) * (iy-ay))
for(int t=0; t<3; t++)
res[t] = S2(ax) * (bx-ix) + S2(bx) * (ix-ax);
if(nz) swap(res[0], res[1]), res[2] = -res[2];
res[0] *= sx; res[1] *= sy;
res[3] = 1;
#undef S0
#undef S1
#undef S2
// println(hlog, kz(h), " => ", kz(res), " => ", kz(direct_exp(res, 1000)), " [", ix, ",", iy, ",", iz, " | ", sx, "/", sy, "/", nz, "]");
if(h[2] < 0.) { swap(res[0], res[1]); res[2] = -res[2]; }
if(h[0] < 0.) res[0] = -res[0];
if(h[1] < 0.) res[1] = -res[1];
return res;
/* ld r = sqrt(res[0] * res[0] + res[1] * res[1] + res[2] * res[2]);
if(r == 0.) return res;
return res * atanh(r) / r; */
}
transmatrix local_perspective, ilocal_perspective;
@ -344,20 +365,35 @@ namespace solv {
string solshader =
"uniform mediump sampler3D tInvExpTable;"
"uniform mediump mat4 uILP;"
"uniform mediump float PRECX, PRECY, PRECZ;"
"float x_to_ix(float u) {"
" if(u < 1e-6) return 0.;"
" float diag = u*u/2.;"
" float x = diag;"
" float y = u;"
" float z = diag+1.;"
" x /= (1.+z);"
" y /= (1.+z);"
" return 0.5 - atan((0.5-x) / y) / 3.1415926535897932384626433832795;"
" }"
"vec4 inverse_exp(vec4 h) {"
"float ix = asinh(h[0]) * 32.;"
"float iy = asinh(h[1]) * 32.;"
"float iz = h[2] * 8. / log(2.);"
"float ix = h[0] >= 0. ? x_to_ix(h[0]) : x_to_ix(-h[0]);"
"float iy = h[1] >= 0. ? x_to_ix(h[1]) : x_to_ix(-h[1]);"
"float iz = tanh(h[2]);"
"if(ix < 0.) ix = -ix;"
"if(iy < 0.) iy = -iy;"
"if(iz < 0.) { iz = -iz; float s = ix; ix = iy; iy = s; }"
"if(h[2] < 1e-6) { iz = -iz; float s = ix; ix = iy; iy = s; }"
"if(iz < 0.) iz = 0.;"
"vec4 res = texture3D(tInvExpTable, vec3((ix + 0.5) / 64., (iy + 0.5) / 64., (iz + 0.5) / 32.));"
"vec4 res = texture3D(tInvExpTable, vec3(ix*(1.-1./PRECX) + 0.5/PRECX, iy*(1.-1./PRECY) + .5/PRECY, iz*(1.-1./PRECZ) + .5/PRECZ));"
"if(h[2] < 0.) { res.xy = res.yx; res[2] = -res[2]; }"
"if(h[2] < 1e-6) { res.xy = res.yx; res[2] = -res[2]; }"
"if(h[0] < 0.) res[0] = -res[0];"
"if(h[1] < 0.) res[1] = -res[1];"