reworked 3D vision

This commit is contained in:
Zeno Rogue 2018-02-03 13:41:49 +01:00
parent 33ebed2cf3
commit b3f047ea6a
13 changed files with 451 additions and 276 deletions

View File

@ -10,6 +10,29 @@ int utfsize(char c) {
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) {
return *y? *x==*y?eqs(x+1,y+1):false:true;
}
@ -152,36 +175,70 @@ void setcameraangle(bool b) {
}
}
void selectEyeGL(int ed) {
DEBB(DF_GRAPH, (debugfile,"selectEyeGL\n"));
void start_projection(int ed) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glTranslatef((vid.xcenter*2.)/vid.xres - 1, 1 - (vid.ycenter*2.)/vid.yres, 0);
if(pmodel) {
vid.scrdist = 4 * vid.radius;
if(ed) {
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
GLfloat ortho[16] = {
GLfloat(2. / vid.xres), 0, 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};
vid.scrdist = -vid.scrdist;
glMultMatrixf(ortho);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
else {
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);
else if(pmodel) {
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 hidepth = 1e9;
@ -196,20 +253,22 @@ void selectEyeGL(int ed) {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
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};
glMultMatrixf(mat);
if(ve) glTranslatef(ve, 0, vid.eye);
vid.scrdist = vid.yres * sc / 2;
if(ed) glTranslatef(stereo::ipd*ed/2, 0, 0);
stereo::scrdist_text = vid.yres * sc / 2;
}
cameraangle_on = false;
}
void selectEyeMask(int ed) {
if(ed == 0) {
void stereo::set_mask(int ed) {
if(ed == 0 || stereo::mode != stereo::sAnaglyph) {
glColorMask( GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE );
}
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) {
DEBB(DF_GRAPH, (debugfile,"setGLProjection\n"));
@ -261,7 +329,7 @@ void setGLProjection(int col) {
else
glDisable(GL_DEPTH_TEST);
selectEyeGL(0);
stereo::set_projection(0);
}
#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);
markcorner = true;
} */
for(int i=0; s[i];) {
// 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;
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();
glTranslatef(x-ed*shift-vid.xcenter,y-vid.ycenter, vid.scrdist);
selectEyeMask(ed);
glTranslatef(x-ed*shift-vid.xcenter,y-vid.ycenter, stereo::scrdist_text);
stereo::set_mask(ed);
glBindTexture(GL_TEXTURE_2D, f.textures[tabid]);
#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();
}
if(vid.goteyes) selectEyeMask(0);
if(stereo::active() && shift) stereo::set_mask(0);
GLERR("print");
@ -782,7 +850,7 @@ ld realradius() {
ld vradius = vid.radius;
if(sphere) {
if(sphereflipped())
vradius /= sqrt(vid.alphax*vid.alphax - 1);
vradius /= sqrt(vid.alpha*vid.alpha - 1);
else
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;
glcoords[r][0] = x + size * sin(rr);
glcoords[r][1] = y + size * cos(rr);
glcoords[r][2] = vid.scrdist;
glcoords[r][2] = stereo::scrdist;
}
qglcoords = pts;
@ -940,7 +1008,7 @@ void displayColorButton(int x, int y, const string& name, int key, int align, in
}
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;

View File

@ -102,6 +102,9 @@ int arg::readCommon() {
else if(argis("-nofps")) {
nofps = true;
}
else if(argis("-nohud")) {
nohud = true;
}
else if(argis("-back")) {
shift(); backcolor = strtol(args(), NULL, 16);
}
@ -132,6 +135,10 @@ int arg::readCommon() {
shift(); int q = argi();
placeItems(q, i);
}
else if(argis("-SM")) {
PHASE(2);
shift(); stereo::mode = stereo::eStereo(argi());
}
else if(argis("-IU")) {
PHASE(3) cheater++; timerghost = false;
shift(); eItem i = readItem(args());

View File

@ -248,7 +248,6 @@ void initConfig() {
// special graphics
addsaver(vid.eye, "eye distance", 0);
addsaver(vid.ballangle, "ball angle", 20);
addsaver(vid.yshift, "Y shift", 0);
addsaver(vid.camera_angle, "camera angle", 0);
@ -332,6 +331,12 @@ void initConfig() {
addsaver(viewdists, "expansion mode");
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
shmup::initConfig();
@ -437,7 +442,7 @@ void loadOldConfig(FILE *f) {
float a, b, c, d;
err=fscanf(f, "%f%f%f%f\n", &a, &b, &c, &d);
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);
vid.usingGL = gl;
@ -1047,6 +1052,66 @@ string explain3D(ld *param) {
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() {
cmode = sm::SIDE | sm::A3 | sm::MAYDARK;
gamescreen(0);
@ -1072,7 +1137,6 @@ void show3D() {
dialog::addBreak(50);
dialog::addSelItem(XLAT("Y shift"), fts3(vid.yshift), 'y');
dialog::addSelItem(XLAT("camera rotation"), fts3(vid.camera_angle), 's');
dialog::addSelItem(XLAT("distance between eyes"), fts3(vid.eye), 'e');
dialog::addBreak(50);
dialog::addBoolItem(XLAT("ball model"), pmodel == mdBall, 'B');
dialog::addBoolItem(XLAT("hyperboloid model"), pmodel == mdHyperboloid, 'M');
@ -1090,6 +1154,7 @@ void show3D() {
else
dialog::addInfo(XLAT("parameters set correctly"));
dialog::addBreak(50);
dialog::addItem(XLAT("stereo vision config"), 'e');
dialog::addItem(XLAT("exit 3D configuration"), 'v');
dialog::display();
@ -1121,13 +1186,10 @@ void show3D() {
dialog::editNumber(geom3::rock_wall_ratio, 0, 1, .1, .9, XLAT("Rock-III to wall ratio"), "");
else if(uni == 'h')
dialog::editNumber(geom3::human_wall_ratio, 0, 1, .1, .7, XLAT("Human to wall ratio"), "");
else if(uni == 'e')
cmode &= sm::A3,
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."));
pushScreen(showStereo);
else if(uni == 'y')
cmode &= sm::A3,
dialog::editNumber(vid.yshift, 0, 1, .1, 0, XLAT("Y shift"),

View File

@ -96,7 +96,7 @@ namespace polygonal {
hyperpoint h;
h[0] = z2.first * vid.radius;
h[1] = z2.second * vid.radius;
h[2] = vid.scrdist;
h[2] = stereo::scrdist;
curvepoint(h);
}

View File

@ -430,6 +430,9 @@ void fix_mouseh() {
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;
keyhandler(sym, uni);

View File

@ -2209,8 +2209,9 @@ void sumaura(int v) {
void drawaura() {
if(!haveaura()) return;
if(stereo::mode) return;
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(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];
}
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 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);
break;
case laCrossroads:
fcol = (vid.goteyes2 ? 0xFF3030 : 0xFF0000);
fcol = (stereo::in_anaglyph() ? 0xFF3030 : 0xFF0000);
break;
case laCaves: case laEmerald: case laDeadCaves:
fcol = 0x202020;
@ -2704,7 +2705,7 @@ void setcolors(cell *c, int& wcol, int &fcol) {
}
break;
case laJungle:
fcol = (vid.goteyes2 ? 0x408040 : 0x008000);
fcol = (stereo::in_anaglyph() ? 0x408040 : 0x008000);
break;
case laMirror: case laMirrorWall: case laMirrorOld:
fcol = 0x808080;
@ -2719,10 +2720,10 @@ void setcolors(cell *c, int& wcol, int &fcol) {
if(c->wall == waPlatform) wcol = 0xF0F0A0;
break;
case laRlyeh:
fcol = (vid.goteyes2 ? 0x4080C0 : 0x004080);
fcol = (stereo::in_anaglyph() ? 0x4080C0 : 0x004080);
break;
case laHell:
fcol = (vid.goteyes2 ? 0xC03030 : 0xC00000);
fcol = (stereo::in_anaglyph() ? 0xC03030 : 0xC00000);
break;
case laCanvas:
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);
// 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;
if(!detaillevel && aw < 0) return;
@ -5342,12 +5343,13 @@ void calcparam() {
vid.xcenter += vid.scrsize * vid.xposition;
vid.ycenter += vid.scrsize * vid.yposition;
ld eye = vid.eye; if(pmodel || rug::rugged) eye = 0;
vid.beta = 1 + vid.alpha + eye;
vid.alphax = vid.alpha + eye;
vid.goteyes = vid.eye > 0.001 || vid.eye < -0.001;
vid.goteyes2 = vid.goteyes;
vid.scrdist = vid.radius;
stereo::tanfov = tan(stereo::fov * M_PI / 360);
if(pmodel)
stereo::scrdist = vid.xres / 2 / stereo::tanfov;
else
stereo::scrdist = vid.radius;
stereo::scrdist_text = stereo::scrdist;
}
int ringcolor = darkena(0xFF, 0, 0xFF);
@ -5360,19 +5362,19 @@ void drawfullmap() {
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;
if(sphere) {
if(mdEqui())
;
else if(!vid.grid && !elliptic)
rad = 0;
else if(vid.alphax <= 0)
else if(vid.alpha <= 0)
;
else if(vid.alphax <= 1 && (vid.grid || elliptic)) // mark the equator
rad = rad * 1 / vid.alphax;
else if(vid.alpha <= 1 && (vid.grid || elliptic)) // mark the equator
rad = rad * 1 / vid.alpha;
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,
vid.usingGL ? PPR_CIRCLE : PPR_OUTCIRCLE);

131
hud.cpp
View File

@ -332,8 +332,9 @@ bool nofps = false;
void drawStats() {
callhandlers(false, hooks_prestats);
#if CAP_ROGUEVIZ
if(rogueviz::on || nohud) return;
if(rogueviz::on) return;
#endif
if(nohud || stereo::mode == stereo::sLR) return;
if(viewdists && sidescreen) {
distcolors[0] = forecolor;
dialog::init("");
@ -375,11 +376,11 @@ void drawStats() {
{
dynamicval<eModel> pm(pmodel, mdDisk);
dynamicval<ld> va(vid.alpha, 1);
dynamicval<ld> vax(vid.alphax, 1);
dynamicval<ld> vax(vid.alpha, 1);
dynamicval<videopar> v(vid, vid);
calcparam();
#if CAP_GL
selectEyeGL(0);
stereo::set_projection(0);
#endif
if(haveMobileCompass()) {
@ -436,69 +437,77 @@ void drawStats() {
}
}
}
return;
}
instat = false;
bool portrait = vid.xres < vid.yres;
int colspace = portrait ? (vid.yres - vid.xres - vid.fsize*3) : (vid.xres - vid.yres - 16) / 2;
int rowspace = portrait ? vid.xres - 16 : vid.yres - vid.fsize * (vid.msgleft ? 9 : 4);
int colid[4], rowid[4];
int maxbyclass[4];
for(int z=0; z<4; z++) maxbyclass[z] = 0;
for(int i=0; i<glyphs; i++) if(ikappear(i))
if(!portrait || (glyphflags(i) | GLYPH_INPORTRAIT))
maxbyclass[glyphclass(i)]++;
int buttonsize;
int columns, rows;
bool imponly = false;
int minsize = vid.fsize * (portrait ? 4 : 2);
rows = 0;
while((buttonsize = minsize - vid.killreduction)) {
columns = colspace / buttonsize;
rows = rowspace / buttonsize;
int coltaken = 0;
for(int z=0; z<4; z++) {
if(z == 2 && !portrait) {
if(coltaken > columns) { vid.killreduction++; continue; }
coltaken = 0;
else {
instat = false;
bool portrait = vid.xres < vid.yres;
int colspace = portrait ? (vid.yres - vid.xres - vid.fsize*3) : (vid.xres - vid.yres - 16) / 2;
int rowspace = portrait ? vid.xres - 16 : vid.yres - vid.fsize * (vid.msgleft ? 9 : 4);
int colid[4], rowid[4];
int maxbyclass[4];
for(int z=0; z<4; z++) maxbyclass[z] = 0;
for(int i=0; i<glyphs; i++) if(ikappear(i))
if(!portrait || (glyphflags(i) | GLYPH_INPORTRAIT))
maxbyclass[glyphclass(i)]++;
int buttonsize;
int columns, rows;
bool imponly = false;
int minsize = vid.fsize * (portrait ? 4 : 2);
rows = 0;
while((buttonsize = minsize - vid.killreduction)) {
columns = colspace / buttonsize;
rows = rowspace / buttonsize;
int coltaken = 0;
for(int z=0; z<4; z++) {
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,
coltaken += (maxbyclass[z] + rows-1) / rows;
if(coltaken > columns) { vid.killreduction++; continue; }
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();
stable_sort(glyphorder, glyphorder+glyphs, glyphsort);
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();
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 i = glyphorder[i0];
if(!ikappear(i)) continue;
int z = glyphclass(i);
int imp = glyphflags(i);
if(imponly) { z &=~1; if(!(imp & GLYPH_IMPORTANT)) continue; }
int cx, cy;
if(portrait)
cx = 8 + buttonsize * rowid[z], cy = vid.fsize*2 + buttonsize * (colid[z]) + buttonsize/2;
else
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);
int cx, cy;
if(portrait)
cx = 8 + buttonsize * rowid[z], cy = vid.fsize*2 + buttonsize * (colid[z]) + buttonsize/2;
else
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;
if(!peace::on) {
if(displayButtonS(vid.xres - 8, vid.fsize, XLAT("score: %1", its(gold())), forecolor, 16, vid.fsize)) {
@ -554,10 +563,4 @@ XLAT(
callhooks(hooks_stats);
}
calcparam();
#if CAP_GL
selectEyeGL(0);
#endif
}

31
hyper.h
View File

@ -587,14 +587,13 @@ extern reaction_t help_delegate;
#define HELPFUN(x) (help_delegate = x, "HELPFUN")
struct videopar {
ld scale, eye, alpha, sspeed, mspeed, yshift, camera_angle;
ld scale, alpha, sspeed, mspeed, yshift, camera_angle;
ld ballangle, ballproj;
int mobilecompasssize;
int aurastr, aurasmoothen;
bool full;
bool goteyes; // for rendering
bool goteyes2; // for choosing colors
int graphglyph; // graphical glyphs
bool darkhepta;
int shifttarget;
@ -609,7 +608,6 @@ struct videopar {
int xcenter, ycenter;
int radius;
int scrsize;
ld alphax, beta;
bool grid;
int particles;
@ -622,9 +620,6 @@ struct videopar {
int msgleft, msglimit;
// for OpenGL
float scrdist;
bool usingGL;
int antialias;
#define AA_NOGL 1
@ -2536,3 +2531,25 @@ struct renderbuffer {
void use_as_texture();
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();

View File

@ -26,7 +26,7 @@ hyperpoint gethyper(ld x, ld y) {
}
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);
@ -45,8 +45,8 @@ hyperpoint gethyper(ld x, ld y) {
ld curv = sphere ? 1 : -1;
A = 1+curv*hr;
B = 2*hr*vid.alphax*-curv;
C = 1 - curv*hr*vid.alphax*vid.alphax;
B = 2*hr*vid.alpha*-curv;
C = 1 - curv*hr*vid.alpha*vid.alpha;
// Az^2 - Bz = C
B /= A; C /= A;
@ -56,13 +56,13 @@ hyperpoint gethyper(ld x, ld y) {
// z = (B/2) + sqrt(C + B^2/4)
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);
hyperpoint H;
H[0] = hx * (hz+vid.alphax);
H[1] = hy * (hz+vid.alphax);
H[0] = hx * (hz+vid.alpha);
H[1] = hy * (hz+vid.alpha);
H[2] = hz;
return H;
@ -83,9 +83,21 @@ void ballmodel(hyperpoint& ret, double alpha, double d, double zl) {
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) {
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(pmodel == mdUnchanged) {
@ -124,9 +136,9 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
if(pmodel == mdDisk) {
if(!vid.camera_angle) {
ret[0] = H[0] / tz;
ret[0] = H[0] / 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 {
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;
ret[0] = ux / 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;
}
@ -164,14 +176,14 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
ret[0] = d * H[0] / rad / M_PI;
ret[1] = d * H[1] / rad / M_PI;
ret[2] = 0;
if(zlev != 1 && vid.goteyes)
ret[2] = geom3::factor_to_lev(zlev);
if(zlev != 1 && stereo::active())
apply_depth(ret, -geom3::factor_to_lev(zlev));
ghcheck(ret,H);
return;
}
tz = H[2]+vid.alphax;
tz = H[2]+vid.alpha;
if(pmodel == mdPolygonal || pmodel == mdPolynomial) {
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;
ret[1] = 1 - y0;
ret[2] = 0;
if(zlev != 1 && vid.goteyes)
ret[2] = y0 * geom3::factor_to_lev(zlev);
if(zlev != 1 && stereo::active())
apply_depth(ret, -y0 * geom3::factor_to_lev(zlev));
ghcheck(ret,H);
return;
}
@ -229,8 +241,8 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
ret[1] = -y0/M_PI*2;
ret[2] = 0;
if(zlev != 1 && vid.goteyes)
ret[2] = geom3::factor_to_lev(zlev) / (1 + yv * yv);
if(zlev != 1 && stereo::active())
apply_depth(ret, -geom3::factor_to_lev(zlev) / (1 + yv * yv));
ghcheck(ret,H);
}
@ -442,7 +454,7 @@ void drawEuclidean() {
transmatrix View0 = View;
ld cellrad = vid.radius / (EUCSCALE + vid.alphax);
ld cellrad = vid.radius / (EUCSCALE + vid.alpha);
ld centerd = matrixnorm(View0);
@ -613,8 +625,8 @@ void fullcenter() {
transmatrix screenpos(ld x, ld y) {
transmatrix V = Id;
V[0][2] += (x - vid.xcenter) / vid.radius * (1+vid.alphax);
V[1][2] += (y - vid.ycenter) / 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.alpha);
return V;
}
@ -625,7 +637,7 @@ transmatrix atscreenpos(ld x, ld y, ld size) {
V[1][2] += (y - vid.ycenter);
V[0][0] = 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;
return V;

View File

@ -184,13 +184,13 @@ void addpoint(const hyperpoint& H) {
if(qglcoords >= POLYMAX) return;
if(true) {
hyperpoint Hscr;
hyperpoint 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) {
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;
else {
@ -198,7 +198,7 @@ void addpoint(const hyperpoint& H) {
(sqrt(curnorm - horizon*horizon) / (vid.alpha - horizon)) /
(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[1] *= coef;
}
@ -218,13 +218,11 @@ void addpoint(const hyperpoint& H) {
void coords_to_poly() {
polyi = qglcoords;
for(int i=0; i<polyi; i++) {
// 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];
ld xe = glcoords[i][2] * vid.eye;
polyx[i] = x-xe;
polyxr[i] = x+xe;
polyy[i] = y;
// printf("%lf %lf\n", double(glcoords[i][0]), double(glcoords[i][1]));
polyx[i] = vid.xcenter + glcoords[i][0] - glcoords[i][2];
polyxr[i] = vid.xcenter + glcoords[i][0] + glcoords[i][2];
polyy[i] = vid.ycenter + glcoords[i][1];
}
}
@ -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) {
if(tinf) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tinf->texture_id);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(3, GL_FLOAT, 0, &tinf->tvertices[tinfshift]);
}
for(int ed = vid.goteyes ? -1 : 0; ed<2; ed+=2) {
if(ed) selectEyeGL(ed);
if(tinf) {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tinf->texture_id);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(3, GL_FLOAT, 0, &tinf->tvertices[tinfshift]);
}
for(int ed = stereo::active() ? -1 : 0; ed<2; ed+=2) {
if(ed) stereo::set_projection(ed), stereo::set_viewport(ed);
bool draw = col;
again:
@ -338,7 +336,8 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline
glPushMatrix();
glapplymatrix(V);
}
/*
if(useV == 2) {
glMatrixMode(GL_MODELVIEW);
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, 0, 1
};
mat[8] += ed * vid.eye;
// EYETODO mat[8] += ed * vid.eye;
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,
0, 1, 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);
}
} */
if(draw) {
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);
if(flags & POLY_INVERSE) {
selectEyeMask(ed);
stereo::set_mask(ed);
glcolor2(col);
glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO);
glStencilFunc( GL_NOTEQUAL, 1, 1);
GLfloat xx = vid.xres;
GLfloat yy = vid.yres;
GLfloat scr[12] = {
-xx, -yy, vid.scrdist, +xx, -yy, vid.scrdist,
+xx, +yy, vid.scrdist, -xx, +yy, vid.scrdist
-xx, -yy, stereo::scrdist, +xx, -yy, stereo::scrdist,
+xx, +yy, stereo::scrdist, -xx, +yy, stereo::scrdist
};
GLfloat *cur = currentvertices;
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;
}
else {
selectEyeMask(ed);
stereo::set_mask(ed);
glcolor2(col);
glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO);
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(stereo::active()) stereo::set_projection(0), stereo::set_viewport(0), stereo::set_mask(0);
if(tinf) {
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) {
if(vid.antialias & AA_LINEWIDTH) {
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 {
double dx = sqrt(dz * dz - 1);
double dfc = dx/(dz+1);
@ -576,7 +577,7 @@ void drawpolyline(polytodraw& p) {
/* pp.outline = 0x80808080;
p.col = 0; */
addpoly(pp.V, pp.tab, pp.cnt);
mercator_loop_min = mercator_loop_max = 0;
@ -587,7 +588,7 @@ void drawpolyline(polytodraw& p) {
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)
return; // too large!
}
@ -604,7 +605,7 @@ void drawpolyline(polytodraw& p) {
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;
@ -629,7 +630,7 @@ void drawpolyline(polytodraw& p) {
ld a = i * M_PI / 180 + h;
glcoords[qglcoords][0] = vid.radius * sin(a);
glcoords[qglcoords][1] = vid.radius * cos(a);
glcoords[qglcoords][2] = vid.scrdist;
glcoords[qglcoords][2] = stereo::scrdist;
qglcoords++;
}
poly_flags ^= POLY_INVERSE;
@ -637,7 +638,7 @@ void drawpolyline(polytodraw& p) {
#if CAP_GL
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)) {
return;
}
@ -685,12 +686,12 @@ void drawpolyline(polytodraw& p) {
else
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);
((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) {
int xmi = 3000, xma = -3000;
@ -808,20 +809,6 @@ void drawqueueitem(polytodraw& ptd) {
#endif
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() {
@ -905,7 +892,7 @@ void drawqueue() {
profile_stop(3);
#if CAP_SDL
if(vid.goteyes && !vid.usingGL) {
if(stereo::active() && !vid.usingGL) {
if(aux && (aux->w != s->w || aux->h != s->h))
SDL_FreeSurface(aux);
@ -965,7 +952,30 @@ void drawqueue() {
}
#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
setcameraangle(false);
@ -2707,7 +2717,8 @@ void getcoord0(const hyperpoint& h, int& xc, int &yc, int &sc) {
applymodel(h, hscr);
xc = vid.xcenter + vid.radius * hscr[0];
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) {

136
rug.cpp
View File

@ -19,8 +19,6 @@ bool good_shape;
ld modelscale = 1;
ld model_distance = 2;
ld fov = 90;
eGeometry gwhere = gEuclid;
#define USING_NATIVE_GEOMETRY dynamicval<eGeometry> gw(geometry, gwhere == gElliptic ? gSphere : gwhere)
@ -55,6 +53,7 @@ struct rugpoint {
double dist;
hyperpoint h; // point in the represented space
hyperpoint flat; // point in the native space, in azeq
hyperpoint precompute;
vector<edge> edges;
// Find-Union algorithm
rugpoint *glue;
@ -202,7 +201,7 @@ rugpoint *addRugpoint(hyperpoint h, double dist) {
m->h = h;
/*
ld tz = vid.alphax+h[2];
ld tz = vid.alpha+h[2];
m->x1 = (1 + h[0] / tz) / 2;
m->y1 = (1 + h[1] / tz) / 2;
*/
@ -345,7 +344,7 @@ void setVidParam() {
vid.xres = vid.yres = TEXTURESIZE;
vid.scrsize = 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() {
@ -899,11 +898,11 @@ void physics() {
// drawing the Rug
//-----------------
int eyemod;
bool use_precompute;
void getco(rugpoint *m, hyperpoint& h, int &spherepoints) {
using namespace hyperpoint_vec;
h = m->getglue()->flat;
h = use_precompute ? m->getglue()->precompute : m->getglue()->flat;
if(rug_perspective && gwhere >= gSphere) {
if(h[2] > 0) {
ld rad = hypot3(h);
@ -916,7 +915,6 @@ void getco(rugpoint *m, hyperpoint& h, int &spherepoints) {
spherepoints++;
}
}
if(eyemod) h[0] += eyemod * h[2] * vid.eye;
}
extern int besti;
@ -938,7 +936,6 @@ ld raddif(ld a, ld b) {
}
bool ods = false;
ld ipd = 0.05;
bool project_ods(hyperpoint azeq, hyperpoint& h1, hyperpoint& h2, bool eye) {
ld tanalpha = tan(ipd/2);
@ -1067,6 +1064,7 @@ void prepareTexture() {
videopar svid = vid;
setVidParam();
dynamicval<stereo::eStereo> d(stereo::mode, stereo::sOFF);
glbuf->enable();
@ -1113,12 +1111,6 @@ void drawRugScene() {
glbuf->use_as_texture();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(backcolor == 0)
glClearColor(0.05,0.05,0.05,1);
else
@ -1131,60 +1123,59 @@ void drawRugScene() {
glEnable(GL_DEPTH_TEST);
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(ods) {
glOrtho(-M_PI, M_PI, -M_PI, M_PI, 0, -M_PI * 2);
}
else
#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 {
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);
}
glBegin(GL_TRIANGLES);
for(int t=0; t<size(triangles); t++)
drawTriangle(triangles[t]);
glEnd();
stereo::set_mask(0);
}
glDisable(GL_TEXTURE_2D);
@ -1193,9 +1184,8 @@ void drawRugScene() {
glEnable(GL_BLEND);
glDisable(GL_FOG);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
selectEyeGL(0);
stereo::set_mask(0), stereo::set_viewport(0);
stereo::set_projection(0);
need_mouseh = true;
}
@ -1494,7 +1484,7 @@ void show() {
dialog::addSelItem(XLAT("model scale factor"), fts(modelscale), 'm');
if(rug::rugged)
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');
if(!good_shape) {
dialog::addSelItem(XLAT("maximum error"), ftsg(err_zero), 'e');
@ -1591,12 +1581,8 @@ void show() {
dialog::scaleLog();
dialog::reaction = [] () { err_zero_current = err_zero; };
}
else if(uni == 'f') {
dialog::editNumber(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(uni == 'f')
pushScreen(showStereo);
else if(uni == 'n' && !rug::rugged)
gwhere = eGeometry((gwhere+1) % 4);
#if !ISPANDORA
@ -1648,6 +1634,10 @@ int rugArgs() {
shift(); vertex_limit = argi();
}
else if(argis("-rugon")) {
PHASE(3); rug::init();
}
#if CAP_ODS
else if(argis("-ods")) {
ods = true;

View File

@ -1525,7 +1525,7 @@ void movePlayer(monster *m, int delta) {
hyperpoint jh = hpxy(mdx/100.0, mdy/100.0);
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;

View File

@ -467,7 +467,7 @@ void drawRawTexture() {
glMatrixMode(GL_MODELVIEW);
glcolor2(0xFFFFFF20);
glPushMatrix();
glTranslatef(0, 0, vid.scrdist);
glTranslatef(0, 0, stereo::scrdist);
glBindTexture(GL_TEXTURE_2D, textureid);
vector<GLfloat> tver, sver;
for(int i=0; i<4; i++) {