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
116
basegraph.cpp
116
basegraph.cpp
@ -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;
|
||||
|
||||
@ -199,17 +256,19 @@ void selectEyeGL(int ed) {
|
||||
|
||||
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
|
||||
@ -489,10 +557,10 @@ bool gl_print(int x, int y, int shift, int size, const char *s, int color, int a
|
||||
|
||||
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;
|
||||
|
@ -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());
|
||||
|
76
config.cpp
76
config.cpp
@ -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);
|
||||
@ -333,6 +332,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();
|
||||
#endif
|
||||
@ -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();
|
||||
|
||||
@ -1123,10 +1188,7 @@ void show3D() {
|
||||
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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
38
graph.cpp
38
graph.cpp
@ -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);
|
||||
|
133
hud.cpp
133
hud.cpp
@ -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,68 +437,76 @@ 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(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; }
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
calcparam();
|
||||
#if CAP_GL
|
||||
stereo::set_projection(0);
|
||||
#endif
|
||||
|
||||
string s0;
|
||||
if(!peace::on) {
|
||||
@ -555,9 +564,3 @@ XLAT(
|
||||
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")
|
||||
|
||||
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();
|
||||
|
||||
|
52
hypgraph.cpp
52
hypgraph.cpp
@ -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) {
|
||||
@ -126,7 +138,7 @@ void applymodel(hyperpoint H, hyperpoint& ret) {
|
||||
if(!vid.camera_angle) {
|
||||
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;
|
||||
|
111
polygons.cpp
111
polygons.cpp
@ -186,11 +186,11 @@ void addpoint(const hyperpoint& H) {
|
||||
if(true) {
|
||||
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]);
|
||||
}
|
||||
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);
|
||||
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:
|
||||
|
||||
@ -339,6 +337,7 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline
|
||||
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);
|
||||
@ -411,6 +410,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);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
@ -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);
|
||||
@ -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) {
|
||||
|
128
rug.cpp
128
rug.cpp
@ -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);
|
||||
|
||||
#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;
|
||||
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()) {
|
||||
|
||||
glOrtho(-xview, xview, -yview, yview, -1000, 1000);
|
||||
}
|
||||
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);
|
||||
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f);
|
||||
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(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(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);
|
||||
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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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++) {
|
||||
|
Loading…
Reference in New Issue
Block a user