mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 17:10:36 +00:00
reworked 3D vision
This commit is contained in:
parent
33ebed2cf3
commit
b3f047ea6a
122
basegraph.cpp
122
basegraph.cpp
@ -10,6 +10,29 @@ int utfsize(char c) {
|
|||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace stereo {
|
||||||
|
eStereo mode;
|
||||||
|
ld ipd;
|
||||||
|
ld lr_eyewidth, anaglyph_eyewidth;
|
||||||
|
ld fov, tanfov;
|
||||||
|
|
||||||
|
GLfloat scrdist, scrdist_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stereo::in_anaglyph() { return stereo::mode == stereo::sAnaglyph; }
|
||||||
|
bool stereo::active() { return stereo::mode != sOFF; }
|
||||||
|
|
||||||
|
ld stereo::eyewidth() {
|
||||||
|
switch(stereo::mode) {
|
||||||
|
case stereo::sAnaglyph:
|
||||||
|
return stereo::anaglyph_eyewidth;
|
||||||
|
case stereo::sLR:
|
||||||
|
return stereo::lr_eyewidth;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool eqs(const char* x, const char* y) {
|
bool eqs(const char* x, const char* y) {
|
||||||
return *y? *x==*y?eqs(x+1,y+1):false:true;
|
return *y? *x==*y?eqs(x+1,y+1):false:true;
|
||||||
}
|
}
|
||||||
@ -152,36 +175,70 @@ void setcameraangle(bool b) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectEyeGL(int ed) {
|
void start_projection(int ed) {
|
||||||
DEBB(DF_GRAPH, (debugfile,"selectEyeGL\n"));
|
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
glTranslatef((vid.xcenter*2.)/vid.xres - 1, 1 - (vid.ycenter*2.)/vid.yres, 0);
|
glTranslatef((vid.xcenter*2.)/vid.xres - 1, 1 - (vid.ycenter*2.)/vid.yres, 0);
|
||||||
|
|
||||||
if(pmodel) {
|
if(ed) {
|
||||||
vid.scrdist = 4 * vid.radius;
|
if(stereo::mode == stereo::sLR) {
|
||||||
|
glTranslatef(ed * (stereo::eyewidth() - .5) * 4, 0, 0);
|
||||||
|
glScalef(2, 1, 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
glTranslatef(-ed * stereo::eyewidth(), 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stereo::set_projection(int ed) {
|
||||||
|
DEBB(DF_GRAPH, (debugfile,"stereo::set_projection\n"));
|
||||||
|
|
||||||
|
start_projection(ed);
|
||||||
|
|
||||||
|
if(pmodel && !stereo::active()) {
|
||||||
|
|
||||||
// simulate glOrtho
|
// simulate glOrtho
|
||||||
GLfloat ortho[16] = {
|
GLfloat ortho[16] = {
|
||||||
GLfloat(2. / vid.xres), 0, 0, 0,
|
GLfloat(2. / vid.xres), 0, 0, 0,
|
||||||
0, GLfloat(-2. / vid.yres), 0, 0,
|
0, GLfloat(-2. / vid.yres), 0, 0,
|
||||||
0, 0, GLfloat(.4 / vid.scrdist), 0,
|
0, 0, GLfloat(.4 / stereo::scrdist), 0,
|
||||||
0, 0, 0, 1};
|
0, 0, 0, 1};
|
||||||
|
|
||||||
vid.scrdist = -vid.scrdist;
|
|
||||||
glMultMatrixf(ortho);
|
glMultMatrixf(ortho);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
}
|
}
|
||||||
else {
|
else if(pmodel) {
|
||||||
float ve = ed*vid.eye;
|
|
||||||
ve *= 2; // vid.xres; ve /= vid.radius;
|
|
||||||
if(ve)
|
|
||||||
glTranslatef(-(ve * vid.radius) * (vid.alpha - (vid.radius*1./vid.xres) * vid.eye) / vid.xres, 0, 0);
|
|
||||||
|
|
||||||
|
float lowdepth = .1, hidepth = 1e9;
|
||||||
|
|
||||||
|
ld right = vid.xres/2 * lowdepth / stereo::scrdist;
|
||||||
|
ld left = -right;
|
||||||
|
ld top = -vid.yres/2 * lowdepth / stereo::scrdist;
|
||||||
|
ld bottom = -top;
|
||||||
|
|
||||||
|
GLfloat frustum[16] = {
|
||||||
|
GLfloat(2 * lowdepth / (right-left)), 0, 0, 0,
|
||||||
|
0, GLfloat(2 * lowdepth / (top-bottom)), 0, 0,
|
||||||
|
0, 0, -(hidepth+lowdepth)/(hidepth-lowdepth), -1,
|
||||||
|
0, 0, -2*lowdepth*hidepth/(hidepth-lowdepth), 0};
|
||||||
|
|
||||||
|
glMultMatrixf(frustum);
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
if(ed) glTranslatef(stereo::ipd * vid.radius * ed/2, 0, 0);
|
||||||
|
|
||||||
|
glScalef(1, 1, -1);
|
||||||
|
glTranslatef(0, 0, stereo::scrdist);
|
||||||
|
|
||||||
|
stereo::scrdist_text = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
float lowdepth = .1;
|
float lowdepth = .1;
|
||||||
float hidepth = 1e9;
|
float hidepth = 1e9;
|
||||||
|
|
||||||
@ -196,20 +253,22 @@ void selectEyeGL(int ed) {
|
|||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
GLfloat sc = vid.radius / (vid.yres/2.);
|
GLfloat sc = vid.radius / (vid.yres/2.);
|
||||||
GLfloat mat[16] = {sc,0,0,0, 0,-sc,0,0, 0,0,-1,0, 0,0, 0,1};
|
GLfloat mat[16] = {sc,0,0,0, 0,-sc,0,0, 0,0,-1,0, 0,0, 0,1};
|
||||||
|
|
||||||
glMultMatrixf(mat);
|
glMultMatrixf(mat);
|
||||||
|
|
||||||
if(ve) glTranslatef(ve, 0, vid.eye);
|
if(ed) glTranslatef(stereo::ipd*ed/2, 0, 0);
|
||||||
vid.scrdist = vid.yres * sc / 2;
|
|
||||||
|
stereo::scrdist_text = vid.yres * sc / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
cameraangle_on = false;
|
cameraangle_on = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void selectEyeMask(int ed) {
|
void stereo::set_mask(int ed) {
|
||||||
if(ed == 0) {
|
if(ed == 0 || stereo::mode != stereo::sAnaglyph) {
|
||||||
glColorMask( GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE );
|
glColorMask( GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE );
|
||||||
}
|
}
|
||||||
else if(ed == 1) {
|
else if(ed == 1) {
|
||||||
@ -220,6 +279,15 @@ void selectEyeMask(int ed) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stereo::set_viewport(int ed) {
|
||||||
|
if(ed == 0 || stereo::mode != stereo::sLR)
|
||||||
|
glViewport(0, 0, vid.xres, vid.yres);
|
||||||
|
else if(ed == 1)
|
||||||
|
glViewport(0, 0, vid.xres/2, vid.yres);
|
||||||
|
else if(ed == -1)
|
||||||
|
glViewport(vid.xres/2, 0, vid.xres/2, vid.yres);
|
||||||
|
}
|
||||||
|
|
||||||
void setGLProjection(int col) {
|
void setGLProjection(int col) {
|
||||||
DEBB(DF_GRAPH, (debugfile,"setGLProjection\n"));
|
DEBB(DF_GRAPH, (debugfile,"setGLProjection\n"));
|
||||||
|
|
||||||
@ -261,7 +329,7 @@ void setGLProjection(int col) {
|
|||||||
else
|
else
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
selectEyeGL(0);
|
stereo::set_projection(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CAP_GLFONT
|
#if CAP_GLFONT
|
||||||
@ -475,7 +543,7 @@ bool gl_print(int x, int y, int shift, int size, const char *s, int color, int a
|
|||||||
displaystr(x+w, y+h, 1, 10, "X", 0xFFFFFF, 8);
|
displaystr(x+w, y+h, 1, 10, "X", 0xFFFFFF, 8);
|
||||||
markcorner = true;
|
markcorner = true;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
for(int i=0; s[i];) {
|
for(int i=0; s[i];) {
|
||||||
|
|
||||||
// glListBase(f.list_base);
|
// glListBase(f.list_base);
|
||||||
@ -488,11 +556,11 @@ bool gl_print(int x, int y, int shift, int size, const char *s, int color, int a
|
|||||||
int hi = f.heights[tabid] * size/gsiz;
|
int hi = f.heights[tabid] * size/gsiz;
|
||||||
|
|
||||||
GLERR("pre-print");
|
GLERR("pre-print");
|
||||||
|
|
||||||
for(int ed = (vid.goteyes && shift)?-1:0; ed<2; ed+=2) {
|
for(int ed = (stereo::active() && shift)?-1:0; ed<2; ed+=2) {
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(x-ed*shift-vid.xcenter,y-vid.ycenter, vid.scrdist);
|
glTranslatef(x-ed*shift-vid.xcenter,y-vid.ycenter, stereo::scrdist_text);
|
||||||
selectEyeMask(ed);
|
stereo::set_mask(ed);
|
||||||
glBindTexture(GL_TEXTURE_2D, f.textures[tabid]);
|
glBindTexture(GL_TEXTURE_2D, f.textures[tabid]);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
@ -516,7 +584,7 @@ bool gl_print(int x, int y, int shift, int size, const char *s, int color, int a
|
|||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(vid.goteyes) selectEyeMask(0);
|
if(stereo::active() && shift) stereo::set_mask(0);
|
||||||
|
|
||||||
GLERR("print");
|
GLERR("print");
|
||||||
|
|
||||||
@ -782,7 +850,7 @@ ld realradius() {
|
|||||||
ld vradius = vid.radius;
|
ld vradius = vid.radius;
|
||||||
if(sphere) {
|
if(sphere) {
|
||||||
if(sphereflipped())
|
if(sphereflipped())
|
||||||
vradius /= sqrt(vid.alphax*vid.alphax - 1);
|
vradius /= sqrt(vid.alpha*vid.alpha - 1);
|
||||||
else
|
else
|
||||||
vradius = 1e12; // use the following
|
vradius = 1e12; // use the following
|
||||||
}
|
}
|
||||||
@ -885,7 +953,7 @@ void drawCircle(int x, int y, int size, int color) {
|
|||||||
float rr = (M_PI * 2 * r) / pts;
|
float rr = (M_PI * 2 * r) / pts;
|
||||||
glcoords[r][0] = x + size * sin(rr);
|
glcoords[r][0] = x + size * sin(rr);
|
||||||
glcoords[r][1] = y + size * cos(rr);
|
glcoords[r][1] = y + size * cos(rr);
|
||||||
glcoords[r][2] = vid.scrdist;
|
glcoords[r][2] = stereo::scrdist;
|
||||||
}
|
}
|
||||||
|
|
||||||
qglcoords = pts;
|
qglcoords = pts;
|
||||||
@ -940,7 +1008,7 @@ void displayColorButton(int x, int y, const string& name, int key, int align, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
ld textscale() {
|
ld textscale() {
|
||||||
return vid.fsize / (vid.radius * crossf) * (1+vid.alphax) * 2;
|
return vid.fsize / (vid.radius * crossf) * (1+vid.alpha) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool notgl = false;
|
// bool notgl = false;
|
||||||
|
@ -102,6 +102,9 @@ int arg::readCommon() {
|
|||||||
else if(argis("-nofps")) {
|
else if(argis("-nofps")) {
|
||||||
nofps = true;
|
nofps = true;
|
||||||
}
|
}
|
||||||
|
else if(argis("-nohud")) {
|
||||||
|
nohud = true;
|
||||||
|
}
|
||||||
else if(argis("-back")) {
|
else if(argis("-back")) {
|
||||||
shift(); backcolor = strtol(args(), NULL, 16);
|
shift(); backcolor = strtol(args(), NULL, 16);
|
||||||
}
|
}
|
||||||
@ -132,6 +135,10 @@ int arg::readCommon() {
|
|||||||
shift(); int q = argi();
|
shift(); int q = argi();
|
||||||
placeItems(q, i);
|
placeItems(q, i);
|
||||||
}
|
}
|
||||||
|
else if(argis("-SM")) {
|
||||||
|
PHASE(2);
|
||||||
|
shift(); stereo::mode = stereo::eStereo(argi());
|
||||||
|
}
|
||||||
else if(argis("-IU")) {
|
else if(argis("-IU")) {
|
||||||
PHASE(3) cheater++; timerghost = false;
|
PHASE(3) cheater++; timerghost = false;
|
||||||
shift(); eItem i = readItem(args());
|
shift(); eItem i = readItem(args());
|
||||||
|
80
config.cpp
80
config.cpp
@ -248,7 +248,6 @@ void initConfig() {
|
|||||||
|
|
||||||
// special graphics
|
// special graphics
|
||||||
|
|
||||||
addsaver(vid.eye, "eye distance", 0);
|
|
||||||
addsaver(vid.ballangle, "ball angle", 20);
|
addsaver(vid.ballangle, "ball angle", 20);
|
||||||
addsaver(vid.yshift, "Y shift", 0);
|
addsaver(vid.yshift, "Y shift", 0);
|
||||||
addsaver(vid.camera_angle, "camera angle", 0);
|
addsaver(vid.camera_angle, "camera angle", 0);
|
||||||
@ -332,6 +331,12 @@ void initConfig() {
|
|||||||
|
|
||||||
addsaver(viewdists, "expansion mode");
|
addsaver(viewdists, "expansion mode");
|
||||||
addsaver(backbrightness, "brightness behind sphere");
|
addsaver(backbrightness, "brightness behind sphere");
|
||||||
|
|
||||||
|
addsaver(stereo::ipd, "interpupilar-distance", 0.05);
|
||||||
|
addsaver(stereo::lr_eyewidth, "eyewidth-lr", 0.5);
|
||||||
|
addsaver(stereo::anaglyph_eyewidth, "eyewidth-anaglyph", 0.1);
|
||||||
|
addsaver(stereo::fov, "field-of-vision", 90);
|
||||||
|
addsaverenum(stereo::mode, "stereo-mode");
|
||||||
|
|
||||||
#if CAP_SHMUP
|
#if CAP_SHMUP
|
||||||
shmup::initConfig();
|
shmup::initConfig();
|
||||||
@ -437,7 +442,7 @@ void loadOldConfig(FILE *f) {
|
|||||||
float a, b, c, d;
|
float a, b, c, d;
|
||||||
err=fscanf(f, "%f%f%f%f\n", &a, &b, &c, &d);
|
err=fscanf(f, "%f%f%f%f\n", &a, &b, &c, &d);
|
||||||
if(err == 4) {
|
if(err == 4) {
|
||||||
vid.scale = a; vid.eye = b; vid.alpha = c; vid.sspeed = d;
|
vid.scale = a; vid.alpha = c; vid.sspeed = d;
|
||||||
}
|
}
|
||||||
err=fscanf(f, "%d%d%d%d%d%d%d", &vid.wallmode, &vid.monmode, &vid.axes, &musicvolume, &vid.framelimit, &gl, &vid.antialias);
|
err=fscanf(f, "%d%d%d%d%d%d%d", &vid.wallmode, &vid.monmode, &vid.axes, &musicvolume, &vid.framelimit, &gl, &vid.antialias);
|
||||||
vid.usingGL = gl;
|
vid.usingGL = gl;
|
||||||
@ -1047,6 +1052,66 @@ string explain3D(ld *param) {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showStereo() {
|
||||||
|
cmode = sm::SIDE | sm::A3 | sm::MAYDARK;
|
||||||
|
gamescreen(0);
|
||||||
|
using namespace geom3;
|
||||||
|
dialog::init(XLAT("stereo vision config"));
|
||||||
|
|
||||||
|
string modenames[4] = { "OFF", "anaglyph", "stereo", "ODS" };
|
||||||
|
|
||||||
|
dialog::addSelItem(XLAT("stereo mode"), XLAT(modenames[stereo::mode]), 'm');
|
||||||
|
dialog::addSelItem(XLAT("interpupilar distance"), fts3(stereo::ipd), 'e');
|
||||||
|
|
||||||
|
switch(stereo::mode) {
|
||||||
|
case stereo::sAnaglyph:
|
||||||
|
dialog::addSelItem(XLAT("distance between images"), fts(stereo::anaglyph_eyewidth), 'd');
|
||||||
|
break;
|
||||||
|
case stereo::sLR:
|
||||||
|
dialog::addSelItem(XLAT("distance between images"), fts(stereo::lr_eyewidth), 'd');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dialog::addBreak(100);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog::addSelItem(XLAT("field of view"), fts(stereo::fov) + "°", 'f');
|
||||||
|
|
||||||
|
dialog::addItem(XLAT("exit stereo configuration"), 'v');
|
||||||
|
dialog::display();
|
||||||
|
|
||||||
|
keyhandler = [] (int sym, int uni) {
|
||||||
|
using namespace geom3;
|
||||||
|
dialog::handleNavigation(sym, uni);
|
||||||
|
|
||||||
|
if(uni == 'm')
|
||||||
|
{ stereo::mode = stereo::eStereo((1 + stereo::mode) % 3); return; }
|
||||||
|
|
||||||
|
else if(uni == 'e')
|
||||||
|
dialog::editNumber(stereo::ipd, -10, 10, 0.01, 0, XLAT("interpupilar distance"),
|
||||||
|
XLAT("Watch the Minkowski hyperboloid or the hypersian rug mode with the "
|
||||||
|
"red/cyan 3D glasses."));
|
||||||
|
|
||||||
|
else if(uni == 'd' && stereo::mode == stereo::sAnaglyph)
|
||||||
|
dialog::editNumber(stereo::anaglyph_eyewidth, -1, 1, 0.01, 0, XLAT("distance between images"),
|
||||||
|
XLAT("Watch the Minkowski hyperboloid or the hypersian rug mode with the "
|
||||||
|
"red/cyan 3D glasses."));
|
||||||
|
|
||||||
|
else if(uni == 'd' && stereo::mode == stereo::sLR)
|
||||||
|
dialog::editNumber(stereo::lr_eyewidth, -1, 1, 0.01, 0, XLAT("distance between images"),
|
||||||
|
XLAT("Watch the Minkowski hyperboloid or the hypersian rug mode with the "
|
||||||
|
"red/cyan 3D glasses."));
|
||||||
|
|
||||||
|
else if(uni == 'f')
|
||||||
|
dialog::editNumber(stereo::fov, 1, 170, 1, 45, "field of view",
|
||||||
|
"Horizontal field of view, in the perspective projection. "
|
||||||
|
"In the orthogonal projection this just controls the scale."
|
||||||
|
);
|
||||||
|
|
||||||
|
else if(doexiton(sym, uni)) popScreen();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void show3D() {
|
void show3D() {
|
||||||
cmode = sm::SIDE | sm::A3 | sm::MAYDARK;
|
cmode = sm::SIDE | sm::A3 | sm::MAYDARK;
|
||||||
gamescreen(0);
|
gamescreen(0);
|
||||||
@ -1072,7 +1137,6 @@ void show3D() {
|
|||||||
dialog::addBreak(50);
|
dialog::addBreak(50);
|
||||||
dialog::addSelItem(XLAT("Y shift"), fts3(vid.yshift), 'y');
|
dialog::addSelItem(XLAT("Y shift"), fts3(vid.yshift), 'y');
|
||||||
dialog::addSelItem(XLAT("camera rotation"), fts3(vid.camera_angle), 's');
|
dialog::addSelItem(XLAT("camera rotation"), fts3(vid.camera_angle), 's');
|
||||||
dialog::addSelItem(XLAT("distance between eyes"), fts3(vid.eye), 'e');
|
|
||||||
dialog::addBreak(50);
|
dialog::addBreak(50);
|
||||||
dialog::addBoolItem(XLAT("ball model"), pmodel == mdBall, 'B');
|
dialog::addBoolItem(XLAT("ball model"), pmodel == mdBall, 'B');
|
||||||
dialog::addBoolItem(XLAT("hyperboloid model"), pmodel == mdHyperboloid, 'M');
|
dialog::addBoolItem(XLAT("hyperboloid model"), pmodel == mdHyperboloid, 'M');
|
||||||
@ -1090,6 +1154,7 @@ void show3D() {
|
|||||||
else
|
else
|
||||||
dialog::addInfo(XLAT("parameters set correctly"));
|
dialog::addInfo(XLAT("parameters set correctly"));
|
||||||
dialog::addBreak(50);
|
dialog::addBreak(50);
|
||||||
|
dialog::addItem(XLAT("stereo vision config"), 'e');
|
||||||
dialog::addItem(XLAT("exit 3D configuration"), 'v');
|
dialog::addItem(XLAT("exit 3D configuration"), 'v');
|
||||||
dialog::display();
|
dialog::display();
|
||||||
|
|
||||||
@ -1121,13 +1186,10 @@ void show3D() {
|
|||||||
dialog::editNumber(geom3::rock_wall_ratio, 0, 1, .1, .9, XLAT("Rock-III to wall ratio"), "");
|
dialog::editNumber(geom3::rock_wall_ratio, 0, 1, .1, .9, XLAT("Rock-III to wall ratio"), "");
|
||||||
else if(uni == 'h')
|
else if(uni == 'h')
|
||||||
dialog::editNumber(geom3::human_wall_ratio, 0, 1, .1, .7, XLAT("Human to wall ratio"), "");
|
dialog::editNumber(geom3::human_wall_ratio, 0, 1, .1, .7, XLAT("Human to wall ratio"), "");
|
||||||
|
|
||||||
else if(uni == 'e')
|
else if(uni == 'e')
|
||||||
cmode &= sm::A3,
|
pushScreen(showStereo);
|
||||||
dialog::editNumber(vid.eye, -10, 10, 0.01, 0, XLAT("distance between eyes"),
|
|
||||||
XLAT("Watch the Minkowski hyperboloid or the hypersian rug mode with the "
|
|
||||||
"red/cyan 3D glasses."));
|
|
||||||
|
|
||||||
else if(uni == 'y')
|
else if(uni == 'y')
|
||||||
cmode &= sm::A3,
|
cmode &= sm::A3,
|
||||||
dialog::editNumber(vid.yshift, 0, 1, .1, 0, XLAT("Y shift"),
|
dialog::editNumber(vid.yshift, 0, 1, .1, 0, XLAT("Y shift"),
|
||||||
|
@ -96,7 +96,7 @@ namespace polygonal {
|
|||||||
hyperpoint h;
|
hyperpoint h;
|
||||||
h[0] = z2.first * vid.radius;
|
h[0] = z2.first * vid.radius;
|
||||||
h[1] = z2.second * vid.radius;
|
h[1] = z2.second * vid.radius;
|
||||||
h[2] = vid.scrdist;
|
h[2] = stereo::scrdist;
|
||||||
curvepoint(h);
|
curvepoint(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,6 +430,9 @@ void fix_mouseh() {
|
|||||||
|
|
||||||
void handlekey(int sym, int uni) {
|
void handlekey(int sym, int uni) {
|
||||||
|
|
||||||
|
if(uni == '=') { stereo::mode = stereo::eStereo((1 + stereo::mode) % 3); return; }
|
||||||
|
if(uni == '+') switchGL();
|
||||||
|
|
||||||
if(callhandlers(false, hooks_handleKey, sym, uni)) return;
|
if(callhandlers(false, hooks_handleKey, sym, uni)) return;
|
||||||
|
|
||||||
keyhandler(sym, uni);
|
keyhandler(sym, uni);
|
||||||
|
38
graph.cpp
38
graph.cpp
@ -2209,8 +2209,9 @@ void sumaura(int v) {
|
|||||||
|
|
||||||
void drawaura() {
|
void drawaura() {
|
||||||
if(!haveaura()) return;
|
if(!haveaura()) return;
|
||||||
|
if(stereo::mode) return;
|
||||||
double rad = vid.radius;
|
double rad = vid.radius;
|
||||||
if(sphere && !mdEqui()) rad /= sqrt(vid.alphax*vid.alphax - 1);
|
if(sphere && !mdEqui()) rad /= sqrt(vid.alpha*vid.alpha - 1);
|
||||||
|
|
||||||
for(int v=0; v<4; v++) sumaura(v);
|
for(int v=0; v<4; v++) sumaura(v);
|
||||||
for(auto& p: auraspecials) {
|
for(auto& p: auraspecials) {
|
||||||
@ -2297,7 +2298,7 @@ void drawaura() {
|
|||||||
cx[r][z][u+2] = bak[u] + (aurac[rm][u] / (aurac[rm][3]+.1) - bak[u]) * cmul[z];
|
cx[r][z][u+2] = bak[u] + (aurac[rm][u] / (aurac[rm][3]+.1) - bak[u]) * cmul[z];
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int u=0; u<4; u++) glcoords[u][2] = vid.scrdist;
|
for(int u=0; u<4; u++) glcoords[u][2] = stereo::scrdist;
|
||||||
for(int u=0; u<4; u++) coltab[u][3] = 1;
|
for(int u=0; u<4; u++) coltab[u][3] = 1;
|
||||||
|
|
||||||
for(int r=0; r<AURA; r++) for(int z=0;z<10;z++) {
|
for(int r=0; r<AURA; r++) for(int z=0;z<10;z++) {
|
||||||
@ -2693,7 +2694,7 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
|||||||
fcol = reptilecolor(c);
|
fcol = reptilecolor(c);
|
||||||
break;
|
break;
|
||||||
case laCrossroads:
|
case laCrossroads:
|
||||||
fcol = (vid.goteyes2 ? 0xFF3030 : 0xFF0000);
|
fcol = (stereo::in_anaglyph() ? 0xFF3030 : 0xFF0000);
|
||||||
break;
|
break;
|
||||||
case laCaves: case laEmerald: case laDeadCaves:
|
case laCaves: case laEmerald: case laDeadCaves:
|
||||||
fcol = 0x202020;
|
fcol = 0x202020;
|
||||||
@ -2704,7 +2705,7 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case laJungle:
|
case laJungle:
|
||||||
fcol = (vid.goteyes2 ? 0x408040 : 0x008000);
|
fcol = (stereo::in_anaglyph() ? 0x408040 : 0x008000);
|
||||||
break;
|
break;
|
||||||
case laMirror: case laMirrorWall: case laMirrorOld:
|
case laMirror: case laMirrorWall: case laMirrorOld:
|
||||||
fcol = 0x808080;
|
fcol = 0x808080;
|
||||||
@ -2719,10 +2720,10 @@ void setcolors(cell *c, int& wcol, int &fcol) {
|
|||||||
if(c->wall == waPlatform) wcol = 0xF0F0A0;
|
if(c->wall == waPlatform) wcol = 0xF0F0A0;
|
||||||
break;
|
break;
|
||||||
case laRlyeh:
|
case laRlyeh:
|
||||||
fcol = (vid.goteyes2 ? 0x4080C0 : 0x004080);
|
fcol = (stereo::in_anaglyph() ? 0x4080C0 : 0x004080);
|
||||||
break;
|
break;
|
||||||
case laHell:
|
case laHell:
|
||||||
fcol = (vid.goteyes2 ? 0xC03030 : 0xC00000);
|
fcol = (stereo::in_anaglyph() ? 0xC03030 : 0xC00000);
|
||||||
break;
|
break;
|
||||||
case laCanvas:
|
case laCanvas:
|
||||||
fcol = c->landparam;
|
fcol = c->landparam;
|
||||||
@ -3166,7 +3167,7 @@ void placeSidewall(cell *c, int i, int sidepar, const transmatrix& V, bool warp,
|
|||||||
|
|
||||||
transmatrix V2 = V * ddspin(c, i);
|
transmatrix V2 = V * ddspin(c, i);
|
||||||
|
|
||||||
// if(sphere && vid.alphax <= 1 && tC0(V2 * xpush(cellgfxdist(c, i)/2))[2] < -.5) return;
|
// if(sphere && vid.alpha <= 1 && tC0(V2 * xpush(cellgfxdist(c, i)/2))[2] < -.5) return;
|
||||||
|
|
||||||
/* int aw = away(V2); prio += aw;
|
/* int aw = away(V2); prio += aw;
|
||||||
if(!detaillevel && aw < 0) return;
|
if(!detaillevel && aw < 0) return;
|
||||||
@ -5342,12 +5343,13 @@ void calcparam() {
|
|||||||
vid.xcenter += vid.scrsize * vid.xposition;
|
vid.xcenter += vid.scrsize * vid.xposition;
|
||||||
vid.ycenter += vid.scrsize * vid.yposition;
|
vid.ycenter += vid.scrsize * vid.yposition;
|
||||||
|
|
||||||
ld eye = vid.eye; if(pmodel || rug::rugged) eye = 0;
|
stereo::tanfov = tan(stereo::fov * M_PI / 360);
|
||||||
vid.beta = 1 + vid.alpha + eye;
|
|
||||||
vid.alphax = vid.alpha + eye;
|
if(pmodel)
|
||||||
vid.goteyes = vid.eye > 0.001 || vid.eye < -0.001;
|
stereo::scrdist = vid.xres / 2 / stereo::tanfov;
|
||||||
vid.goteyes2 = vid.goteyes;
|
else
|
||||||
vid.scrdist = vid.radius;
|
stereo::scrdist = vid.radius;
|
||||||
|
stereo::scrdist_text = stereo::scrdist;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ringcolor = darkena(0xFF, 0, 0xFF);
|
int ringcolor = darkena(0xFF, 0, 0xFF);
|
||||||
@ -5360,19 +5362,19 @@ void drawfullmap() {
|
|||||||
|
|
||||||
ptds.clear();
|
ptds.clear();
|
||||||
|
|
||||||
if(!vid.goteyes && !euclid && (pmodel == mdDisk || pmodel == mdBall || (sphere && mdEqui()))) {
|
if(!stereo::active() && !euclid && (pmodel == mdDisk || pmodel == mdBall || (sphere && mdEqui()))) {
|
||||||
double rad = vid.radius;
|
double rad = vid.radius;
|
||||||
if(sphere) {
|
if(sphere) {
|
||||||
if(mdEqui())
|
if(mdEqui())
|
||||||
;
|
;
|
||||||
else if(!vid.grid && !elliptic)
|
else if(!vid.grid && !elliptic)
|
||||||
rad = 0;
|
rad = 0;
|
||||||
else if(vid.alphax <= 0)
|
else if(vid.alpha <= 0)
|
||||||
;
|
;
|
||||||
else if(vid.alphax <= 1 && (vid.grid || elliptic)) // mark the equator
|
else if(vid.alpha <= 1 && (vid.grid || elliptic)) // mark the equator
|
||||||
rad = rad * 1 / vid.alphax;
|
rad = rad * 1 / vid.alpha;
|
||||||
else if(vid.grid) // mark the edge
|
else if(vid.grid) // mark the edge
|
||||||
rad /= sqrt(vid.alphax*vid.alphax - 1);
|
rad /= sqrt(vid.alpha*vid.alpha - 1);
|
||||||
}
|
}
|
||||||
if(!haveaura()) queuecircle(vid.xcenter, vid.ycenter, rad, ringcolor,
|
if(!haveaura()) queuecircle(vid.xcenter, vid.ycenter, rad, ringcolor,
|
||||||
vid.usingGL ? PPR_CIRCLE : PPR_OUTCIRCLE);
|
vid.usingGL ? PPR_CIRCLE : PPR_OUTCIRCLE);
|
||||||
|
131
hud.cpp
131
hud.cpp
@ -332,8 +332,9 @@ bool nofps = false;
|
|||||||
void drawStats() {
|
void drawStats() {
|
||||||
callhandlers(false, hooks_prestats);
|
callhandlers(false, hooks_prestats);
|
||||||
#if CAP_ROGUEVIZ
|
#if CAP_ROGUEVIZ
|
||||||
if(rogueviz::on || nohud) return;
|
if(rogueviz::on) return;
|
||||||
#endif
|
#endif
|
||||||
|
if(nohud || stereo::mode == stereo::sLR) return;
|
||||||
if(viewdists && sidescreen) {
|
if(viewdists && sidescreen) {
|
||||||
distcolors[0] = forecolor;
|
distcolors[0] = forecolor;
|
||||||
dialog::init("");
|
dialog::init("");
|
||||||
@ -375,11 +376,11 @@ void drawStats() {
|
|||||||
{
|
{
|
||||||
dynamicval<eModel> pm(pmodel, mdDisk);
|
dynamicval<eModel> pm(pmodel, mdDisk);
|
||||||
dynamicval<ld> va(vid.alpha, 1);
|
dynamicval<ld> va(vid.alpha, 1);
|
||||||
dynamicval<ld> vax(vid.alphax, 1);
|
dynamicval<ld> vax(vid.alpha, 1);
|
||||||
dynamicval<videopar> v(vid, vid);
|
dynamicval<videopar> v(vid, vid);
|
||||||
calcparam();
|
calcparam();
|
||||||
#if CAP_GL
|
#if CAP_GL
|
||||||
selectEyeGL(0);
|
stereo::set_projection(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(haveMobileCompass()) {
|
if(haveMobileCompass()) {
|
||||||
@ -436,69 +437,77 @@ void drawStats() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
instat = false;
|
else {
|
||||||
bool portrait = vid.xres < vid.yres;
|
|
||||||
int colspace = portrait ? (vid.yres - vid.xres - vid.fsize*3) : (vid.xres - vid.yres - 16) / 2;
|
instat = false;
|
||||||
int rowspace = portrait ? vid.xres - 16 : vid.yres - vid.fsize * (vid.msgleft ? 9 : 4);
|
bool portrait = vid.xres < vid.yres;
|
||||||
int colid[4], rowid[4];
|
int colspace = portrait ? (vid.yres - vid.xres - vid.fsize*3) : (vid.xres - vid.yres - 16) / 2;
|
||||||
int maxbyclass[4];
|
int rowspace = portrait ? vid.xres - 16 : vid.yres - vid.fsize * (vid.msgleft ? 9 : 4);
|
||||||
for(int z=0; z<4; z++) maxbyclass[z] = 0;
|
int colid[4], rowid[4];
|
||||||
for(int i=0; i<glyphs; i++) if(ikappear(i))
|
int maxbyclass[4];
|
||||||
if(!portrait || (glyphflags(i) | GLYPH_INPORTRAIT))
|
for(int z=0; z<4; z++) maxbyclass[z] = 0;
|
||||||
maxbyclass[glyphclass(i)]++;
|
for(int i=0; i<glyphs; i++) if(ikappear(i))
|
||||||
int buttonsize;
|
if(!portrait || (glyphflags(i) | GLYPH_INPORTRAIT))
|
||||||
int columns, rows;
|
maxbyclass[glyphclass(i)]++;
|
||||||
bool imponly = false;
|
int buttonsize;
|
||||||
int minsize = vid.fsize * (portrait ? 4 : 2);
|
int columns, rows;
|
||||||
rows = 0;
|
bool imponly = false;
|
||||||
while((buttonsize = minsize - vid.killreduction)) {
|
int minsize = vid.fsize * (portrait ? 4 : 2);
|
||||||
columns = colspace / buttonsize;
|
rows = 0;
|
||||||
rows = rowspace / buttonsize;
|
while((buttonsize = minsize - vid.killreduction)) {
|
||||||
int coltaken = 0;
|
columns = colspace / buttonsize;
|
||||||
for(int z=0; z<4; z++) {
|
rows = rowspace / buttonsize;
|
||||||
if(z == 2 && !portrait) {
|
int coltaken = 0;
|
||||||
if(coltaken > columns) { vid.killreduction++; continue; }
|
for(int z=0; z<4; z++) {
|
||||||
coltaken = 0;
|
if(z == 2 && !portrait) {
|
||||||
|
if(coltaken > columns) { vid.killreduction++; continue; }
|
||||||
|
coltaken = 0;
|
||||||
|
}
|
||||||
|
colid[z] = coltaken, rowid[z] = 0,
|
||||||
|
coltaken += (maxbyclass[z] + rows-1) / rows;
|
||||||
}
|
}
|
||||||
colid[z] = coltaken, rowid[z] = 0,
|
if(coltaken > columns) { vid.killreduction++; continue; }
|
||||||
coltaken += (maxbyclass[z] + rows-1) / rows;
|
break;
|
||||||
}
|
}
|
||||||
if(coltaken > columns) { vid.killreduction++; continue; }
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(buttonsize <= vid.fsize*3/4) {
|
|
||||||
imponly = true; buttonsize = minsize;
|
|
||||||
rows = rowspace / buttonsize; if(!rows) return;
|
|
||||||
colid[0] = 0; colid[2] = portrait ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
updatesort();
|
if(buttonsize <= vid.fsize*3/4) {
|
||||||
stable_sort(glyphorder, glyphorder+glyphs, glyphsort);
|
imponly = true; buttonsize = minsize;
|
||||||
|
rows = rowspace / buttonsize; if(!rows) return;
|
||||||
|
colid[0] = 0; colid[2] = portrait ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
updatesort();
|
||||||
|
stable_sort(glyphorder, glyphorder+glyphs, glyphsort);
|
||||||
|
|
||||||
|
for(int i0=0; i0<glyphs; i0++) {
|
||||||
|
int i = glyphorder[i0];
|
||||||
|
if(!ikappear(i)) continue;
|
||||||
|
int z = glyphclass(i);
|
||||||
|
int imp = glyphflags(i);
|
||||||
|
if(imponly) { z &=~1; if(!(imp & GLYPH_IMPORTANT)) continue; }
|
||||||
|
|
||||||
for(int i0=0; i0<glyphs; i0++) {
|
int cx, cy;
|
||||||
int i = glyphorder[i0];
|
if(portrait)
|
||||||
if(!ikappear(i)) continue;
|
cx = 8 + buttonsize * rowid[z], cy = vid.fsize*2 + buttonsize * (colid[z]) + buttonsize/2;
|
||||||
int z = glyphclass(i);
|
else
|
||||||
int imp = glyphflags(i);
|
cx = 8 + buttonsize * (colid[z]), cy = vid.fsize * 3 + buttonsize * rowid[z];
|
||||||
if(imponly) { z &=~1; if(!(imp & GLYPH_IMPORTANT)) continue; }
|
|
||||||
|
if(!portrait && z < 2) cx = vid.xres - cx - buttonsize;
|
||||||
int cx, cy;
|
|
||||||
if(portrait)
|
rowid[z]++; if(rowid[z] >= rows) rowid[z] = 0, colid[z]++;
|
||||||
cx = 8 + buttonsize * rowid[z], cy = vid.fsize*2 + buttonsize * (colid[z]) + buttonsize/2;
|
|
||||||
else
|
displayglyph2(cx, cy, buttonsize, i);
|
||||||
cx = 8 + buttonsize * (colid[z]), cy = vid.fsize * 3 + buttonsize * rowid[z];
|
}
|
||||||
|
|
||||||
if(!portrait && z < 2) cx = vid.xres - cx - buttonsize;
|
|
||||||
|
|
||||||
rowid[z]++; if(rowid[z] >= rows) rowid[z] = 0, colid[z]++;
|
|
||||||
|
|
||||||
displayglyph2(cx, cy, buttonsize, i);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
calcparam();
|
||||||
|
#if CAP_GL
|
||||||
|
stereo::set_projection(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
string s0;
|
string s0;
|
||||||
if(!peace::on) {
|
if(!peace::on) {
|
||||||
if(displayButtonS(vid.xres - 8, vid.fsize, XLAT("score: %1", its(gold())), forecolor, 16, vid.fsize)) {
|
if(displayButtonS(vid.xres - 8, vid.fsize, XLAT("score: %1", its(gold())), forecolor, 16, vid.fsize)) {
|
||||||
@ -554,10 +563,4 @@ XLAT(
|
|||||||
|
|
||||||
callhooks(hooks_stats);
|
callhooks(hooks_stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
calcparam();
|
|
||||||
#if CAP_GL
|
|
||||||
selectEyeGL(0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
31
hyper.h
31
hyper.h
@ -587,14 +587,13 @@ extern reaction_t help_delegate;
|
|||||||
#define HELPFUN(x) (help_delegate = x, "HELPFUN")
|
#define HELPFUN(x) (help_delegate = x, "HELPFUN")
|
||||||
|
|
||||||
struct videopar {
|
struct videopar {
|
||||||
ld scale, eye, alpha, sspeed, mspeed, yshift, camera_angle;
|
ld scale, alpha, sspeed, mspeed, yshift, camera_angle;
|
||||||
ld ballangle, ballproj;
|
ld ballangle, ballproj;
|
||||||
int mobilecompasssize;
|
int mobilecompasssize;
|
||||||
int aurastr, aurasmoothen;
|
int aurastr, aurasmoothen;
|
||||||
|
|
||||||
bool full;
|
bool full;
|
||||||
bool goteyes; // for rendering
|
|
||||||
bool goteyes2; // for choosing colors
|
|
||||||
int graphglyph; // graphical glyphs
|
int graphglyph; // graphical glyphs
|
||||||
bool darkhepta;
|
bool darkhepta;
|
||||||
int shifttarget;
|
int shifttarget;
|
||||||
@ -609,7 +608,6 @@ struct videopar {
|
|||||||
int xcenter, ycenter;
|
int xcenter, ycenter;
|
||||||
int radius;
|
int radius;
|
||||||
int scrsize;
|
int scrsize;
|
||||||
ld alphax, beta;
|
|
||||||
|
|
||||||
bool grid;
|
bool grid;
|
||||||
int particles;
|
int particles;
|
||||||
@ -622,9 +620,6 @@ struct videopar {
|
|||||||
|
|
||||||
int msgleft, msglimit;
|
int msgleft, msglimit;
|
||||||
|
|
||||||
// for OpenGL
|
|
||||||
float scrdist;
|
|
||||||
|
|
||||||
bool usingGL;
|
bool usingGL;
|
||||||
int antialias;
|
int antialias;
|
||||||
#define AA_NOGL 1
|
#define AA_NOGL 1
|
||||||
@ -2536,3 +2531,25 @@ struct renderbuffer {
|
|||||||
void use_as_texture();
|
void use_as_texture();
|
||||||
void clear(int col);
|
void clear(int col);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace stereo {
|
||||||
|
enum eStereo { sOFF, sAnaglyph, sLR, sODS };
|
||||||
|
|
||||||
|
extern eStereo mode;
|
||||||
|
extern ld ipd;
|
||||||
|
extern ld lr_eyewidth, anaglyph_eyewidth;
|
||||||
|
extern ld fov, tanfov;
|
||||||
|
|
||||||
|
extern GLfloat scrdist, scrdist_text;
|
||||||
|
|
||||||
|
ld eyewidth();
|
||||||
|
bool active();
|
||||||
|
bool in_anaglyph();
|
||||||
|
|
||||||
|
void set_viewport(int ed);
|
||||||
|
void set_projection(int ed);
|
||||||
|
void set_mask(int ed);
|
||||||
|
}
|
||||||
|
|
||||||
|
double randd();
|
||||||
|
|
||||||
|
54
hypgraph.cpp
54
hypgraph.cpp
@ -26,7 +26,7 @@ hyperpoint gethyper(ld x, ld y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(euclid)
|
if(euclid)
|
||||||
return hpxy(hx * (EUCSCALE + vid.alphax), hy * (EUCSCALE + vid.alphax));
|
return hpxy(hx * (EUCSCALE + vid.alpha), hy * (EUCSCALE + vid.alpha));
|
||||||
|
|
||||||
if(vid.camera_angle) camrotate(hx, hy);
|
if(vid.camera_angle) camrotate(hx, hy);
|
||||||
|
|
||||||
@ -45,8 +45,8 @@ hyperpoint gethyper(ld x, ld y) {
|
|||||||
ld curv = sphere ? 1 : -1;
|
ld curv = sphere ? 1 : -1;
|
||||||
|
|
||||||
A = 1+curv*hr;
|
A = 1+curv*hr;
|
||||||
B = 2*hr*vid.alphax*-curv;
|
B = 2*hr*vid.alpha*-curv;
|
||||||
C = 1 - curv*hr*vid.alphax*vid.alphax;
|
C = 1 - curv*hr*vid.alpha*vid.alpha;
|
||||||
|
|
||||||
// Az^2 - Bz = C
|
// Az^2 - Bz = C
|
||||||
B /= A; C /= A;
|
B /= A; C /= A;
|
||||||
@ -56,13 +56,13 @@ hyperpoint gethyper(ld x, ld y) {
|
|||||||
// z = (B/2) + sqrt(C + B^2/4)
|
// z = (B/2) + sqrt(C + B^2/4)
|
||||||
|
|
||||||
ld rootsign = 1;
|
ld rootsign = 1;
|
||||||
if(sphere && vid.alphax > 1) rootsign = -1;
|
if(sphere && vid.alpha > 1) rootsign = -1;
|
||||||
|
|
||||||
ld hz = B / 2 + rootsign * sqrt(C + B*B/4);
|
ld hz = B / 2 + rootsign * sqrt(C + B*B/4);
|
||||||
|
|
||||||
hyperpoint H;
|
hyperpoint H;
|
||||||
H[0] = hx * (hz+vid.alphax);
|
H[0] = hx * (hz+vid.alpha);
|
||||||
H[1] = hy * (hz+vid.alphax);
|
H[1] = hy * (hz+vid.alpha);
|
||||||
H[2] = hz;
|
H[2] = hz;
|
||||||
|
|
||||||
return H;
|
return H;
|
||||||
@ -83,9 +83,21 @@ void ballmodel(hyperpoint& ret, double alpha, double d, double zl) {
|
|||||||
ret[2] = - ax * sa * cb - ay * sb;
|
ret[2] = - ax * sa * cb - ay * sb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void apply_depth(hyperpoint &f, ld z) {
|
||||||
|
if(vid.usingGL)
|
||||||
|
f[2] = z;
|
||||||
|
else {
|
||||||
|
z = z * vid.radius;
|
||||||
|
ld mul = stereo::scrdist / (stereo::scrdist + z);
|
||||||
|
f[0] = f[0] * mul;
|
||||||
|
f[1] = f[1] * mul;
|
||||||
|
f[2] = vid.xres * stereo::eyewidth() / 2 / vid.radius + stereo::ipd * mul / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void applymodel(hyperpoint H, hyperpoint& ret) {
|
void applymodel(hyperpoint H, hyperpoint& ret) {
|
||||||
|
|
||||||
ld tz = euclid ? (EUCSCALE+vid.alphax) : vid.alphax+H[2];
|
ld tz = euclid ? (EUCSCALE+vid.alpha) : vid.alpha+H[2];
|
||||||
if(tz < BEHIND_LIMIT && tz > -BEHIND_LIMIT) tz = BEHIND_LIMIT;
|
if(tz < BEHIND_LIMIT && tz > -BEHIND_LIMIT) tz = BEHIND_LIMIT;
|
||||||
|
|
||||||
if(pmodel == mdUnchanged) {
|
if(pmodel == mdUnchanged) {
|
||||||
@ -124,9 +136,9 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
|||||||
if(pmodel == mdDisk) {
|
if(pmodel == mdDisk) {
|
||||||
|
|
||||||
if(!vid.camera_angle) {
|
if(!vid.camera_angle) {
|
||||||
ret[0] = H[0] / tz;
|
ret[0] = H[0] / tz;
|
||||||
ret[1] = H[1] / tz;
|
ret[1] = H[1] / tz;
|
||||||
ret[2] = (1 - vid.beta / tz);
|
ret[2] = vid.xres / vid.radius * stereo::eyewidth() / 2 - stereo::ipd / tz / 2;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ld tx = H[0];
|
ld tx = H[0];
|
||||||
@ -137,7 +149,7 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
|||||||
ld ux = tx, uy = ty * cc - ss * tz, uz = tz * cc + ss * ty;
|
ld ux = tx, uy = ty * cc - ss * tz, uz = tz * cc + ss * ty;
|
||||||
ret[0] = ux / uz;
|
ret[0] = ux / uz;
|
||||||
ret[1] = uy / uz;
|
ret[1] = uy / uz;
|
||||||
ret[2] = 1 - vid.beta / uz;
|
ret[2] = vid.xres / vid.radius * stereo::eyewidth() / 2 - stereo::ipd / uz / 2;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -164,14 +176,14 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
|||||||
ret[0] = d * H[0] / rad / M_PI;
|
ret[0] = d * H[0] / rad / M_PI;
|
||||||
ret[1] = d * H[1] / rad / M_PI;
|
ret[1] = d * H[1] / rad / M_PI;
|
||||||
ret[2] = 0;
|
ret[2] = 0;
|
||||||
if(zlev != 1 && vid.goteyes)
|
if(zlev != 1 && stereo::active())
|
||||||
ret[2] = geom3::factor_to_lev(zlev);
|
apply_depth(ret, -geom3::factor_to_lev(zlev));
|
||||||
ghcheck(ret,H);
|
ghcheck(ret,H);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tz = H[2]+vid.alphax;
|
tz = H[2]+vid.alpha;
|
||||||
|
|
||||||
if(pmodel == mdPolygonal || pmodel == mdPolynomial) {
|
if(pmodel == mdPolygonal || pmodel == mdPolynomial) {
|
||||||
pair<long double, long double> p = polygonal::compute(H[0]/tz, H[1]/tz);
|
pair<long double, long double> p = polygonal::compute(H[0]/tz, H[1]/tz);
|
||||||
@ -198,8 +210,8 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
|||||||
if(wmspatial || mmspatial) y0 *= zlev;
|
if(wmspatial || mmspatial) y0 *= zlev;
|
||||||
ret[1] = 1 - y0;
|
ret[1] = 1 - y0;
|
||||||
ret[2] = 0;
|
ret[2] = 0;
|
||||||
if(zlev != 1 && vid.goteyes)
|
if(zlev != 1 && stereo::active())
|
||||||
ret[2] = y0 * geom3::factor_to_lev(zlev);
|
apply_depth(ret, -y0 * geom3::factor_to_lev(zlev));
|
||||||
ghcheck(ret,H);
|
ghcheck(ret,H);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -229,8 +241,8 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
|||||||
ret[1] = -y0/M_PI*2;
|
ret[1] = -y0/M_PI*2;
|
||||||
ret[2] = 0;
|
ret[2] = 0;
|
||||||
|
|
||||||
if(zlev != 1 && vid.goteyes)
|
if(zlev != 1 && stereo::active())
|
||||||
ret[2] = geom3::factor_to_lev(zlev) / (1 + yv * yv);
|
apply_depth(ret, -geom3::factor_to_lev(zlev) / (1 + yv * yv));
|
||||||
|
|
||||||
ghcheck(ret,H);
|
ghcheck(ret,H);
|
||||||
}
|
}
|
||||||
@ -442,7 +454,7 @@ void drawEuclidean() {
|
|||||||
|
|
||||||
transmatrix View0 = View;
|
transmatrix View0 = View;
|
||||||
|
|
||||||
ld cellrad = vid.radius / (EUCSCALE + vid.alphax);
|
ld cellrad = vid.radius / (EUCSCALE + vid.alpha);
|
||||||
|
|
||||||
ld centerd = matrixnorm(View0);
|
ld centerd = matrixnorm(View0);
|
||||||
|
|
||||||
@ -613,8 +625,8 @@ void fullcenter() {
|
|||||||
|
|
||||||
transmatrix screenpos(ld x, ld y) {
|
transmatrix screenpos(ld x, ld y) {
|
||||||
transmatrix V = Id;
|
transmatrix V = Id;
|
||||||
V[0][2] += (x - vid.xcenter) / vid.radius * (1+vid.alphax);
|
V[0][2] += (x - vid.xcenter) / vid.radius * (1+vid.alpha);
|
||||||
V[1][2] += (y - vid.ycenter) / vid.radius * (1+vid.alphax);
|
V[1][2] += (y - vid.ycenter) / vid.radius * (1+vid.alpha);
|
||||||
return V;
|
return V;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -625,7 +637,7 @@ transmatrix atscreenpos(ld x, ld y, ld size) {
|
|||||||
V[1][2] += (y - vid.ycenter);
|
V[1][2] += (y - vid.ycenter);
|
||||||
V[0][0] = size * 2 * hcrossf / crossf;
|
V[0][0] = size * 2 * hcrossf / crossf;
|
||||||
V[1][1] = size * 2 * hcrossf / crossf;
|
V[1][1] = size * 2 * hcrossf / crossf;
|
||||||
V[2][2] = vid.scrdist;
|
V[2][2] = stereo::scrdist;
|
||||||
if(euclid) V[2][2] /= EUCSCALE;
|
if(euclid) V[2][2] /= EUCSCALE;
|
||||||
|
|
||||||
return V;
|
return V;
|
||||||
|
119
polygons.cpp
119
polygons.cpp
@ -184,13 +184,13 @@ void addpoint(const hyperpoint& H) {
|
|||||||
if(qglcoords >= POLYMAX) return;
|
if(qglcoords >= POLYMAX) return;
|
||||||
|
|
||||||
if(true) {
|
if(true) {
|
||||||
hyperpoint Hscr;
|
hyperpoint Hscr;
|
||||||
applymodel(H, Hscr);
|
applymodel(H, Hscr);
|
||||||
if(vid.alphax + H[2] <= BEHIND_LIMIT && pmodel == mdDisk) poly_flags |= POLY_BEHIND;
|
if(vid.alpha + H[2] <= BEHIND_LIMIT && pmodel == mdDisk) poly_flags |= POLY_BEHIND;
|
||||||
|
|
||||||
if(spherespecial) {
|
if(spherespecial) {
|
||||||
double curnorm = H[0]*H[0]+H[1]*H[1]+H[2]*H[2];
|
double curnorm = H[0]*H[0]+H[1]*H[1]+H[2]*H[2];
|
||||||
double horizon = curnorm / vid.alphax;
|
double horizon = curnorm / vid.alpha;
|
||||||
|
|
||||||
if((spherespecial>0) ^ (H[2] <= -horizon)) poly_flags |= POLY_INFRONT;
|
if((spherespecial>0) ^ (H[2] <= -horizon)) poly_flags |= POLY_INFRONT;
|
||||||
else {
|
else {
|
||||||
@ -198,7 +198,7 @@ void addpoint(const hyperpoint& H) {
|
|||||||
(sqrt(curnorm - horizon*horizon) / (vid.alpha - horizon)) /
|
(sqrt(curnorm - horizon*horizon) / (vid.alpha - horizon)) /
|
||||||
(sqrt(curnorm - H[2]*H[2]) / (vid.alpha+H[2]));
|
(sqrt(curnorm - H[2]*H[2]) / (vid.alpha+H[2]));
|
||||||
|
|
||||||
// double coef = (vid.alphax + horizon) / (vid.alphax + H[2]); -< that one has a funny effect, seriously
|
// double coef = (vid.alpha + horizon) / (vid.alpha + H[2]); -< that one has a funny effect, seriously
|
||||||
Hscr[0] *= coef;
|
Hscr[0] *= coef;
|
||||||
Hscr[1] *= coef;
|
Hscr[1] *= coef;
|
||||||
}
|
}
|
||||||
@ -218,13 +218,11 @@ void addpoint(const hyperpoint& H) {
|
|||||||
void coords_to_poly() {
|
void coords_to_poly() {
|
||||||
polyi = qglcoords;
|
polyi = qglcoords;
|
||||||
for(int i=0; i<polyi; i++) {
|
for(int i=0; i<polyi; i++) {
|
||||||
// printf("%lf %lf\n", double(glcoords[i][0]), double(glcoords[i][1]));
|
// printf("%lf %lf\n", double(glcoords[i][0]), double(glcoords[i][1]));
|
||||||
ld x = vid.xcenter + glcoords[i][0];
|
|
||||||
ld y = vid.ycenter + glcoords[i][1];
|
polyx[i] = vid.xcenter + glcoords[i][0] - glcoords[i][2];
|
||||||
ld xe = glcoords[i][2] * vid.eye;
|
polyxr[i] = vid.xcenter + glcoords[i][0] + glcoords[i][2];
|
||||||
polyx[i] = x-xe;
|
polyy[i] = vid.ycenter + glcoords[i][1];
|
||||||
polyxr[i] = x+xe;
|
|
||||||
polyy[i] = y;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,15 +319,15 @@ int tinfshift;
|
|||||||
|
|
||||||
void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline, int flags, textureinfo *tinf) {
|
void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline, int flags, textureinfo *tinf) {
|
||||||
|
|
||||||
if(tinf) {
|
if(tinf) {
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glBindTexture(GL_TEXTURE_2D, tinf->texture_id);
|
glBindTexture(GL_TEXTURE_2D, tinf->texture_id);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
glTexCoordPointer(3, GL_FLOAT, 0, &tinf->tvertices[tinfshift]);
|
glTexCoordPointer(3, GL_FLOAT, 0, &tinf->tvertices[tinfshift]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int ed = vid.goteyes ? -1 : 0; ed<2; ed+=2) {
|
for(int ed = stereo::active() ? -1 : 0; ed<2; ed+=2) {
|
||||||
if(ed) selectEyeGL(ed);
|
if(ed) stereo::set_projection(ed), stereo::set_viewport(ed);
|
||||||
bool draw = col;
|
bool draw = col;
|
||||||
again:
|
again:
|
||||||
|
|
||||||
@ -338,7 +336,8 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline
|
|||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glapplymatrix(V);
|
glapplymatrix(V);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if(useV == 2) {
|
if(useV == 2) {
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
@ -348,7 +347,7 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline
|
|||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
0, 0, 0, 1
|
0, 0, 0, 1
|
||||||
};
|
};
|
||||||
mat[8] += ed * vid.eye;
|
// EYETODO mat[8] += ed * vid.eye;
|
||||||
glMultMatrixf(mat);
|
glMultMatrixf(mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,11 +358,11 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline
|
|||||||
1, 0, 0, 0,
|
1, 0, 0, 0,
|
||||||
0, 1, 0, 0,
|
0, 1, 0, 0,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
0, 0, vid.scrdist, 1
|
0, 0, stereo::scrdist, 1
|
||||||
};
|
};
|
||||||
mat[8] += ed * vid.eye;
|
// EYETODO mat[8] += ed * vid.eye;
|
||||||
glMultMatrixf(mat);
|
glMultMatrixf(mat);
|
||||||
}
|
} */
|
||||||
|
|
||||||
if(draw) {
|
if(draw) {
|
||||||
glEnable(GL_STENCIL_TEST);
|
glEnable(GL_STENCIL_TEST);
|
||||||
@ -375,15 +374,15 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline
|
|||||||
glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, ps, pq);
|
glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, ps, pq);
|
||||||
|
|
||||||
if(flags & POLY_INVERSE) {
|
if(flags & POLY_INVERSE) {
|
||||||
selectEyeMask(ed);
|
stereo::set_mask(ed);
|
||||||
glcolor2(col);
|
glcolor2(col);
|
||||||
glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO);
|
glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO);
|
||||||
glStencilFunc( GL_NOTEQUAL, 1, 1);
|
glStencilFunc( GL_NOTEQUAL, 1, 1);
|
||||||
GLfloat xx = vid.xres;
|
GLfloat xx = vid.xres;
|
||||||
GLfloat yy = vid.yres;
|
GLfloat yy = vid.yres;
|
||||||
GLfloat scr[12] = {
|
GLfloat scr[12] = {
|
||||||
-xx, -yy, vid.scrdist, +xx, -yy, vid.scrdist,
|
-xx, -yy, stereo::scrdist, +xx, -yy, stereo::scrdist,
|
||||||
+xx, +yy, vid.scrdist, -xx, +yy, vid.scrdist
|
+xx, +yy, stereo::scrdist, -xx, +yy, stereo::scrdist
|
||||||
};
|
};
|
||||||
GLfloat *cur = currentvertices;
|
GLfloat *cur = currentvertices;
|
||||||
activateVertexArray(scr, 4);
|
activateVertexArray(scr, 4);
|
||||||
@ -393,7 +392,7 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline
|
|||||||
draw = false; goto again;
|
draw = false; goto again;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
selectEyeMask(ed);
|
stereo::set_mask(ed);
|
||||||
glcolor2(col);
|
glcolor2(col);
|
||||||
glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO);
|
glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO);
|
||||||
glStencilFunc( GL_EQUAL, 1, 1);
|
glStencilFunc( GL_EQUAL, 1, 1);
|
||||||
@ -410,6 +409,8 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline
|
|||||||
|
|
||||||
if(useV) glPopMatrix();
|
if(useV) glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(stereo::active()) stereo::set_projection(0), stereo::set_viewport(0), stereo::set_mask(0);
|
||||||
|
|
||||||
if(tinf) {
|
if(tinf) {
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
@ -422,7 +423,7 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline
|
|||||||
double linewidthat(const hyperpoint& h, double minwidth) {
|
double linewidthat(const hyperpoint& h, double minwidth) {
|
||||||
if(vid.antialias & AA_LINEWIDTH) {
|
if(vid.antialias & AA_LINEWIDTH) {
|
||||||
double dz = h[2];
|
double dz = h[2];
|
||||||
if(dz < 1 || abs(dz-vid.scrdist) < 1e-6) return vid.linewidth;
|
if(dz < 1 || abs(dz-stereo::scrdist) < 1e-6) return vid.linewidth;
|
||||||
else {
|
else {
|
||||||
double dx = sqrt(dz * dz - 1);
|
double dx = sqrt(dz * dz - 1);
|
||||||
double dfc = dx/(dz+1);
|
double dfc = dx/(dz+1);
|
||||||
@ -576,7 +577,7 @@ void drawpolyline(polytodraw& p) {
|
|||||||
|
|
||||||
/* pp.outline = 0x80808080;
|
/* pp.outline = 0x80808080;
|
||||||
p.col = 0; */
|
p.col = 0; */
|
||||||
|
|
||||||
addpoly(pp.V, pp.tab, pp.cnt);
|
addpoly(pp.V, pp.tab, pp.cnt);
|
||||||
|
|
||||||
mercator_loop_min = mercator_loop_max = 0;
|
mercator_loop_min = mercator_loop_max = 0;
|
||||||
@ -587,7 +588,7 @@ void drawpolyline(polytodraw& p) {
|
|||||||
|
|
||||||
if(poly_flags & POLY_BEHIND) return;
|
if(poly_flags & POLY_BEHIND) return;
|
||||||
|
|
||||||
for(int i=0; i<qglcoords; i++) {
|
if(0) for(int i=0; i<qglcoords; i++) {
|
||||||
if(abs(glcoords[i][0]) > poly_limit || abs(glcoords[i][1]) > poly_limit)
|
if(abs(glcoords[i][0]) > poly_limit || abs(glcoords[i][1]) > poly_limit)
|
||||||
return; // too large!
|
return; // too large!
|
||||||
}
|
}
|
||||||
@ -604,7 +605,7 @@ void drawpolyline(polytodraw& p) {
|
|||||||
poly_flags ^= POLY_INVERSE;
|
poly_flags ^= POLY_INVERSE;
|
||||||
|
|
||||||
if(poly_flags & POLY_INVERSE) {
|
if(poly_flags & POLY_INVERSE) {
|
||||||
if(curradius < vid.alphax - 1e-6) return;
|
if(curradius < vid.alpha - 1e-6) return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else poly_flags &=~ POLY_INVERSE;
|
else poly_flags &=~ POLY_INVERSE;
|
||||||
@ -629,7 +630,7 @@ void drawpolyline(polytodraw& p) {
|
|||||||
ld a = i * M_PI / 180 + h;
|
ld a = i * M_PI / 180 + h;
|
||||||
glcoords[qglcoords][0] = vid.radius * sin(a);
|
glcoords[qglcoords][0] = vid.radius * sin(a);
|
||||||
glcoords[qglcoords][1] = vid.radius * cos(a);
|
glcoords[qglcoords][1] = vid.radius * cos(a);
|
||||||
glcoords[qglcoords][2] = vid.scrdist;
|
glcoords[qglcoords][2] = stereo::scrdist;
|
||||||
qglcoords++;
|
qglcoords++;
|
||||||
}
|
}
|
||||||
poly_flags ^= POLY_INVERSE;
|
poly_flags ^= POLY_INVERSE;
|
||||||
@ -637,7 +638,7 @@ void drawpolyline(polytodraw& p) {
|
|||||||
|
|
||||||
#if CAP_GL
|
#if CAP_GL
|
||||||
if(vid.usingGL) {
|
if(vid.usingGL) {
|
||||||
// if(pmodel == 0) for(int i=0; i<qglcoords; i++) glcoords[i][2] = vid.scrdist;
|
// if(pmodel == 0) for(int i=0; i<qglcoords; i++) glcoords[i][2] = stereo::scrdist;
|
||||||
if(pp.tinf && (poly_flags & POLY_INVERSE)) {
|
if(pp.tinf && (poly_flags & POLY_INVERSE)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -685,12 +686,12 @@ void drawpolyline(polytodraw& p) {
|
|||||||
else
|
else
|
||||||
filledPolygonColorI(s, polyx, polyy, polyi, p.col);
|
filledPolygonColorI(s, polyx, polyy, polyi, p.col);
|
||||||
|
|
||||||
if(vid.goteyes) filledPolygonColorI(aux, polyxr, polyy, polyi, p.col);
|
if(stereo::active()) filledPolygonColorI(aux, polyxr, polyy, polyi, p.col);
|
||||||
|
|
||||||
// part(pp.outline, 0) = part(pp.outline, 0) * linewidthat(tC0(pp.V), pp.minwidth);
|
// part(pp.outline, 0) = part(pp.outline, 0) * linewidthat(tC0(pp.V), pp.minwidth);
|
||||||
|
|
||||||
((vid.antialias & AA_NOGL) ?aapolylineColor:polylineColor)(s, polyx, polyy, polyi, pp.outline);
|
((vid.antialias & AA_NOGL) ?aapolylineColor:polylineColor)(s, polyx, polyy, polyi, pp.outline);
|
||||||
if(vid.goteyes) aapolylineColor(aux, polyxr, polyy, polyi, pp.outline);
|
if(stereo::active()) aapolylineColor(aux, polyxr, polyy, polyi, pp.outline);
|
||||||
|
|
||||||
if(vid.xres >= 2000 || fatborder) {
|
if(vid.xres >= 2000 || fatborder) {
|
||||||
int xmi = 3000, xma = -3000;
|
int xmi = 3000, xma = -3000;
|
||||||
@ -808,20 +809,6 @@ void drawqueueitem(polytodraw& ptd) {
|
|||||||
#endif
|
#endif
|
||||||
drawCircle(ptd.u.cir.x, ptd.u.cir.y, ptd.u.cir.size, ptd.col);
|
drawCircle(ptd.u.cir.x, ptd.u.cir.y, ptd.u.cir.size, ptd.col);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CAP_SDL
|
|
||||||
if(vid.goteyes && !vid.usingGL) {
|
|
||||||
int qty = s->w * s->h;
|
|
||||||
int *a = (int*) s->pixels;
|
|
||||||
int *b = (int*) aux->pixels;
|
|
||||||
SDL_LockSurface(aux);
|
|
||||||
while(qty) {
|
|
||||||
*a = ((*a) & 0xFF0000) | ((*b) & 0x00FFFF);
|
|
||||||
a++; b++; qty--;
|
|
||||||
}
|
|
||||||
SDL_UnlockSurface(aux);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initquickqueue() {
|
void initquickqueue() {
|
||||||
@ -905,7 +892,7 @@ void drawqueue() {
|
|||||||
profile_stop(3);
|
profile_stop(3);
|
||||||
|
|
||||||
#if CAP_SDL
|
#if CAP_SDL
|
||||||
if(vid.goteyes && !vid.usingGL) {
|
if(stereo::active() && !vid.usingGL) {
|
||||||
|
|
||||||
if(aux && (aux->w != s->w || aux->h != s->h))
|
if(aux && (aux->w != s->w || aux->h != s->h))
|
||||||
SDL_FreeSurface(aux);
|
SDL_FreeSurface(aux);
|
||||||
@ -965,7 +952,30 @@ void drawqueue() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CAP_GL
|
#if CAP_GL
|
||||||
if(vid.goteyes && vid.usingGL) selectEyeGL(0), selectEyeMask(0);
|
if(vid.usingGL)
|
||||||
|
stereo::set_projection(0), stereo::set_mask(0), stereo::set_viewport(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CAP_SDL
|
||||||
|
if(stereo::mode == stereo::sAnaglyph && !vid.usingGL) {
|
||||||
|
int qty = s->w * s->h;
|
||||||
|
int *a = (int*) s->pixels;
|
||||||
|
int *b = (int*) aux->pixels;
|
||||||
|
SDL_LockSurface(aux);
|
||||||
|
while(qty) {
|
||||||
|
*a = ((*a) & 0xFF0000) | ((*b) & 0x00FFFF);
|
||||||
|
a++; b++; qty--;
|
||||||
|
}
|
||||||
|
SDL_UnlockSurface(aux);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stereo::mode == stereo::sLR && !vid.usingGL) {
|
||||||
|
SDL_LockSurface(aux);
|
||||||
|
for(int y=0; y<vid.yres; y++)
|
||||||
|
for(int x=vid.xres/2; x<vid.xres; x++)
|
||||||
|
qpixel(s,x,y) = qpixel(aux,x,y);
|
||||||
|
SDL_UnlockSurface(aux);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
setcameraangle(false);
|
setcameraangle(false);
|
||||||
@ -2707,7 +2717,8 @@ void getcoord0(const hyperpoint& h, int& xc, int &yc, int &sc) {
|
|||||||
applymodel(h, hscr);
|
applymodel(h, hscr);
|
||||||
xc = vid.xcenter + vid.radius * hscr[0];
|
xc = vid.xcenter + vid.radius * hscr[0];
|
||||||
yc = vid.ycenter + vid.radius * hscr[1];
|
yc = vid.ycenter + vid.radius * hscr[1];
|
||||||
sc = vid.eye * vid.radius * hscr[2];
|
sc = 0;
|
||||||
|
// EYETODO sc = vid.eye * vid.radius * hscr[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
void queuechr(const hyperpoint& h, int size, char chr, int col, int frame = 0) {
|
void queuechr(const hyperpoint& h, int size, char chr, int col, int frame = 0) {
|
||||||
|
136
rug.cpp
136
rug.cpp
@ -19,8 +19,6 @@ bool good_shape;
|
|||||||
ld modelscale = 1;
|
ld modelscale = 1;
|
||||||
ld model_distance = 2;
|
ld model_distance = 2;
|
||||||
|
|
||||||
ld fov = 90;
|
|
||||||
|
|
||||||
eGeometry gwhere = gEuclid;
|
eGeometry gwhere = gEuclid;
|
||||||
|
|
||||||
#define USING_NATIVE_GEOMETRY dynamicval<eGeometry> gw(geometry, gwhere == gElliptic ? gSphere : gwhere)
|
#define USING_NATIVE_GEOMETRY dynamicval<eGeometry> gw(geometry, gwhere == gElliptic ? gSphere : gwhere)
|
||||||
@ -55,6 +53,7 @@ struct rugpoint {
|
|||||||
double dist;
|
double dist;
|
||||||
hyperpoint h; // point in the represented space
|
hyperpoint h; // point in the represented space
|
||||||
hyperpoint flat; // point in the native space, in azeq
|
hyperpoint flat; // point in the native space, in azeq
|
||||||
|
hyperpoint precompute;
|
||||||
vector<edge> edges;
|
vector<edge> edges;
|
||||||
// Find-Union algorithm
|
// Find-Union algorithm
|
||||||
rugpoint *glue;
|
rugpoint *glue;
|
||||||
@ -202,7 +201,7 @@ rugpoint *addRugpoint(hyperpoint h, double dist) {
|
|||||||
m->h = h;
|
m->h = h;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ld tz = vid.alphax+h[2];
|
ld tz = vid.alpha+h[2];
|
||||||
m->x1 = (1 + h[0] / tz) / 2;
|
m->x1 = (1 + h[0] / tz) / 2;
|
||||||
m->y1 = (1 + h[1] / tz) / 2;
|
m->y1 = (1 + h[1] / tz) / 2;
|
||||||
*/
|
*/
|
||||||
@ -345,7 +344,7 @@ void setVidParam() {
|
|||||||
vid.xres = vid.yres = TEXTURESIZE;
|
vid.xres = vid.yres = TEXTURESIZE;
|
||||||
vid.scrsize = HTEXTURESIZE;
|
vid.scrsize = HTEXTURESIZE;
|
||||||
vid.radius = vid.scrsize * vid.scale; vid.xcenter = HTEXTURESIZE; vid.ycenter = HTEXTURESIZE;
|
vid.radius = vid.scrsize * vid.scale; vid.xcenter = HTEXTURESIZE; vid.ycenter = HTEXTURESIZE;
|
||||||
vid.beta = 2; vid.alphax = 1; vid.eye = 0; vid.goteyes = false;
|
vid.alpha = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void buildTorusRug() {
|
void buildTorusRug() {
|
||||||
@ -899,11 +898,11 @@ void physics() {
|
|||||||
// drawing the Rug
|
// drawing the Rug
|
||||||
//-----------------
|
//-----------------
|
||||||
|
|
||||||
int eyemod;
|
bool use_precompute;
|
||||||
|
|
||||||
void getco(rugpoint *m, hyperpoint& h, int &spherepoints) {
|
void getco(rugpoint *m, hyperpoint& h, int &spherepoints) {
|
||||||
using namespace hyperpoint_vec;
|
using namespace hyperpoint_vec;
|
||||||
h = m->getglue()->flat;
|
h = use_precompute ? m->getglue()->precompute : m->getglue()->flat;
|
||||||
if(rug_perspective && gwhere >= gSphere) {
|
if(rug_perspective && gwhere >= gSphere) {
|
||||||
if(h[2] > 0) {
|
if(h[2] > 0) {
|
||||||
ld rad = hypot3(h);
|
ld rad = hypot3(h);
|
||||||
@ -916,7 +915,6 @@ void getco(rugpoint *m, hyperpoint& h, int &spherepoints) {
|
|||||||
spherepoints++;
|
spherepoints++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(eyemod) h[0] += eyemod * h[2] * vid.eye;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int besti;
|
extern int besti;
|
||||||
@ -938,7 +936,6 @@ ld raddif(ld a, ld b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ods = false;
|
bool ods = false;
|
||||||
ld ipd = 0.05;
|
|
||||||
|
|
||||||
bool project_ods(hyperpoint azeq, hyperpoint& h1, hyperpoint& h2, bool eye) {
|
bool project_ods(hyperpoint azeq, hyperpoint& h1, hyperpoint& h2, bool eye) {
|
||||||
ld tanalpha = tan(ipd/2);
|
ld tanalpha = tan(ipd/2);
|
||||||
@ -1067,6 +1064,7 @@ void prepareTexture() {
|
|||||||
videopar svid = vid;
|
videopar svid = vid;
|
||||||
|
|
||||||
setVidParam();
|
setVidParam();
|
||||||
|
dynamicval<stereo::eStereo> d(stereo::mode, stereo::sOFF);
|
||||||
|
|
||||||
glbuf->enable();
|
glbuf->enable();
|
||||||
|
|
||||||
@ -1113,12 +1111,6 @@ void drawRugScene() {
|
|||||||
|
|
||||||
glbuf->use_as_texture();
|
glbuf->use_as_texture();
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glLoadIdentity();
|
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glLoadIdentity();
|
|
||||||
|
|
||||||
if(backcolor == 0)
|
if(backcolor == 0)
|
||||||
glClearColor(0.05,0.05,0.05,1);
|
glClearColor(0.05,0.05,0.05,1);
|
||||||
else
|
else
|
||||||
@ -1131,60 +1123,59 @@ void drawRugScene() {
|
|||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthFunc(GL_LESS);
|
glDepthFunc(GL_LESS);
|
||||||
|
|
||||||
ld tanfov = tan(fov * M_PI / 360);
|
for(int ed=stereo::active() && stereo::mode != stereo::sODS ? -1 : 0; ed < 2; ed += 2) {
|
||||||
|
use_precompute = false;
|
||||||
|
stereo::set_mask(ed), stereo::set_viewport(ed);
|
||||||
|
if(ed == 1 && stereo::mode == stereo::sAnaglyph)
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
start_projection(ed);
|
||||||
|
if(stereo::mode == stereo::sODS)
|
||||||
|
glOrtho(-M_PI, M_PI, -M_PI, M_PI, 0, -M_PI * 2);
|
||||||
|
else if(rug_perspective || stereo::active()) {
|
||||||
|
|
||||||
|
ld vnear = .001;
|
||||||
|
ld vfar = 1000;
|
||||||
|
ld sca = vnear * stereo::tanfov / vid.xres;
|
||||||
|
xview = stereo::tanfov;
|
||||||
|
yview = stereo::tanfov * vid.yres / vid.xres;
|
||||||
|
glFrustum(-sca * vid.xres, sca * vid.xres, -sca * vid.yres, sca * vid.yres, vnear, vfar);
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
if(!rug_perspective) glTranslatef(0, 0, -model_distance);
|
||||||
|
if(ed) {
|
||||||
|
if(gwhere == gEuclid)
|
||||||
|
glTranslatef(stereo::ipd*ed/2, 0, 0);
|
||||||
|
else {
|
||||||
|
use_precompute = true;
|
||||||
|
for(auto p: points) {
|
||||||
|
p->precompute = p->flat;
|
||||||
|
push_point(p->precompute, 0, stereo::ipd*ed/2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
xview = stereo::tanfov * model_distance;
|
||||||
|
yview = stereo::tanfov * model_distance * vid.yres / vid.xres;
|
||||||
|
glOrtho(-xview, xview, yview, -yview, -1000, 1000);
|
||||||
|
}
|
||||||
|
glColor4f(1.f, 1.f, 1.f, 1.f);
|
||||||
|
|
||||||
#if CAP_ODS
|
if(rug_perspective && gwhere >= gSphere) {
|
||||||
if(ods) {
|
glEnable(GL_FOG);
|
||||||
glOrtho(-M_PI, M_PI, -M_PI, M_PI, 0, -M_PI * 2);
|
glFogi(GL_FOG_MODE, GL_LINEAR);
|
||||||
}
|
glFogf(GL_FOG_START, 0);
|
||||||
else
|
glFogf(GL_FOG_END, gwhere == gSphere ? 10 : 4);
|
||||||
#endif
|
}
|
||||||
if(rug_perspective) {
|
|
||||||
ld vnear = .001;
|
|
||||||
ld vfar = 1000;
|
|
||||||
ld sca = vnear * tanfov / vid.xres;
|
|
||||||
xview = -tanfov;
|
|
||||||
yview = -tanfov * vid.yres / vid.xres;
|
|
||||||
glFrustum(-sca * vid.xres, sca * vid.xres, -sca * vid.yres, sca * vid.yres, vnear, vfar);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xview = tanfov * model_distance;
|
|
||||||
yview = tanfov * model_distance * vid.yres / vid.xres;
|
|
||||||
|
|
||||||
glOrtho(-xview, xview, -yview, yview, -1000, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
glColor4f(1.f, 1.f, 1.f, 1.f);
|
|
||||||
|
|
||||||
if(rug_perspective && gwhere >= gSphere) {
|
|
||||||
glEnable(GL_FOG);
|
|
||||||
glFogi(GL_FOG_MODE, GL_LINEAR);
|
|
||||||
glFogf(GL_FOG_START, 0);
|
|
||||||
glFogf(GL_FOG_END, gwhere == gSphere ? 10 : 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(vid.eye > .001 || vid.eye < -.001) {
|
|
||||||
selectEyeMask(1);
|
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
|
||||||
glBegin(GL_TRIANGLES);
|
|
||||||
eyemod = 1;
|
|
||||||
for(int t=0; t<size(triangles); t++)
|
|
||||||
drawTriangle(triangles[t]);
|
|
||||||
glEnd();
|
|
||||||
selectEyeMask(-1);
|
|
||||||
eyemod = -1;
|
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
|
||||||
glBegin(GL_TRIANGLES);
|
|
||||||
for(int t=0; t<size(triangles); t++)
|
|
||||||
drawTriangle(triangles[t]);
|
|
||||||
glEnd();
|
|
||||||
selectEyeMask(0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
for(int t=0; t<size(triangles); t++)
|
for(int t=0; t<size(triangles); t++)
|
||||||
drawTriangle(triangles[t]);
|
drawTriangle(triangles[t]);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
|
stereo::set_mask(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
@ -1193,9 +1184,8 @@ void drawRugScene() {
|
|||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glDisable(GL_FOG);
|
glDisable(GL_FOG);
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
stereo::set_mask(0), stereo::set_viewport(0);
|
||||||
glLoadIdentity();
|
stereo::set_projection(0);
|
||||||
selectEyeGL(0);
|
|
||||||
|
|
||||||
need_mouseh = true;
|
need_mouseh = true;
|
||||||
}
|
}
|
||||||
@ -1494,7 +1484,7 @@ void show() {
|
|||||||
dialog::addSelItem(XLAT("model scale factor"), fts(modelscale), 'm');
|
dialog::addSelItem(XLAT("model scale factor"), fts(modelscale), 'm');
|
||||||
if(rug::rugged)
|
if(rug::rugged)
|
||||||
dialog::addSelItem(XLAT("model iterations"), its(queueiter), 0);
|
dialog::addSelItem(XLAT("model iterations"), its(queueiter), 0);
|
||||||
dialog::addSelItem(XLAT("field of view"), fts(fov) + "°", 'f');
|
dialog::addItem(XLAT("stereo vision config"), 'f');
|
||||||
// dialog::addSelItem(XLAT("protractor"), fts(protractor * 180 / M_PI) + "°", 'f');
|
// dialog::addSelItem(XLAT("protractor"), fts(protractor * 180 / M_PI) + "°", 'f');
|
||||||
if(!good_shape) {
|
if(!good_shape) {
|
||||||
dialog::addSelItem(XLAT("maximum error"), ftsg(err_zero), 'e');
|
dialog::addSelItem(XLAT("maximum error"), ftsg(err_zero), 'e');
|
||||||
@ -1591,12 +1581,8 @@ void show() {
|
|||||||
dialog::scaleLog();
|
dialog::scaleLog();
|
||||||
dialog::reaction = [] () { err_zero_current = err_zero; };
|
dialog::reaction = [] () { err_zero_current = err_zero; };
|
||||||
}
|
}
|
||||||
else if(uni == 'f') {
|
else if(uni == 'f')
|
||||||
dialog::editNumber(fov, 1, 170, 1, 45, "field of view",
|
pushScreen(showStereo);
|
||||||
"Horizontal field of view, in the perspective projection. "
|
|
||||||
"In the orthogonal projection this just controls the scale."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if(uni == 'n' && !rug::rugged)
|
else if(uni == 'n' && !rug::rugged)
|
||||||
gwhere = eGeometry((gwhere+1) % 4);
|
gwhere = eGeometry((gwhere+1) % 4);
|
||||||
#if !ISPANDORA
|
#if !ISPANDORA
|
||||||
@ -1648,6 +1634,10 @@ int rugArgs() {
|
|||||||
shift(); vertex_limit = argi();
|
shift(); vertex_limit = argi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(argis("-rugon")) {
|
||||||
|
PHASE(3); rug::init();
|
||||||
|
}
|
||||||
|
|
||||||
#if CAP_ODS
|
#if CAP_ODS
|
||||||
else if(argis("-ods")) {
|
else if(argis("-ods")) {
|
||||||
ods = true;
|
ods = true;
|
||||||
|
@ -1525,7 +1525,7 @@ void movePlayer(monster *m, int delta) {
|
|||||||
hyperpoint jh = hpxy(mdx/100.0, mdy/100.0);
|
hyperpoint jh = hpxy(mdx/100.0, mdy/100.0);
|
||||||
hyperpoint ctr = m->pat * C0;
|
hyperpoint ctr = m->pat * C0;
|
||||||
|
|
||||||
if(sphere && vid.alphax > 1.001) for(int i=0; i<3; i++) ctr[i] = -ctr[i];
|
if(sphere && vid.alpha > 1.001) for(int i=0; i<3; i++) ctr[i] = -ctr[i];
|
||||||
|
|
||||||
hyperpoint h = inverse(m->pat) * rgpushxto0(ctr) * jh;
|
hyperpoint h = inverse(m->pat) * rgpushxto0(ctr) * jh;
|
||||||
|
|
||||||
|
@ -467,7 +467,7 @@ void drawRawTexture() {
|
|||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glcolor2(0xFFFFFF20);
|
glcolor2(0xFFFFFF20);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(0, 0, vid.scrdist);
|
glTranslatef(0, 0, stereo::scrdist);
|
||||||
glBindTexture(GL_TEXTURE_2D, textureid);
|
glBindTexture(GL_TEXTURE_2D, textureid);
|
||||||
vector<GLfloat> tver, sver;
|
vector<GLfloat> tver, sver;
|
||||||
for(int i=0; i<4; i++) {
|
for(int i=0; i<4; i++) {
|
||||||
|
Loading…
Reference in New Issue
Block a user