levellines feature

This commit is contained in:
Zeno Rogue 2019-11-03 13:36:06 +01:00
parent d1d8ee07a1
commit 3725b06d0b
7 changed files with 106 additions and 15 deletions

View File

@ -1504,6 +1504,28 @@ EX void add_edit_wall_quality(char c) {
});
}
EX void edit_levellines(char c) {
if(levellines)
dialog::addSelItem(XLAT("level lines"), fts(levellines), c);
else
dialog::addBoolItem(XLAT("level lines"), false, c);
dialog::add_action([] {
dialog::editNumber(levellines, 0, 100, 0.5, 0, XLAT("level lines"),
XLAT(
"This feature superimposes level lines on the rendered screen. These lines depend on the Z coordinate. In 3D hyperbolic the Z coordinate is taken from the Klein model. "
"Level lines can be used to observe the curvature: circles correspond to positive curvature, while hyperbolas correspond to negative. See e.g. the Hypersian Rug mode.")
);
dialog::reaction = ray::reset_raycaster;
dialog::extra_options = [] {
dialog::addBoolItem(XLAT("disable textures"), disable_texture, 'T');
dialog::add_action([] { ray::reset_raycaster(); disable_texture = !disable_texture; });
dialog::addItem(XLAT("disable level lines"), 'D');
dialog::add_action([] { ray::reset_raycaster(); levellines = 0; popScreen(); });
};
dialog::bound_low(0);
});
}
EX void show3D() {
cmode = sm::SIDE | sm::MAYDARK;
gamescreen(0);
@ -1590,7 +1612,9 @@ EX void show3D() {
dialog::addItem(XLAT("configure raycasting"), 'A');
dialog::add_action_push(ray::configure);
}
edit_levellines('L');
if(WDIM == 3 || (GDIM == 3 && euclid)) {
dialog::addSelItem(XLAT("radar range"), fts(vid.radarrange), 'R');
dialog::add_action([] () {
@ -2362,6 +2386,15 @@ EX int read_config_args() {
else if(argis("-msmoff")) {
PHASEFROM(2); memory_saving_mode = false;
}
else if(argis("-levellines")) {
PHASEFROM(2); shift_arg_formula(levellines);
}
else if(argis("-level-notexture")) {
PHASEFROM(2); disable_texture = true;
}
else if(argis("-level-texture")) {
PHASEFROM(2); disable_texture = false;
}
else if(argis("-msens")) {
PHASEFROM(2); shift_arg_formula(mouseaim_sensitivity);
}
@ -2496,6 +2529,7 @@ EX unordered_map<string, ld&> params = {
{"mgrid", vid.multiplier_grid},
{"mring", vid.multiplier_ring},
{"collignon", vid.collignon_parameter},
{"levellines", levellines},
#endif
};

View File

@ -1743,6 +1743,7 @@ EX void sortquickqueue() {
}
EX void quickqueue() {
current_display->next_shader_flags = 0;
spherespecial = 0;
reset_projection(); current_display->set_all(0);
int siz = isize(ptds);
@ -1932,6 +1933,7 @@ EX hookset<bool()> *hooks_vr_draw_all;
EX void drawqueue() {
callhooks(hook_drawqueue);
current_display->next_shader_flags = 0;
reset_projection();
// reset_projection() is not sufficient here, because we need to know shaderside_projection

View File

@ -1078,6 +1078,7 @@ EX void make_floor_textures() {
dynamicval<bool> a3(vid.always3, false);
dynamicval<bool> hq(inHighQual, true);
dynamicval<int> hd(darken, 0);
dynamicval<ld> hll(levellines, 0);
dynamicval<ld> gd(vid.depth, 1);
dynamicval<ld> gc(vid.camera, 1);
dynamicval<geometry_information*> dcgip(cgip, cgip);

View File

@ -253,7 +253,7 @@ struct GLprogram {
GLuint vertShader, fragShader;
GLint uFog, uFogColor, uColor, tTexture, tInvExpTable, uMV, uProjection, uAlpha, uFogBase, uPP;
GLint uPRECX, uPRECY, uPRECZ, uIndexSL, uIterations;
GLint uPRECX, uPRECY, uPRECZ, uIndexSL, uIterations, uLevelLines;
flagtype shader_flags;
@ -318,7 +318,9 @@ GLprogram::GLprogram(string vsh, string fsh) {
uPRECX = -1;
uIterations = -1;
uAlpha = -1;
return;
uLevelLines = -1;
uFogColor = -1;
return;
}
_vsh = vsh; _fsh = fsh;
@ -375,6 +377,7 @@ GLprogram::GLprogram(string vsh, string fsh) {
uPRECZ = glGetUniformLocation(_program, "PRECZ");
uIndexSL = glGetUniformLocation(_program, "uIndexSL");
uIterations = glGetUniformLocation(_program, "uIterations");
uLevelLines = glGetUniformLocation(_program, "uLevelLines");
}
GLprogram::~GLprogram() {
@ -581,11 +584,14 @@ EX void full_enable(shared_ptr<GLprogram> p) {
EX void fog_max(ld fogmax, color_t fogcolor) {
WITHSHADER({
glUniform1f(current_glprogram->uFog, 1 / fogmax);
if(current_glprogram->uFog != -1)
glUniform1f(current_glprogram->uFog, 1 / fogmax);
GLfloat cols[4];
for(int i=0; i<4; i++) cols[i] = part(fogcolor, 3-i) / 255.0;
glUniform4f(current_glprogram->uFogColor, cols[0], cols[1], cols[2], cols[3]);
if(current_glprogram->uFogColor != -1) {
GLfloat cols[4];
for(int i=0; i<4; i++) cols[i] = part(fogcolor, 3-i) / 255.0;
glUniform4f(current_glprogram->uFogColor, cols[0], cols[1], cols[2], cols[3]);
}
}, {
glFogf(GL_FOG_END, fogmax);
})

View File

@ -123,7 +123,7 @@ void enable_raycaster() {
last_geometry = geometry;
deg = S7; if(prod) deg += 2;
if(!our_raycaster) {
bool use_reflect = reflect_val && !nil;
bool use_reflect = reflect_val && !nil && !levellines;
string vsh =
"attribute vec4 aPosition;\n"
@ -556,14 +556,18 @@ void enable_raycaster() {
fmain +=
" vec2 u = cid + vec2(float(which) / float(uLength), 0);\n"
" vec4 col = texture2D(tWallcolor, u);\n"
" if(col[3] > 0.0) {\n"
" if(col[3] > 0.0) {\n";
if(!(levellines && disable_texture)) fmain +=
" vec2 inface = map_texture(position, which);\n"
" vec3 tmap = texture2D(tTextureMap, u).rgb;\n"
" if(tmap.z == 0.) col.xyz *= min(1., (1.-inface.x)/ tmap.x);\n"
" else {\n"
" vec2 inface2 = tmap.xy + tmap.z * inface;\n"
" col.xyz *= texture2D(tTexture, inface2).rgb;\n"
" }\n"
" }\n";
fmain +=
" float d = max(1. - go / uLinearSightRange, uExpStart * exp(-go / uExpDecay));\n"
" col.xyz = col.xyz * d + uFogColor.xyz * (1.-d);\n";
@ -594,6 +598,14 @@ void enable_raycaster() {
" float z = at0.z * go;\n"
" float w = 1.;\n";
if(levellines) {
if(hyperbolic)
fmain += "gl_FragColor.xyz *= 0.5 + 0.5 * cos(z/cosh(go) * uLevelLines * 2. * PI);\n";
else
fmain += "gl_FragColor.xyz *= 0.5 + 0.5 * cos(z * uLevelLines * 2. * PI);\n";
fsh += "uniform float uLevelLines;\n";
}
fmain +=
" gl_FragDepth = (-float("+fts(vnear+vfar)+")+w*float("+fts(2*vnear*vfar)+")/z)/float("+fts(vnear-vfar)+");\n"
" gl_FragDepth = (gl_FragDepth + 1.) / 2.;\n";
@ -866,6 +878,8 @@ EX void cast() {
glUniform4fv(o->uWallX, isize(wallx), &wallx[0][0]);
glUniform4fv(o->uWallY, isize(wally), &wally[0][0]);
if(o->uLevelLines != -1)
glUniform1f(o->uLevelLines, levellines);
if(o->uBinaryWidth != -1)
glUniform1f(o->uBinaryWidth, vid.binary_width/2 * (nih?1:log(2)));
if(o->uPLevel != -1)
@ -980,6 +994,8 @@ EX void configure() {
});
};
});
edit_levellines('L');
dialog::addBack();
dialog::display();

View File

@ -1365,6 +1365,9 @@ EX void drawRugScene() {
current_display->set_all(ed);
eyewidth_translate(ed);
if(glhr::current_glprogram->uLevelLines != -1)
glUniform1f(glhr::current_glprogram->uLevelLines, levellines);
if(vid.stereo_mode == sODS) {
glhr::projection_multiply(glhr::ortho(M_PI, M_PI, 100)); // 2*M_PI));
}
@ -1406,6 +1409,7 @@ EX void drawRugScene() {
100,
darkena(backcolor, 0, 0xFF)
);
GLERR("fog_max");
for(int t=0; t<isize(triangles); t++)
drawTriangle(triangles[t]);
@ -1417,13 +1421,16 @@ EX void drawRugScene() {
glDrawArrays(GL_TRIANGLES, 0, isize(ct_array));
}
GLERR("rugz");
if(isize(cp_array) > 0) {
glhr::prepare(cp_array);
glLineWidth(lwidth);
glDrawArrays(GL_LINES, 0, isize(cp_array));
}
GLERR("rugt");
current_display->set_mask(0);
GLERR("afterrug");
}
glEnable(GL_BLEND);
@ -1885,6 +1892,7 @@ EX void show() {
dialog::addSelItem(XLAT("anti-crossing"), fts(anticusp_factor), 'A');
dialog::addBoolItem(XLAT("3D monsters/walls on the surface"), spatial_rug, 'S');
dialog::add_action([] () { spatial_rug = !spatial_rug; });
edit_levellines('L');
#if CAP_SURFACE
if(hyperbolic) {

View File

@ -8,10 +8,14 @@
#include "hyper.h"
namespace hr {
EX ld levellines;
EX bool disable_texture;
#if HDR
constexpr flagtype GF_TEXTURE = 1;
constexpr flagtype GF_VARCOLOR = 2;
constexpr flagtype GF_LIGHTFOG = 4;
constexpr flagtype GF_LEVELS = 8;
constexpr flagtype GF_which = 15;
@ -56,14 +60,19 @@ shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) {
vsh += "attribute mediump vec4 aPosition;\n";
varying += "varying mediump vec4 vColor;\n";
fmain += "gl_FragColor = vColor;\n";
if(shader_flags & GF_TEXTURE) {
vsh += "attribute mediump vec2 aTexture;\n";
varying += "varying mediump vec2 vTexCoord;\n";
fsh += "uniform mediump sampler2D tTexture;\n";
vmain += "vTexCoord = aTexture;\n",
fmain += "gl_FragColor = vColor * texture2D(tTexture, vTexCoord);\n";
fmain += "gl_FragColor *= texture2D(tTexture, vTexCoord);\n";
}
if(shader_flags & GF_LEVELS) {
fsh += "uniform mediump float uLevelLines;\n";
varying += "varying mediump vec4 vPos;\n";
fmain += "gl_FragColor.rgb *= 0.5 + 0.5 * cos(vPos.z/vPos.w * uLevelLines * 2. * PI);\n";
}
else fmain += "gl_FragColor = vColor;\n";
if(shader_flags & GF_VARCOLOR) {
vsh += "attribute mediump vec4 aColor;\n";
@ -77,7 +86,7 @@ shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) {
if(shader_flags & GF_LIGHTFOG) {
vmain += "float fogx = clamp(1.0 + aPosition.z * uFog, 0.0, 1.0); vColor = vColor * fogx + uFogColor * (1.0-fogx);\n";
vsh += "uniform mediump float uFog;\n";
vsh += "uniform mediump float uFogColor;\n";
vsh += "uniform mediump vec4 uFogColor;\n";
}
string coordinator;
@ -90,12 +99,18 @@ shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) {
bool skip_t = false;
if(pmodel == mdPixel) {
vmain += "vec4 pos = aPosition; pos[3] = 1.0; gl_Position = uP * uMV * pos;\n";
vmain += "vec4 pos = aPosition; pos[3] = 1.0;\n";
vmain += "pos = uMV * pos;\n";
if(shader_flags & GF_LEVELS) vmain += "vPos = pos;\n";
vmain += "gl_Position = uP * pos;\n";
skip_t = true;
shader_flags |= SF_PIXELS | SF_DIRECT;
}
else if(pmodel == mdManual) {
vmain += "gl_Position = uP * uMV * aPosition;\n";
vmain += "vec4 pos = uMV * aPosition;\n";
if(shader_flags & GF_LEVELS)
vmain += "vPos = pos;\n";
vmain += "gl_Position = uP * pos;\n";
skip_t = true;
shader_flags |= SF_DIRECT;
}
@ -228,6 +243,7 @@ shared_ptr<glhr::GLprogram> write_shader(flagtype shader_flags) {
"uniform mediump float uFogBase;\n"
"uniform mediump vec4 uFogColor;\n";
}
if(shader_flags & GF_LEVELS) vmain += "vPos = t;\n";
if(treset) vmain += "t[3] = 1.0;\n";
vmain += "gl_Position = uP * t;\n";
}
@ -269,6 +285,10 @@ void display_data::set_projection(int ed) {
unsigned id;
id = geometry;
id <<= 6; id |= pmodel;
if(levellines && pmodel != mdPixel) {
shader_flags |= GF_LEVELS;
if(disable_texture) shader_flags &=~ GF_TEXTURE;
}
id <<= 6; id |= shader_flags;
id <<= 6; id |= spherephase;
id <<= 1; if(vid.consider_shader_projection) id |= 1;
@ -397,6 +417,10 @@ void display_data::set_projection(int ed) {
if(selected->uAlpha != -1)
glhr::set_ualpha(vid.alpha);
if(selected->uLevelLines != -1) {
glUniform1f(selected->uLevelLines, levellines);
}
if(selected->shader_flags & SF_ORIENT)
glhr::projection_multiply(model_orientation_gl());