mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 17:10:36 +00:00
improved the quality of 3D models from conformal menu
This commit is contained in:
parent
74cc23f1c2
commit
d3c9bfdd92
@ -263,6 +263,10 @@ void stereo::set_viewport(int ed) {
|
||||
glViewport(vid.xres/2, 0, vid.xres/2, vid.yres);
|
||||
}
|
||||
|
||||
bool model_needs_depth() {
|
||||
return pmodel == mdBall || pmodel == mdHyperboloid || pmodel == mdHemisphere;
|
||||
}
|
||||
|
||||
void setGLProjection(int col) {
|
||||
DEBB(DF_GRAPH, (debugfile,"setGLProjection\n"));
|
||||
GLERR("pre_setGLProjection");
|
||||
@ -299,17 +303,17 @@ void setGLProjection(int col) {
|
||||
//glLineWidth(1.0f);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
if(pmodel == mdBall || pmodel == mdHyperboloid || pmodel == mdHemisphere) {
|
||||
if(model_needs_depth()) {
|
||||
#ifdef GL_ES
|
||||
glClearDepthf(1.0f);
|
||||
#else
|
||||
glClearDepth(1.0f);
|
||||
#endif
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glhr::set_depthtest(true);
|
||||
}
|
||||
else
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glhr::set_depthtest(false);
|
||||
|
||||
GLERR("setGLProjection");
|
||||
|
||||
@ -523,6 +527,8 @@ bool gl_print(int x, int y, int shift, int size, const char *s, int color, int a
|
||||
int ysiz = f.heights[32] * size / gsiz;
|
||||
|
||||
bool clicked = (mousex >= x && mousey <= y && mousex <= x+tsize && mousey >= y-ysiz);
|
||||
|
||||
glhr::set_depthtest(false);
|
||||
|
||||
for(int i=0; s[i];) {
|
||||
|
||||
@ -917,6 +923,7 @@ void drawCircle(int x, int y, int size, int color) {
|
||||
glcoords.push_back(make_array<GLfloat>(x + size * sin(rr), y + size * cos(rr), stereo::scrdist));
|
||||
}
|
||||
glhr::vertices(glcoords);
|
||||
glhr::set_depthtest(false);
|
||||
glDrawArrays(GL_LINE_LOOP, 0, pts);
|
||||
return;
|
||||
}
|
||||
|
23
config.cpp
23
config.cpp
@ -337,6 +337,7 @@ void initConfig() {
|
||||
addsaver(stereo::anaglyph_eyewidth, "eyewidth-anaglyph", 0.1);
|
||||
addsaver(stereo::fov, "field-of-vision", 90);
|
||||
addsaverenum(stereo::mode, "stereo-mode");
|
||||
addsaver(vid.euclid_to_sphere, "euclid to sphere projection", 1.5);
|
||||
|
||||
#if CAP_SHMUP
|
||||
shmup::initConfig();
|
||||
@ -1130,6 +1131,17 @@ void showStereo() {
|
||||
};
|
||||
}
|
||||
|
||||
void config_camera_rotation() {
|
||||
dialog::editNumber(vid.ballangle, 0, 90, 5, 0, XLAT("camera rotation in 3D models"),
|
||||
"Rotate the camera in 3D models (ball model, hyperboloid, and hemisphere). "
|
||||
"Note that hyperboloid and hemisphere models are also available in the "
|
||||
"Hypersian Rug surfaces menu, but they are rendered differently there -- "
|
||||
"they are rendered by making a flat picture first, then mapping it to a surface. "
|
||||
"This makes the output better in some ways, but 3D effects are lost. "
|
||||
"Hypersian Rug model also allows more camera freedom."
|
||||
);
|
||||
}
|
||||
|
||||
void show3D() {
|
||||
cmode = sm::SIDE | sm::A3 | sm::MAYDARK;
|
||||
gamescreen(0);
|
||||
@ -1158,7 +1170,7 @@ void show3D() {
|
||||
dialog::addBreak(50);
|
||||
dialog::addBoolItem(XLAT("ball model"), pmodel == mdBall, 'B');
|
||||
dialog::addBoolItem(XLAT("hyperboloid model"), pmodel == mdHyperboloid, 'M');
|
||||
dialog::addSelItem(XLAT("camera rotation in ball model"), fts3(vid.ballangle), 'b');
|
||||
dialog::addSelItem(XLAT("camera rotation in 3D models"), fts3(vid.ballangle), 'b');
|
||||
dialog::addSelItem(XLAT("projection in ball model"), fts3(vid.ballproj), 'x');
|
||||
|
||||
if(sphere)
|
||||
@ -1181,10 +1193,8 @@ void show3D() {
|
||||
dialog::handleNavigation(sym, uni);
|
||||
|
||||
if(uni == 'n')
|
||||
cmode &= sm::A3,
|
||||
dialog::editNumber(geom3::highdetail, 0, 5, .5, 7, XLAT("High detail range"), "");
|
||||
else if(uni == 'm')
|
||||
cmode &= sm::A3,
|
||||
dialog::editNumber(geom3::middetail, 0, 5, .5, 7, XLAT("Mid detail range"), "");
|
||||
else if(uni == 'c')
|
||||
tc_camera = ticks,
|
||||
@ -1209,22 +1219,17 @@ void show3D() {
|
||||
pushScreen(showStereo);
|
||||
|
||||
else if(uni == 'y')
|
||||
cmode &= sm::A3,
|
||||
dialog::editNumber(vid.yshift, 0, 1, .1, 0, XLAT("Y shift"),
|
||||
"Don't center on the player character."
|
||||
);
|
||||
else if(uni == 's')
|
||||
cmode &= sm::A3,
|
||||
dialog::editNumber(vid.camera_angle, -180, 180, 5, 0, XLAT("camera rotation"),
|
||||
"Rotate the camera. Can be used to obtain a first person perspective, "
|
||||
"or third person perspective when combined with Y shift."
|
||||
);
|
||||
else if(uni == 'b')
|
||||
cmode &= sm::A3,
|
||||
dialog::editNumber(vid.ballangle, 0, 90, 5, 0, XLAT("camera rotation in ball model"),
|
||||
"Rotate the camera in ball/hyperboloid model.");
|
||||
config_camera_rotation();
|
||||
else if(uni == 'x')
|
||||
cmode &= sm::A3,
|
||||
dialog::editNumber(vid.ballproj, 0, 100, .1, 0, XLAT("projection in ball model"),
|
||||
"This parameter affects the ball model the same way as the projection parameter affects the disk model.");
|
||||
else if(uni == 'i')
|
||||
|
@ -537,6 +537,7 @@ namespace conformal {
|
||||
{ "right", "up", "left", "down" },
|
||||
{ "right", "up", "left", "down" },
|
||||
{ "right", "up", "left", "down" },
|
||||
{ "right", "up", "left", "down" },
|
||||
{ "right", "up", "left", "down" }
|
||||
};
|
||||
|
||||
@ -577,7 +578,7 @@ namespace conformal {
|
||||
dialog::addBoolItem("Switch", false, '6');
|
||||
}
|
||||
|
||||
if(pmodel == 4) {
|
||||
if(pmodel == mdPolynomial) {
|
||||
dialog::addSelItem(XLAT("coefficient"),
|
||||
fts4(polygonal::coefr[polygonal::coefid]), 'x');
|
||||
dialog::addSelItem(XLAT("coefficient (imaginary)"),
|
||||
@ -585,12 +586,20 @@ namespace conformal {
|
||||
dialog::addSelItem(XLAT("which coefficient"), its(polygonal::coefid), 'n');
|
||||
}
|
||||
|
||||
if(pmodel == 3) {
|
||||
if(pmodel == mdPolygonal) {
|
||||
dialog::addSelItem(XLAT("polygon sides"), its(polygonal::SI), 'x');
|
||||
dialog::addSelItem(XLAT("star factor"), fts(polygonal::STAR), 'y');
|
||||
dialog::addSelItem(XLAT("degree of the approximation"), its(polygonal::deg), 'n');
|
||||
}
|
||||
|
||||
if(pmodel == mdBall || pmodel == mdHyperboloid || pmodel == mdHemisphere) {
|
||||
dialog::addSelItem(XLAT("camera rotation in 3D models"), fts3(vid.ballangle), 'b');
|
||||
}
|
||||
|
||||
if(pmodel == mdHemisphere) {
|
||||
dialog::addSelItem(XLAT("euclid to sphere projection"), fts3(vid.euclid_to_sphere), 'l');
|
||||
}
|
||||
|
||||
if(!bounded && !euclid) dialog::addBoolItem(XLAT("prepare the line animation"), (on), 'e');
|
||||
if(on) dialog::addSelItem(XLAT("animation speed"), fts(lvspeed), 'a');
|
||||
|
||||
@ -633,6 +642,14 @@ namespace conformal {
|
||||
create();
|
||||
}
|
||||
}
|
||||
else if(uni == 'b')
|
||||
config_camera_rotation();
|
||||
else if(uni == 'l') {
|
||||
dialog::editNumber(vid.euclid_to_sphere, 0, 10, .1, 1, XLAT("euclid to sphere projection"),
|
||||
"Stereographic projection to a sphere. Choose the radius of the sphere."
|
||||
);
|
||||
dialog::scaleLog();
|
||||
}
|
||||
else if(uni == 'o')
|
||||
autoband = !autoband;
|
||||
else if(uni == 'm' || uni == 'M') {
|
||||
|
@ -829,7 +829,7 @@ namespace dialog {
|
||||
ne.intval = NULL;
|
||||
ne.positive = false;
|
||||
dialogflags = (cmode & sm::A3);
|
||||
if(cmode & sm::SIDE) dialogflags |= sm::MAYDARK;
|
||||
if(cmode & sm::SIDE) dialogflags |= sm::MAYDARK | sm::SIDE;
|
||||
cmode |= sm::NUMBER;
|
||||
pushScreen(drawNumberDialog);
|
||||
reaction = reaction_t();
|
||||
|
@ -2309,7 +2309,8 @@ void drawaura() {
|
||||
glhr::switch_mode(glhr::gmVarColored);
|
||||
glhr::id_modelview();
|
||||
glhr::prepare(auravertices);
|
||||
glDrawArrays(GL_TRIANGLES, 0, size(auravertices));
|
||||
glhr::set_depthtest(false);
|
||||
glDrawArrays(GL_TRIANGLES, 0, size(auravertices));
|
||||
|
||||
|
||||
setcameraangle(false);
|
||||
|
2
hyper.h
2
hyper.h
@ -647,7 +647,7 @@ extern reaction_t help_delegate;
|
||||
|
||||
struct videopar {
|
||||
ld scale, alpha, sspeed, mspeed, yshift, camera_angle;
|
||||
ld ballangle, ballproj;
|
||||
ld ballangle, ballproj, euclid_to_sphere;
|
||||
int mobilecompasssize;
|
||||
int aurastr, aurasmoothen;
|
||||
|
||||
|
13
hypgraph.cpp
13
hypgraph.cpp
@ -129,20 +129,23 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
||||
|
||||
switch(cgclass) {
|
||||
case gcHyperbolic: {
|
||||
ld zl = zlevel(H);
|
||||
ret = H / H[2];
|
||||
ret[2] = sqrt(1 - sqhypot2(ret));
|
||||
ret = ret * (1 + (zl - 1) * ret[2]);
|
||||
break;
|
||||
}
|
||||
|
||||
case gcEuclid: {
|
||||
// stereographic projection to a sphere
|
||||
auto hd = hdist0(H) / H[2];
|
||||
if(hd == 0) H[2] = -1;
|
||||
auto hd = hdist0(H) / vid.euclid_to_sphere;
|
||||
if(hd == 0) ret = hpxyz(0, 0, -1);
|
||||
else {
|
||||
ld x = 2 * hd / (1 + hd * hd);
|
||||
ld y = x / hd;
|
||||
H = H * x / (hd * H[2]);
|
||||
H[2] = 1 - y;
|
||||
ret = H * x / hd / vid.euclid_to_sphere;
|
||||
ret[2] = (1 - y);
|
||||
ret = ret * (1 + (H[2]-1) * y / vid.euclid_to_sphere);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -153,7 +156,7 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
||||
}
|
||||
}
|
||||
|
||||
ret = rotmatrix(0, 2, ball) * ret;
|
||||
ret = rotmatrix(M_PI/2 + ball, 1, 2) * ret;
|
||||
|
||||
ghcheck(ret, H);
|
||||
return;
|
||||
|
12
polygons.cpp
12
polygons.cpp
@ -250,7 +250,7 @@ void setmatrix(int useV, const transmatrix& V) {
|
||||
GLfloat mat[16] = {
|
||||
1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, -1, 0,
|
||||
0, 0, stereo::scrdist, 1
|
||||
};
|
||||
glhr::set_modelview(glhr::as_glmatrix(mat));
|
||||
@ -299,14 +299,17 @@ void gldraw(int useV, const transmatrix& V, const vector<glvertex>& v, int ps, i
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
glColorMask( GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE );
|
||||
glhr::set_depthtest(false);
|
||||
glStencilOp( GL_INVERT, GL_INVERT, GL_INVERT);
|
||||
glStencilFunc( GL_ALWAYS, 0x1, 0x1 );
|
||||
glhr::color2(0xFFFFFFFF);
|
||||
glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, ps, pq);
|
||||
|
||||
stereo::set_mask(ed);
|
||||
glhr::color2(col);
|
||||
glhr::set_depthtest(model_needs_depth());
|
||||
|
||||
if(flags & POLY_INVERSE) {
|
||||
stereo::set_mask(ed);
|
||||
glhr::color2(col);
|
||||
glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO);
|
||||
glStencilFunc( GL_NOTEQUAL, 1, 1);
|
||||
GLfloat xx = vid.xres;
|
||||
@ -324,8 +327,6 @@ void gldraw(int useV, const transmatrix& V, const vector<glvertex>& v, int ps, i
|
||||
setmatrix(useV, V);
|
||||
}
|
||||
else {
|
||||
stereo::set_mask(ed);
|
||||
glhr::color2(col);
|
||||
glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO);
|
||||
glStencilFunc( GL_EQUAL, 1, 1);
|
||||
glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, ps, pq);
|
||||
@ -337,6 +338,7 @@ void gldraw(int useV, const transmatrix& V, const vector<glvertex>& v, int ps, i
|
||||
|
||||
if(outline) {
|
||||
glhr::color2(outline);
|
||||
glhr::set_depthtest(model_needs_depth());
|
||||
glDrawArrays(GL_LINE_STRIP, ps, pq);
|
||||
}
|
||||
}
|
||||
|
@ -670,4 +670,13 @@ void store_in_buffer(vector<glvertex>& v) {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool current_depthtest;
|
||||
|
||||
void set_depthtest(bool b) {
|
||||
if(b != current_depthtest) {
|
||||
current_depthtest = b;
|
||||
if(b) glEnable(GL_DEPTH_TEST);
|
||||
else glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -483,6 +483,7 @@ void texture_config::drawRawTexture() {
|
||||
}
|
||||
glhr::set_modelview(glhr::translate(0, 0, stereo::scrdist));
|
||||
glhr::prepare(rtver);
|
||||
glhr::set_depthtest(false);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user