5910 lines
134 KiB
C++
5910 lines
134 KiB
C++
/*
|
|
* (c) 2002-2016 Hannes Krueger
|
|
* This file is part of the GPLIGC/ogie package
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
*
|
|
*/
|
|
|
|
/*
|
|
if compiled with -DWITH_OSMESA, the mesa offscreen rendering is included
|
|
-> changed to autoconf -> HAVE_LIBOSMESA
|
|
if compiled with -DONLY_OSMESA, only osmesa will work. all interactive
|
|
features will be disabled, and therefore no GLUT or X11 is needed.
|
|
--> however for text some glut functions are used....
|
|
*/
|
|
|
|
// all platforms include gl.h (except OSX)
|
|
#ifndef __OSX__
|
|
#include <GL/gl.h>
|
|
// glut not needed for ONLY_OSMESA
|
|
// actually ONLY_OSMESA shouldnt be used any longer
|
|
// #ifndef ONLY_OSMESA
|
|
#include <GL/glut.h>
|
|
#include <GL/glu.h>
|
|
// #endif
|
|
|
|
#else
|
|
|
|
// OSX here....
|
|
// #ifndef ONLY_OSMESA
|
|
#include <GLUT/glut.h>
|
|
// #endif
|
|
#include <OpenGL/gl.h>
|
|
#define __MACOSX__
|
|
#endif
|
|
|
|
|
|
#ifdef FREEGLUT
|
|
#include <GL/freeglut_ext.h>
|
|
#endif
|
|
|
|
#ifndef GLUT_VERSION
|
|
// this is the value from GL/freeglut_ext.h. If we dont have freeglut, we need to define it here
|
|
#define GLUT_VERSION 0x01FC
|
|
#endif
|
|
|
|
|
|
#include "oconfig.h"
|
|
#include "config.h"
|
|
|
|
#ifdef HAVE_LIBOSMESA
|
|
//#include <GL/glu.h>
|
|
#include <GL/osmesa.h>
|
|
//#include "osmesa.h"
|
|
#endif
|
|
|
|
#ifndef __WIN32__
|
|
#ifndef __OSX__
|
|
// #ifndef ONLY_OSMESA
|
|
#include <GL/glx.h>
|
|
// #endif
|
|
#endif
|
|
#endif
|
|
|
|
// just for version info
|
|
#ifdef HAVE_LIBGPS
|
|
#include "libgpsmm.h"
|
|
#endif
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <cmath>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <unistd.h>
|
|
|
|
#include <jpeglib.h>
|
|
|
|
// do we need this ?
|
|
#ifndef __WIN32__
|
|
#include <csignal>
|
|
#include <sys/ipc.h>
|
|
#include <sys/shm.h>
|
|
#endif
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "GLexplorer.h"
|
|
#include "flightdata.h"
|
|
#include "ego.h"
|
|
#include "landscape.h"
|
|
|
|
#include "cmdline.h"
|
|
#include "map.h"
|
|
#include "oglexfunc.h"
|
|
#include "airspc.h"
|
|
#include "projection.h"
|
|
//#include "sysinfo.h"
|
|
#include "points.h"
|
|
|
|
|
|
// windows hasn't GLX and Mesa
|
|
#ifdef __WIN32__
|
|
#define NOGLX
|
|
//#include <strings.h>
|
|
//#undef WITH_OSMESA
|
|
#endif
|
|
|
|
// #ifdef __OSX__
|
|
// #define NOGLX
|
|
// #undef WITH_OSMESA
|
|
// #endif
|
|
|
|
// configure hasn't found glXCreatePbuffer
|
|
#ifndef HAVE_GLXPBUFFER
|
|
#define NOGLX
|
|
#endif
|
|
|
|
// no unix, no GLX, Mesa
|
|
#ifndef __unix__
|
|
#define NOGLX
|
|
//#undef WITH_MESA
|
|
#endif
|
|
|
|
#ifndef M_PI
|
|
#define M_PI 3.141592654
|
|
#endif
|
|
|
|
|
|
using namespace std;
|
|
|
|
//const string rcsid_GLexplorer_cpp =
|
|
// "$Id: GLexplorer.cpp 3 2014-07-31 09:59:20Z kruegerh $";
|
|
//const string rcsid_GLexplorer_h = GLEXPLORER_H;
|
|
|
|
//Global stuff
|
|
Flightdata fd; //flightdata object
|
|
//needs to be global! (see keyPressed callback function...)
|
|
|
|
Airspace air; //airspaces....
|
|
|
|
Projection proj; //projection
|
|
|
|
Points lifts;
|
|
Points waypoints;
|
|
|
|
gengetopt_args_info args_info;
|
|
gpligc_ipc_block ipc_block;
|
|
|
|
Ego ego(0, 0, 0, 0, 0, 0); //initialize ego
|
|
GLuint flightdata_displ_list; //the display_lists
|
|
GLuint landscape_displ_list; //
|
|
GLuint airspace_displ_list;
|
|
//GLuint lifts_displ_list;
|
|
|
|
Config conf; //configuration stuff (initialized with compiled-in defaults, see constructor)
|
|
// defaults can be overridden by 1. configfile and 2.cmdline
|
|
|
|
int lastmx = 0; //last mouseposition
|
|
int lastmy = 0;
|
|
|
|
int rightbuttonstate = GLUT_UP;
|
|
int middlebuttonstate = GLUT_UP;
|
|
int leftbuttonstate = GLUT_UP;
|
|
//bool cntrlstate = false;
|
|
|
|
|
|
bool MENUPOPPED = false; //menu hasnt popped or disappeared soon.
|
|
bool MENUCHANGED = false; //menu has to be changed!
|
|
bool MENUSTATE = false;
|
|
|
|
bool HELP = false; //flag for help-display
|
|
bool INFO = false; // flag for info-display
|
|
|
|
bool MOUSEWARPED = false; // Mouse warped indicator. Will be set when the mouse pointer
|
|
// is forcefully re-centered by the program.
|
|
|
|
/*
|
|
bool SHIFTKEY = false;
|
|
bool CNTRLKEY = false;
|
|
bool ALTKEY = false;
|
|
*/
|
|
|
|
int window = -3992; // GLUT window number (3992 to check if its changed (=window created))
|
|
|
|
vector<float>fps(10); // used to smooth framerate
|
|
|
|
|
|
int movie_repeat_counter=0;
|
|
|
|
|
|
#ifndef __WIN32__
|
|
#ifndef ONLY_OSMESA
|
|
// GPLIGC communication... if SIGUSR1 received, reread shared mem block
|
|
void SIGUSR1Handler(int sig)
|
|
{
|
|
if (sig == SIGUSR1) {
|
|
int shm_id;
|
|
key_t key;
|
|
key = ftok(conf.getIGCFileName().c_str(), 76);
|
|
//cout << "key : " << key << endl;
|
|
shm_id = shmget(key, sizeof(gpligc_ipc_block), 0);
|
|
|
|
if (shm_id != -1) {
|
|
char *data;
|
|
char *data_dest;
|
|
data_dest = (char *) &ipc_block;
|
|
data = (char *) shmat(shm_id, (void *) 0, 0);
|
|
|
|
//copy shm segment to the ipc_block struct... (low-level)
|
|
for (int _z = 0;
|
|
_z < (int) sizeof(gpligc_ipc_block); _z++) {
|
|
data_dest[_z] = data[_z];
|
|
}
|
|
shmdt(data);
|
|
|
|
//cout << "Inhalt: " << ipc_block.marker_pos << endl;
|
|
fd.setmarkerpos(ipc_block.marker_pos);
|
|
if (conf.FOLLOW.get()) {
|
|
update_locked_pos();
|
|
}
|
|
if (conf.MARKER_RANGE.get()) {
|
|
GenFlightList();
|
|
}
|
|
}
|
|
|
|
/*
|
|
if (conf.VERBOSE.get()) {
|
|
cout << "SIGUSR1 received... Size of shared mem block:"
|
|
<< sizeof(gpligc_ipc_block) << " shmid:"<< shm_id <<endl;
|
|
}
|
|
*/
|
|
glutPostRedisplay();
|
|
}
|
|
}
|
|
|
|
void update_shmem(void) {
|
|
|
|
ipc_block.marker_pos = fd.getmarker();
|
|
|
|
//cout << "openGLIGCexplorer: " << fd.getmarker();
|
|
|
|
int shm_id;
|
|
key_t key;
|
|
key = ftok(conf.getIGCFileName().c_str(), 76);
|
|
//cout << "key : " << key << endl;
|
|
shm_id = shmget(key, sizeof(gpligc_ipc_block), 0);
|
|
|
|
if (shm_id != -1) {
|
|
char *data;
|
|
char *data_src;
|
|
data_src = (char *) &ipc_block;
|
|
data = (char *) shmat(shm_id, (void *) 0, 0);
|
|
|
|
//copy the ipc_block struct to shm-segment... (low-level)
|
|
for (int _z = 0;
|
|
_z < (int) sizeof(gpligc_ipc_block); _z++) {
|
|
data[_z] = data_src[_z];
|
|
}
|
|
shmdt(data);
|
|
}
|
|
|
|
//cout << "update_shmem called... sending SIGUSR2 to GPLIGC" << endl;
|
|
|
|
// this is now deactivated....
|
|
|
|
//if (args_info.parent_pid_given) {
|
|
// kill(args_info.parent_pid_arg, SIGUSR2);
|
|
//}
|
|
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef ONLY_OSMESA
|
|
int menIdMain, menIdMapSet, menIdStereo, menIdColormap, menIdColormap_sea,
|
|
menIdFSColormap, menIdFSMode, menIdAirspaceType;
|
|
|
|
void menuMain(int val)
|
|
{
|
|
|
|
// this is needed for glutChangeToMenuEntry (which is done in current menu),
|
|
// if this is called from keypressed function and current menu is other than menuMain
|
|
// glutSetMenu(menIdMain); // we dont changeToMenuEntry any more, here
|
|
|
|
MENUPOPPED=true;
|
|
|
|
switch (val) {
|
|
|
|
case 1:
|
|
conf.MAP.toggle();
|
|
GenLandscapeList();
|
|
GenFlightList(); //?
|
|
glutPostRedisplay();
|
|
|
|
MENUCHANGED= true;
|
|
// if (conf.MAP.get()) {
|
|
// glutChangeToMenuEntry(1, "Maps off", 1);
|
|
// } else {
|
|
// glutChangeToMenuEntry(1, "Maps on", 1);
|
|
// }
|
|
|
|
|
|
break;
|
|
|
|
case 2:
|
|
conf.MODULATE.toggle();
|
|
|
|
if (conf.MAP.get()) {
|
|
GenLandscapeList();
|
|
glutPostRedisplay();
|
|
}
|
|
MENUCHANGED= true;
|
|
|
|
// if (conf.MODULATE.get()) {
|
|
// glutChangeToMenuEntry(2, "Colored maps off", 2);
|
|
// } else {
|
|
// glutChangeToMenuEntry(2, "Colored maps on", 2);
|
|
// }
|
|
|
|
|
|
break;
|
|
|
|
case 11:
|
|
if (conf.DEM.get()) {
|
|
conf.LANDSCAPE.toggle();
|
|
GenFlightList();
|
|
GenLandscapeList();
|
|
glutPostRedisplay();
|
|
}
|
|
MENUCHANGED= true;
|
|
|
|
// if (conf.LANDSCAPE.get()) {
|
|
// glutChangeToMenuEntry(5, "Terrain off", 11);
|
|
// } else {
|
|
// glutChangeToMenuEntry(5, "Terrain on", 11);
|
|
// }
|
|
|
|
break;
|
|
|
|
case 12:
|
|
conf.FOG.toggle();
|
|
//GenFlightList();
|
|
InitGL(conf.getwidth(), conf.getheight());
|
|
glutPostRedisplay();
|
|
MENUCHANGED= true;
|
|
|
|
// if (conf.FOG.get()) {
|
|
// glutChangeToMenuEntry(8, "Haze off", 12);
|
|
// } else {
|
|
// glutChangeToMenuEntry(8, "Haze on", 12);
|
|
// }
|
|
|
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
if (conf.getAirspaceFileName() != "not available") {
|
|
conf.AIRSPACE.toggle();
|
|
GenAirspaceList();
|
|
glutPostRedisplay();
|
|
}
|
|
MENUCHANGED= true;
|
|
|
|
// if (conf.AIRSPACE.get()) {
|
|
// glutChangeToMenuEntry(9, "Airspace off", 13);
|
|
// } else {
|
|
// glutChangeToMenuEntry(9, "Airspace on", 13);
|
|
// }
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 21:
|
|
if (conf.FLIGHT.get()) {
|
|
conf.CURTAIN.toggle();
|
|
GenFlightList();
|
|
glutPostRedisplay();
|
|
}
|
|
MENUCHANGED= true;
|
|
|
|
// if (conf.CURTAIN.get()) {
|
|
// glutChangeToMenuEntry(14, "Curtain off", 21);
|
|
// } else {
|
|
// glutChangeToMenuEntry(14, "Curtain on", 21);
|
|
// }
|
|
|
|
|
|
break;
|
|
|
|
case 31:
|
|
if (conf.FLIGHT.get()) {
|
|
|
|
conf.MARKER.toggle();
|
|
glutPostRedisplay();
|
|
}
|
|
MENUCHANGED= true;
|
|
|
|
|
|
// if (conf.MARKER.get()) {
|
|
// glutChangeToMenuEntry(16, "Marker off", 31);
|
|
// } else {
|
|
// glutChangeToMenuEntry(16, "Marker on", 31);
|
|
// }
|
|
|
|
|
|
break;
|
|
|
|
case 32:
|
|
conf.INFO.toggle();
|
|
|
|
|
|
glutPostRedisplay();
|
|
MENUCHANGED= true;
|
|
|
|
// if (conf.INFO.get()) {
|
|
// glutChangeToMenuEntry(17, "Info off", 32);
|
|
// } else {
|
|
// glutChangeToMenuEntry(17, "Info on", 32);
|
|
// }
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 33:
|
|
if (conf.FLIGHT.get()) {
|
|
if (conf.FOLLOW.get()) {
|
|
ego.setdx(0);
|
|
ego.setdy(0);
|
|
ego.setdz(0);
|
|
} else {
|
|
update_diff_pos();
|
|
}
|
|
|
|
conf.FOLLOW.toggle();
|
|
}
|
|
MENUCHANGED= true;
|
|
|
|
// if (conf.FOLLOW.get()) {
|
|
// glutChangeToMenuEntry(18, "Follow mode off", 33);
|
|
// } else {
|
|
// glutChangeToMenuEntry(18, "Follow mode on", 33);
|
|
// }
|
|
|
|
|
|
break;
|
|
|
|
case 34:
|
|
if (conf.FLIGHT.get()) {
|
|
conf.MARKER_RANGE.toggle();
|
|
GenFlightList();
|
|
glutPostRedisplay();
|
|
}
|
|
MENUCHANGED= true;
|
|
|
|
// if (conf.MARKER_RANGE.get()) {
|
|
// glutChangeToMenuEntry(19, "Range off", 34);
|
|
// } else {
|
|
// // glutChangeToMenuEntry(19, "Range on", 34);
|
|
// }
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 35:
|
|
// makes no sense without flight
|
|
//if (conf.FLIGHT.get()) {
|
|
conf.FLYING.toggle();
|
|
//}
|
|
|
|
if (conf.FLYING.get() || conf.JOYSTICK.get() || conf.GPSD.get()) {
|
|
glutIdleFunc(&IdleFunc);
|
|
} else {
|
|
glutIdleFunc(NULL);
|
|
}
|
|
|
|
glutPostRedisplay();
|
|
MENUCHANGED= true;
|
|
|
|
// if (conf.FLYING.get()) {
|
|
// glutChangeToMenuEntry(20, "Movie off", 35);
|
|
// } else {
|
|
// glutChangeToMenuEntry(20, "Movie on", 35);
|
|
// }
|
|
|
|
|
|
break;
|
|
|
|
case 36:
|
|
conf.JOYSTICK.toggle();
|
|
|
|
if (conf.FLYING.get() || conf.JOYSTICK.get() || conf.GPSD.get() ) {
|
|
glutIdleFunc(&IdleFunc);
|
|
} else {
|
|
glutIdleFunc(NULL);
|
|
}
|
|
MENUCHANGED= true;
|
|
|
|
if (conf.JOYSTICK.get()) {
|
|
glutJoystickFunc(joystick,0);
|
|
// glutChangeToMenuEntry(21,"Joystick off", 36);
|
|
} else {
|
|
glutJoystickFunc(NULL,0);
|
|
// glutChangeToMenuEntry(21,"Joystick on", 36);
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case 41:
|
|
conf.ORTHOVIEW.toggle();
|
|
GenFlightList();
|
|
InitGL(conf.getwidth(), conf.getheight()); //???
|
|
glutPostRedisplay();
|
|
MENUCHANGED= true;
|
|
|
|
// if (conf.ORTHOVIEW.get()) {
|
|
// glutChangeToMenuEntry(23, "3D perspectivic view",
|
|
// 41);
|
|
// } else {
|
|
// glutChangeToMenuEntry(23, "2D orthographic view",
|
|
// 41);
|
|
// }
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 97:
|
|
HELP = true; INFO=false;
|
|
glutPostRedisplay();
|
|
break;
|
|
|
|
case 98:
|
|
INFO = true; HELP=false;
|
|
glutPostRedisplay();
|
|
break;
|
|
|
|
case 99:
|
|
Ende(0);
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// recreate/update menus!
|
|
void menuRecreate()
|
|
{
|
|
if (conf.DEBUG.get())
|
|
cout << " re-creating menus"<< endl;
|
|
glutSetMenu(menIdAirspaceType);
|
|
|
|
if (conf.AIRSPACE_P.get()) {
|
|
glutChangeToMenuEntry(1, "Prohibited D off", 1);
|
|
|
|
} else {
|
|
glutChangeToMenuEntry(1, "Prohibited P on", 1);
|
|
}
|
|
|
|
if (conf.AIRSPACE_R.get()) {
|
|
glutChangeToMenuEntry(2, "Restricted R off", 2); //2
|
|
} else {
|
|
glutChangeToMenuEntry(2, "Restricted R on", 2);
|
|
}
|
|
|
|
if (conf.AIRSPACE_Q.get()) {
|
|
glutChangeToMenuEntry(3, "Danger Q off", 3); //3
|
|
} else {
|
|
glutChangeToMenuEntry(3, "Danger Q on", 3);
|
|
}
|
|
|
|
if (conf.AIRSPACE_C.get()) {
|
|
glutChangeToMenuEntry(4, "Class C off", 4); //4
|
|
} else {
|
|
glutChangeToMenuEntry(4, "Class C on", 4);
|
|
}
|
|
|
|
if (conf.AIRSPACE_D.get()) {
|
|
glutChangeToMenuEntry(5, "Class D off", 5); //5
|
|
} else {
|
|
glutChangeToMenuEntry(5, "Class D on", 5);
|
|
}
|
|
|
|
if (conf.AIRSPACE_CTR.get()) {
|
|
glutChangeToMenuEntry(6, "CTR off", 6); //6
|
|
} else {
|
|
glutChangeToMenuEntry(6, "CTR on", 6);
|
|
}
|
|
|
|
// recreate/change main menu!
|
|
glutSetMenu(menIdMain);
|
|
if (conf.MAP.get()) {
|
|
glutChangeToMenuEntry(1, "Maps off", 1);
|
|
} else {
|
|
glutChangeToMenuEntry(1, "Maps on", 1);
|
|
}
|
|
if (conf.MODULATE.get()) {
|
|
glutChangeToMenuEntry(2, "Colored maps off", 2);
|
|
} else {
|
|
glutChangeToMenuEntry(2, "Colored maps on", 2);
|
|
}
|
|
if (conf.LANDSCAPE.get()) {
|
|
glutChangeToMenuEntry(5, "Terrain off", 11);
|
|
} else {
|
|
glutChangeToMenuEntry(5, "Terrain on", 11);
|
|
}
|
|
if (conf.FOG.get()) {
|
|
glutChangeToMenuEntry(8, "Haze off", 12);
|
|
} else {
|
|
glutChangeToMenuEntry(8, "Haze on", 12);
|
|
}
|
|
if (conf.AIRSPACE.get()) {
|
|
glutChangeToMenuEntry(9, "Airspace off", 13);
|
|
} else {
|
|
glutChangeToMenuEntry(9, "Airspace on", 13);
|
|
}
|
|
if (conf.CURTAIN.get()) {
|
|
glutChangeToMenuEntry(14, "Curtain off", 21);
|
|
} else {
|
|
glutChangeToMenuEntry(14, "Curtain on", 21);
|
|
}
|
|
if (conf.MARKER.get()) {
|
|
glutChangeToMenuEntry(16, "Marker off", 31);
|
|
} else {
|
|
glutChangeToMenuEntry(16, "Marker on", 31);
|
|
}
|
|
if (conf.INFO.get()) {
|
|
glutChangeToMenuEntry(17, "Info off", 32);
|
|
} else {
|
|
glutChangeToMenuEntry(17, "Info on", 32);
|
|
}
|
|
if (conf.FOLLOW.get()) {
|
|
glutChangeToMenuEntry(18, "Follow mode off", 33);
|
|
} else {
|
|
glutChangeToMenuEntry(18, "Follow mode on", 33);
|
|
}
|
|
if (conf.MARKER_RANGE.get()) {
|
|
glutChangeToMenuEntry(19, "Range off", 34);
|
|
} else {
|
|
glutChangeToMenuEntry(19, "Range on", 34);
|
|
}
|
|
if (conf.FLYING.get()) {
|
|
glutChangeToMenuEntry(20, "Movie off", 35);
|
|
} else {
|
|
glutChangeToMenuEntry(20, "Movie on", 35);
|
|
}
|
|
if (conf.JOYSTICK.get()) {
|
|
// glutJoystickFunc(joystick,0);
|
|
glutChangeToMenuEntry(21,"Joystick off", 36);
|
|
} else {
|
|
// glutJoystickFunc(NULL,0);
|
|
glutChangeToMenuEntry(21,"Joystick on", 36);
|
|
}
|
|
if (conf.ORTHOVIEW.get()) {
|
|
glutChangeToMenuEntry(23, "3D perspectivic view",
|
|
41);
|
|
} else {
|
|
glutChangeToMenuEntry(23, "2D orthographic view",
|
|
41);
|
|
}
|
|
|
|
MENUCHANGED=false;
|
|
|
|
}
|
|
|
|
void menuMapSet(int val)
|
|
{
|
|
MENUPOPPED=true;
|
|
if (val == 9999) return;
|
|
|
|
conf.ActiveMapSet.set(val);
|
|
|
|
if (conf.MAP.get()) {
|
|
GenLandscapeList();
|
|
glutPostRedisplay();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void menuStereo(int val)
|
|
{
|
|
MENUPOPPED=true;
|
|
// nothing to do in Hardware stereo mode
|
|
// HW stereo can be enabled at start time and cannot be changed then
|
|
if (conf.STEREO_HW.get()) {
|
|
return;
|
|
}
|
|
|
|
bool REBUILD = false;
|
|
|
|
switch (val) {
|
|
|
|
// turn off stereo modes
|
|
case 1:
|
|
|
|
// rebuilding terrain list is necessary if we had colored anaglyph before
|
|
// because everything is drawn in B&W then
|
|
if ((conf.STEREO_RG.get() || conf.STEREO_RB.get())
|
|
&& !conf.BW.get()) {
|
|
REBUILD = true;
|
|
}
|
|
conf.STEREO.off();
|
|
conf.STEREO_RG.off();
|
|
conf.STEREO_RB.off();
|
|
InitGL(conf.getwidth(), conf.getheight());
|
|
if (REBUILD) {
|
|
GenLandscapeList();
|
|
GenFlightList();
|
|
GenAirspaceList();
|
|
}
|
|
glutPostRedisplay();
|
|
break;
|
|
|
|
case 2:
|
|
if (conf.STEREO.get()) {
|
|
return;
|
|
}
|
|
if ((conf.STEREO_RG.get() || conf.STEREO_RB.get())
|
|
&& !conf.BW.get()) {
|
|
REBUILD = true;
|
|
}
|
|
conf.STEREO.on();
|
|
conf.STEREO_RG.off();
|
|
conf.STEREO_RB.off();
|
|
InitGL(conf.getwidth(), conf.getheight());
|
|
if (REBUILD) {
|
|
GenLandscapeList();
|
|
GenFlightList();
|
|
GenAirspaceList();
|
|
}
|
|
glutPostRedisplay();
|
|
break;
|
|
|
|
case 3:
|
|
if (conf.STEREO_RG.get()) {
|
|
return;
|
|
}
|
|
if (!(conf.STEREO_RB.get() || conf.BW.get())) {
|
|
REBUILD = true;
|
|
}
|
|
conf.STEREO.off();
|
|
conf.STEREO_RG.on();
|
|
conf.STEREO_RB.off();
|
|
InitGL(conf.getwidth(), conf.getheight());
|
|
if (REBUILD) {
|
|
GenLandscapeList();
|
|
GenFlightList();
|
|
GenAirspaceList();
|
|
}
|
|
glutPostRedisplay();
|
|
break;
|
|
|
|
case 4:
|
|
if (conf.STEREO_RB.get()) {
|
|
return;
|
|
}
|
|
if (!(conf.STEREO_RG.get() || conf.BW.get())) {
|
|
REBUILD = true;
|
|
}
|
|
conf.STEREO.off();
|
|
conf.STEREO_RG.off();
|
|
conf.STEREO_RB.on();
|
|
InitGL(conf.getwidth(), conf.getheight());
|
|
if (REBUILD) {
|
|
GenLandscapeList();
|
|
GenFlightList();
|
|
GenAirspaceList();
|
|
}
|
|
glutPostRedisplay();
|
|
break;
|
|
|
|
case 5:
|
|
conf.SWAP_STEREO.toggle();
|
|
glutPostRedisplay();
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void menuColormap(int val)
|
|
{
|
|
MENUPOPPED=true;
|
|
if (conf.colmapnumber.get() == val) {
|
|
return;
|
|
}
|
|
conf.colmapnumber.set(val);
|
|
|
|
if ((conf.LANDSCAPE.get() && conf.MAP.get() && conf.MODULATE.get())
|
|
|| (conf.LANDSCAPE.get() && !conf.MAP.get()
|
|
&& !conf.WIRE.get())) {
|
|
|
|
GenLandscapeList();
|
|
glutPostRedisplay();
|
|
}
|
|
}
|
|
|
|
void menuColormap_sea(int val)
|
|
{
|
|
MENUPOPPED=true;
|
|
if (conf.colmap2number.get() == val) {
|
|
return;
|
|
}
|
|
conf.colmap2number.set(val);
|
|
|
|
if ((conf.LANDSCAPE.get() && conf.MAP.get() && conf.MODULATE.get())
|
|
|| (conf.LANDSCAPE.get() && !conf.MAP.get()
|
|
&& !conf.WIRE.get())) {
|
|
|
|
GenLandscapeList();
|
|
glutPostRedisplay();
|
|
}
|
|
}
|
|
|
|
void menuFSColormap(int val)
|
|
{
|
|
MENUPOPPED=true;
|
|
if (conf.flightstrip_colmap.get() == val) {
|
|
return;
|
|
}
|
|
conf.flightstrip_colmap.set(val);
|
|
GenFlightList();
|
|
glutPostRedisplay();
|
|
}
|
|
|
|
void menuFSMode(int val)
|
|
{
|
|
MENUPOPPED=true;
|
|
if (conf.flightstrip_mode.get() == val) {
|
|
return;
|
|
}
|
|
conf.flightstrip_mode.set(val);
|
|
GenFlightList();
|
|
glutPostRedisplay();
|
|
}
|
|
|
|
void menuAirspaceType(int val)
|
|
{
|
|
MENUPOPPED=true;
|
|
switch (val) {
|
|
|
|
case 1:
|
|
conf.AIRSPACE_P.toggle();
|
|
MENUCHANGED = true;
|
|
break;
|
|
|
|
case 2:
|
|
conf.AIRSPACE_R.toggle();
|
|
MENUCHANGED = true;
|
|
break;
|
|
|
|
case 3:
|
|
conf.AIRSPACE_Q.toggle();
|
|
MENUCHANGED = true;
|
|
break;
|
|
|
|
case 4:
|
|
conf.AIRSPACE_C.toggle();
|
|
MENUCHANGED = true;
|
|
break;
|
|
|
|
case 5:
|
|
conf.AIRSPACE_D.toggle();
|
|
MENUCHANGED = true;
|
|
break;
|
|
|
|
case 6:
|
|
conf.AIRSPACE_CTR.toggle();
|
|
MENUCHANGED = true;
|
|
break;
|
|
}
|
|
|
|
GenAirspaceList();
|
|
glutPostRedisplay();
|
|
}
|
|
|
|
void GenMenu(void)
|
|
{
|
|
// create Map-Set-Submenu
|
|
//if (conf.getMapSetName().size() > 0) {
|
|
//cout << "XXX" << conf.getMapSetName().size() << endl;
|
|
|
|
// freeglut 3.0!
|
|
// glutSetMenuFont(menIdMain, GLUT_BITMAP_TIMES_ROMAN_10);
|
|
|
|
menIdMapSet = glutCreateMenu(menuMapSet);
|
|
vector < string > MapSets;
|
|
MapSets = conf.getMapSetName();
|
|
|
|
if (MapSets.size() == 0) {
|
|
glutAddMenuEntry("no map sets found", 9999);
|
|
}
|
|
|
|
for (int i = 0; i < (int) MapSets.size(); i++) {
|
|
//cout << "set:" << i <<" "<< MapSets[i] << endl;
|
|
glutAddMenuEntry(MapSets[i].c_str(), i + 1);
|
|
}
|
|
//}
|
|
|
|
// create Stereo menu
|
|
menIdStereo = glutCreateMenu(menuStereo);
|
|
glutAddMenuEntry("Stereo off", 1);
|
|
glutAddMenuEntry("Double image", 2);
|
|
glutAddMenuEntry("Red Green", 3);
|
|
glutAddMenuEntry("Red Blue", 4);
|
|
glutAddMenuEntry("Swap Images", 5);
|
|
|
|
//create Colormapmenu
|
|
menIdColormap = glutCreateMenu(menuColormap);
|
|
glutAddMenuEntry("Max's colormap", 1);
|
|
glutAddMenuEntry("Atlas colormap", 2);
|
|
glutAddMenuEntry("Graymap", 3);
|
|
glutAddMenuEntry("Atlas 2 colormap", 4);
|
|
glutAddMenuEntry("Violett - blue", 5);
|
|
glutAddMenuEntry("Killer Rainbow map", 6);
|
|
glutAddMenuEntry("White", 7);
|
|
|
|
|
|
//create Colormapmenu sea
|
|
menIdColormap_sea = glutCreateMenu(menuColormap_sea);
|
|
glutAddMenuEntry("Max's colormap", 1);
|
|
glutAddMenuEntry("Atlas colormap", 2);
|
|
glutAddMenuEntry("Graymap", 3);
|
|
glutAddMenuEntry("Atlas 2 colormap", 4);
|
|
glutAddMenuEntry("Violett - blue", 5);
|
|
glutAddMenuEntry("Killer Rainbow map", 6);
|
|
glutAddMenuEntry("White", 7);
|
|
|
|
//create Colormapmenu FS
|
|
menIdFSColormap = glutCreateMenu(menuFSColormap);
|
|
glutAddMenuEntry("Max's colormap", 1);
|
|
glutAddMenuEntry("Atlas colormap", 2);
|
|
glutAddMenuEntry("Graymap", 3);
|
|
glutAddMenuEntry("Atlas 2 colormap", 4);
|
|
glutAddMenuEntry("Violett - blue", 5);
|
|
glutAddMenuEntry("Killer Rainbow map", 6);
|
|
glutAddMenuEntry("White", 7);
|
|
|
|
//create FS Mode menu
|
|
menIdFSMode = glutCreateMenu(menuFSMode);
|
|
glutAddMenuEntry("classic", 0);
|
|
glutAddMenuEntry("altitude", 1);
|
|
glutAddMenuEntry("speed", 2);
|
|
glutAddMenuEntry("vario", 3);
|
|
|
|
|
|
//create Airspace type menu
|
|
menIdAirspaceType=glutCreateMenu(menuAirspaceType);
|
|
if (conf.AIRSPACE_P.get()) {
|
|
glutAddMenuEntry("Prohibited P off", 1); //1
|
|
} else {
|
|
glutAddMenuEntry("Prohibited P on", 1);
|
|
}
|
|
|
|
if (conf.AIRSPACE_R.get()) {
|
|
glutAddMenuEntry("Restricted R off", 2); //2
|
|
} else {
|
|
glutAddMenuEntry("Restricted R on", 2);
|
|
}
|
|
|
|
if (conf.AIRSPACE_Q.get()) {
|
|
glutAddMenuEntry("Danger Q off", 3); //3
|
|
} else {
|
|
glutAddMenuEntry("Danger Q on", 3);
|
|
}
|
|
|
|
if (conf.AIRSPACE_C.get()) {
|
|
glutAddMenuEntry("Class C off", 4); //4
|
|
} else {
|
|
glutAddMenuEntry("Class C on", 4);
|
|
}
|
|
|
|
if (conf.AIRSPACE_D.get()) {
|
|
glutAddMenuEntry("Class D off", 5); //5
|
|
} else {
|
|
glutAddMenuEntry("Class D on", 5);
|
|
}
|
|
|
|
if (conf.AIRSPACE_CTR.get()) {
|
|
glutAddMenuEntry("CTR off", 6); //6
|
|
} else {
|
|
glutAddMenuEntry("CTR on", 6);
|
|
}
|
|
|
|
|
|
// create Main Menu
|
|
menIdMain = glutCreateMenu(menuMain);
|
|
|
|
if (conf.MAP.get()) {
|
|
glutAddMenuEntry("Maps off", 1); //1
|
|
} else {
|
|
glutAddMenuEntry("Maps on", 1);
|
|
}
|
|
|
|
if (conf.MODULATE.get()) {
|
|
glutAddMenuEntry("Colored maps off", 2); //2
|
|
} else {
|
|
glutAddMenuEntry("Colored maps on", 2);
|
|
}
|
|
|
|
glutAddSubMenu("Map Sets", menIdMapSet); //3
|
|
|
|
|
|
//-----------
|
|
glutAddMenuEntry(" ", 0); //4
|
|
|
|
|
|
if (conf.LANDSCAPE.get()) {
|
|
glutAddMenuEntry("Terrain off", 11); //5
|
|
} else {
|
|
glutAddMenuEntry("Terrain on", 11);
|
|
}
|
|
|
|
glutAddSubMenu("Terrain Colorramps", menIdColormap); //6
|
|
glutAddSubMenu("Sea Colorramps", menIdColormap_sea); //7
|
|
|
|
if (conf.FOG.get()) {
|
|
glutAddMenuEntry("Haze off", 12); //8
|
|
} else {
|
|
glutAddMenuEntry("Haze on", 12);
|
|
}
|
|
|
|
if (conf.AIRSPACE.get()) {
|
|
glutAddMenuEntry("Airspace off", 13); //9
|
|
} else {
|
|
glutAddMenuEntry("Airspace on", 13);
|
|
}
|
|
|
|
glutAddSubMenu("Airspace types", menIdAirspaceType); // 10
|
|
|
|
//------------
|
|
glutAddMenuEntry(" ", 0); //11
|
|
|
|
glutAddSubMenu("Flight track Colorramp", menIdFSColormap); //12
|
|
glutAddSubMenu("Flight track Mode", menIdFSMode); //13
|
|
|
|
if (conf.CURTAIN.get()) {
|
|
glutAddMenuEntry("Curtain off", 21); //14
|
|
} else {
|
|
glutAddMenuEntry("Curtain on", 21);
|
|
}
|
|
|
|
|
|
//---------
|
|
glutAddMenuEntry(" ", 0); //15
|
|
|
|
if (conf.MARKER.get()) {
|
|
glutAddMenuEntry("Marker off", 31); //16
|
|
} else {
|
|
glutAddMenuEntry("Marker on", 31);
|
|
}
|
|
|
|
if (conf.INFO.get()) {
|
|
glutAddMenuEntry("Info off", 32); //17
|
|
} else {
|
|
glutAddMenuEntry("Info on", 32);
|
|
}
|
|
|
|
if (conf.FOLLOW.get()) {
|
|
glutAddMenuEntry("Follow off", 33); //18
|
|
} else {
|
|
glutAddMenuEntry("Follow on", 33);
|
|
}
|
|
|
|
if (conf.MARKER_RANGE.get()) {
|
|
glutAddMenuEntry("Range off", 34); //19
|
|
} else {
|
|
glutAddMenuEntry("Range on", 34);
|
|
}
|
|
|
|
if (conf.FLYING.get()) {
|
|
glutAddMenuEntry("Movie off", 35); //20
|
|
} else {
|
|
glutAddMenuEntry("Movie on", 35);
|
|
}
|
|
|
|
if (conf.JOYSTICK.get()) {
|
|
glutAddMenuEntry("Joystick off",36); //21
|
|
} else {
|
|
glutAddMenuEntry("Joystick on",36);
|
|
}
|
|
|
|
//-------
|
|
|
|
glutAddMenuEntry(" ", 0); //22
|
|
|
|
if (conf.ORTHOVIEW.get()) {
|
|
glutAddMenuEntry("3D perspectivic view", 41); //23
|
|
} else {
|
|
glutAddMenuEntry("2D orthographic view", 41);
|
|
}
|
|
|
|
glutAddSubMenu("Stereo Modes", menIdStereo); //24
|
|
|
|
glutAddMenuEntry(" ", 0); //25
|
|
|
|
glutAddMenuEntry("Help", 97); //26
|
|
glutAddMenuEntry("About OGIE",98); //27
|
|
glutAddMenuEntry("Quit", 99); //28
|
|
glutAttachMenu(GLUT_RIGHT_BUTTON);
|
|
}
|
|
|
|
|
|
void menuStatus(int val, int x, int y)
|
|
{
|
|
MENUPOPPED = true;
|
|
|
|
if (conf.DEBUG.get())
|
|
cout << "menuStatus called: ";
|
|
|
|
if (val == GLUT_MENU_IN_USE) {
|
|
MENUSTATE = true;
|
|
if (conf.DEBUG.get())
|
|
cout << "ON" << endl;
|
|
|
|
}
|
|
|
|
if (val == GLUT_MENU_NOT_IN_USE) {
|
|
MENUSTATE = false;
|
|
MENUPOPPED = false;
|
|
if (conf.DEBUG.get())
|
|
cout << "OFF" << endl;
|
|
if (MENUCHANGED)
|
|
menuRecreate();
|
|
}
|
|
}
|
|
|
|
// all the menu stuff #ifndef ONLY_OSMESA
|
|
#endif
|
|
|
|
|
|
//this function sets up the flight-display list
|
|
void GenFlightList(void)
|
|
{
|
|
if (conf.DEBUG.get()) {
|
|
cout << "GenFlightList START: " << flush;
|
|
#ifndef ONLY_OSMESA
|
|
glutReportErrors();
|
|
#endif
|
|
cout << endl << flush;
|
|
}
|
|
|
|
glDeleteLists(flightdata_displ_list, 1); //delete list to free memory
|
|
flightdata_displ_list = glGenLists(1); //create new List
|
|
glNewList(flightdata_displ_list, GL_COMPILE);
|
|
|
|
/*
|
|
if (conf.DEBUG.get()) {
|
|
cout << "GenFlightList 1: " << flush;
|
|
glutReportErrors();
|
|
cout << endl << flush;
|
|
}
|
|
*/
|
|
|
|
// draw flight linestrip
|
|
if (!conf.LANDSCAPE.get() && !conf.MAP.get()) {
|
|
fd.draw_linestrip(conf.offset.get(), conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get()
|
|
|| conf.BW.get(), 0.8, 0.1, 0.1,
|
|
1.0, 1.0, 1.0);
|
|
} else {
|
|
fd.draw_linestrip(conf.offset.get(), conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get()
|
|
|| conf.BW.get(), conf.flightstrip_col_rup.get(), conf.flightstrip_col_gup.get(), conf.flightstrip_col_bup.get(),
|
|
conf.flightstrip_col_rdown.get(), conf.flightstrip_col_gdown.get(), conf.flightstrip_col_bdown.get());
|
|
}
|
|
|
|
/*
|
|
if (conf.DEBUG.get()) {
|
|
cout << "GenFlightList 2: " << flush;
|
|
glutReportErrors();
|
|
cout << endl << flush;
|
|
}
|
|
*/
|
|
|
|
// The "Shadow" for "Flat-Landscape"
|
|
if (conf.FLIGHT.get()) {
|
|
if (!conf.LANDSCAPE.get()) {
|
|
fd.draw_shadow(conf.offset.get(),
|
|
conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get()
|
|
|| conf.BW.get(), 2.0, 0.0, 0.0,
|
|
0.0);
|
|
} else {
|
|
fd.draw_shadow_terrain(conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get()
|
|
|| conf.BW.get(), 1.0, 0.0,
|
|
0.0, 0.3);
|
|
}
|
|
}
|
|
// we need to render transparent stuff at the end (thus put it at the end of the flight_list)
|
|
|
|
/*
|
|
if (conf.DEBUG.get()) {
|
|
cout << "GenFlightList 3: " << flush;
|
|
glutReportErrors();
|
|
cout << endl << flush;
|
|
}
|
|
*/
|
|
|
|
// Curtain
|
|
if (conf.CURTAIN.get()) {
|
|
fd.draw_curtain(conf.offset.get(), conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get()
|
|
|| conf.BW.get(), 0.0, 0.0, 0.4, 0.4);
|
|
}
|
|
glEndList();
|
|
// this used to be an experiment to smooth the linestrip:
|
|
// fd.setglEvaluator();
|
|
if (conf.DEBUG.get()) {
|
|
cout << "GenFlightList END: " << flush;
|
|
#ifndef ONLY_OSMESA
|
|
glutReportErrors();
|
|
#endif
|
|
cout << endl << flush;
|
|
}
|
|
}
|
|
|
|
void GenAirspaceList()
|
|
{
|
|
|
|
if (conf.DEBUG.get()) {
|
|
cout << "GenAirList START: " << flush;
|
|
#ifndef ONLY_OSMESA
|
|
glutReportErrors();
|
|
#endif
|
|
cout << endl << flush;
|
|
}
|
|
|
|
glDeleteLists(airspace_displ_list, 1); // delete list to free memory
|
|
airspace_displ_list = glGenLists(1); // create new List
|
|
glNewList(airspace_displ_list, GL_COMPILE);
|
|
|
|
//Airspace
|
|
if (conf.AIRSPACE.get()) {
|
|
air.drawAirspace(conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get() || conf.BW.get());
|
|
}
|
|
glEndList();
|
|
|
|
if (conf.DEBUG.get()) {
|
|
cout << "GenAirList END: " << flush;
|
|
#ifndef ONLY_OSMESA
|
|
glutReportErrors();
|
|
#endif
|
|
cout << endl << flush;
|
|
}
|
|
}
|
|
|
|
/*
|
|
void GenPointsList()
|
|
{
|
|
if (conf.DEBUG.get()) {
|
|
cout << "GenPointsList START: " << flush;
|
|
#ifndef ONLY_OSMESA
|
|
glutReportErrors();
|
|
#endif
|
|
cout << endl << flush;
|
|
}
|
|
|
|
// lifts. more sections are needed for WPs etc
|
|
glDeleteLists(lifts_displ_list,1);
|
|
lifts_displ_list = glGenLists(1);
|
|
glNewList(lifts_displ_list, GL_COMPILE);
|
|
|
|
if (conf.LIFTS.get()) {
|
|
lifts.drawLifts(conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get() || conf.BW.get());
|
|
}
|
|
|
|
glEndList();
|
|
|
|
if (conf.DEBUG.get()) {
|
|
cout << "GenPointsList END: " << flush;
|
|
#ifndef ONLY_OSMESA
|
|
glutReportErrors();
|
|
#endif
|
|
cout << endl << flush;
|
|
}
|
|
|
|
}
|
|
*/
|
|
|
|
// generate the terrain display list
|
|
void GenLandscapeList()
|
|
{
|
|
|
|
landscape_jump:
|
|
|
|
if (conf.DEBUG.get()) {
|
|
cout << "GenLandList START: " << flush;
|
|
#ifndef ONLY_OSMESA
|
|
glutReportErrors();
|
|
#endif
|
|
cout << endl << flush;
|
|
}
|
|
|
|
|
|
// loading message
|
|
#ifndef ONLY_OSMESA
|
|
if (!( conf.OSMESA.get() || conf.OFFSCREEN.get()))
|
|
glutSwapBuffers(); //nobody knows whats in the back buffer,
|
|
// but there is a good changce that after swapping there is the previous displayed image
|
|
|
|
// make shure that the text appears right and left in hw-stereo-mode
|
|
// doesnt make sense in offscreen mode... and GL_BACK would segfault!
|
|
if (! ( conf.OSMESA.get() || conf.OFFSCREEN.get() )) {
|
|
if (conf.STEREO_HW.get()) {
|
|
glDrawBuffer(GL_BACK);
|
|
}
|
|
|
|
//vector <string> message;
|
|
//message.push_back("loading...");
|
|
|
|
|
|
int font_height = conf.getheight() / 5;
|
|
glLineWidth(5.0);
|
|
gltext(conf.getwidth() / 4, (conf.getheight() / 2),
|
|
font_height, "loading...", conf.getwidth(),
|
|
conf.getheight());
|
|
glutSwapBuffers();
|
|
glLineWidth(1.0);
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
glDeleteLists(landscape_displ_list, 1); //free memory
|
|
landscape_displ_list = glGenLists(1); //create new List
|
|
glNewList(landscape_displ_list, GL_COMPILE);
|
|
|
|
|
|
|
|
|
|
|
|
//the huge green rectangle (flat-landscape)
|
|
if (!conf.LANDSCAPE.get() && !conf.MAP.get()) {
|
|
//glPushAttrib(GL_ENABLE_BIT);
|
|
//glPushAttrib(GL_POLYGON_BIT);
|
|
|
|
//glPolygonMode(GL_FRONT, GL_FILL); //should already be set (default)
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glBegin(GL_POLYGON);
|
|
|
|
float _col[3] = { 0.0, 0.3, 0.0 };
|
|
|
|
if (conf.BW.get() || conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get()) {
|
|
glColor3fv(graycolor(_col));
|
|
} else {
|
|
glColor3fv(_col);
|
|
}
|
|
|
|
// if we have texture maps the green floor should be deeper to avoid strange effects...
|
|
// can be deeper in any case (why not?) fd.getzmin - 0.1 km (=-100m)
|
|
GLfloat greenheight =
|
|
fd.getzmin() + ((float) conf.offset.get() / 1000.0) -
|
|
0.1;
|
|
|
|
|
|
glVertex3f((GLfloat) fd.getxmax() + conf.getborder(),
|
|
(GLfloat) fd.getymin() - conf.getborder(),
|
|
greenheight);
|
|
glVertex3f((GLfloat) fd.getxmax() + conf.getborder(),
|
|
(GLfloat) fd.getymax() + conf.getborder(),
|
|
greenheight);
|
|
glVertex3f((GLfloat) fd.getxmin() - conf.getborder(),
|
|
(GLfloat) fd.getymax() + conf.getborder(),
|
|
greenheight);
|
|
glVertex3f((GLfloat) fd.getxmin() - conf.getborder(),
|
|
(GLfloat) fd.getymin() - conf.getborder(),
|
|
greenheight);
|
|
glEnd();
|
|
|
|
//glPopAttrib();
|
|
glEnable (GL_LIGHTING); // reset our default
|
|
}
|
|
|
|
|
|
// TESTING
|
|
/* float _x,_y;
|
|
proj.get_xy(47.0,11.0,_x,_y);
|
|
glRasterPos3f(_x,_y,3.5);
|
|
glColor3f(0,0,0);
|
|
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,'X');
|
|
*/
|
|
|
|
// textured maps... on flat ground
|
|
if (conf.MAP.get() && !conf.LANDSCAPE.get()) {
|
|
|
|
for (int r = conf.getMapIndexLow();
|
|
r < conf.getMapIndexHigh(); r++) {
|
|
|
|
Map map;
|
|
map.set_proj_pointer(&proj);
|
|
map.set_conf_pointer(&conf);
|
|
|
|
if (conf.getMapFilename(r)[ conf.getMapFilename(r).size() - 3] == 'j'
|
|
|| conf.getMapFilename(r)[ conf.getMapFilename(r).size() - 3] == 'J') {
|
|
|
|
map.readMap_jpeg(conf.getMapFilename(r),
|
|
conf.getmap_width(r),
|
|
conf.getmap_height(r));
|
|
} else {
|
|
|
|
map.readMap(conf.getMapFilename(r),
|
|
conf.getmap_width(r),
|
|
conf.getmap_height(r));
|
|
}
|
|
|
|
map.setcenter_lat(fd.getcenter_lat());
|
|
map.setcenter_lon(fd.getcenter_lon());
|
|
|
|
map.settop(conf.getmap_top(r));
|
|
map.setbottom(conf.getmap_bottom(r));
|
|
map.setright(conf.getmap_right(r));
|
|
map.setleft(conf.getmap_left(r));
|
|
|
|
map.setglmap(fd.getzmin() +
|
|
((float) conf.offset.get() / 1000.0) -
|
|
0.01, conf.COMPRESSION.get(), true,
|
|
conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get()
|
|
|| conf.BW.get());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//Terrain with textured map
|
|
if (conf.LANDSCAPE.get() && conf.MAP.get()) {
|
|
|
|
short int _max_h_bkp;
|
|
short int _min_h_bkp;
|
|
|
|
if (conf.MODULATE.get()) {
|
|
|
|
short int _max_h = -8888;
|
|
short int _min_h = -8888;
|
|
|
|
_max_h_bkp = conf.getmax_h();
|
|
_min_h_bkp = conf.getmin_h();
|
|
|
|
// get min and max_h with dummy readDEM_fast
|
|
// vielleicht kriegt man das noch mal schneller hin?
|
|
|
|
//cout << conf.getmax_h() << " max -- min: " << conf.getmin_h() << endl;
|
|
|
|
if (conf.getmax_h() == -9999
|
|
|| conf.getmin_h() == -9999) {
|
|
|
|
for (int r = conf.getMapIndexLow();
|
|
r < conf.getMapIndexHigh(); r++) {
|
|
|
|
Landscape land;
|
|
land.set_conf_pointer(&conf);
|
|
|
|
land.set_sealevel((double) conf.
|
|
get_sealevel());
|
|
land.set_sealevel2((double) conf.
|
|
get_sealevel2
|
|
());
|
|
land.set_sealevel3((double) conf.
|
|
get_sealevel3());
|
|
|
|
land.set_proj_pointer(&proj);
|
|
land.setdownscalefactor(conf.
|
|
getdownscalefactor
|
|
());
|
|
land.setcenter_lat(fd.
|
|
getcenter_lat
|
|
());
|
|
land.setcenter_lon(fd.
|
|
getcenter_lon
|
|
());
|
|
land.setmax_lat(conf.
|
|
getmap_top(r));
|
|
land.setmin_lat(conf.
|
|
getmap_bottom(r));
|
|
land.setmax_lon(conf.
|
|
getmap_right(r));
|
|
land.setmin_lon(conf.
|
|
getmap_left(r));
|
|
land.setgrid_lat(conf.
|
|
getdem_grid_lat
|
|
());
|
|
land.setgrid_lon(conf.
|
|
getdem_grid_lon
|
|
());
|
|
|
|
int ret = land.readDEM(conf.
|
|
getDemFileName(),
|
|
conf.
|
|
getdem_rows(),
|
|
conf.
|
|
getdem_columns(),
|
|
conf.
|
|
getdem_lat_min(),
|
|
conf.
|
|
getdem_lat_max(),
|
|
conf.
|
|
getdem_lon_min(),
|
|
conf.
|
|
getdem_lon_max
|
|
(), true);
|
|
|
|
if (ret == 99) {
|
|
if (conf.DEBUG.get())
|
|
cout << "readDEM returned 99 " << endl << flush;
|
|
glEndList();
|
|
goto landscape_jump;
|
|
}
|
|
|
|
|
|
if (_min_h == -8888)
|
|
_min_h = land.getmin_h();
|
|
if (_max_h == -8888)
|
|
_max_h = land.getmax_h();
|
|
|
|
if (land.getmin_h() < _min_h)
|
|
_min_h = land.getmin_h();
|
|
if (land.getmax_h() > _max_h)
|
|
_max_h = land.getmax_h();
|
|
}
|
|
|
|
if (conf.getmax_h() == -9999)
|
|
conf.setmax_h(_max_h);
|
|
if (conf.getmin_h() == -9999)
|
|
conf.setmin_h(_min_h);
|
|
}
|
|
if (conf.VERBOSE.get()) {
|
|
cout <<
|
|
"Max and Min Alt used for modulated colors: (min, max): "
|
|
<< conf.getmin_h() << ", " << conf.
|
|
getmax_h() << endl;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//cout << "entering Terrain AND Map mode..." << endl;
|
|
for (int r = conf.getMapIndexLow();
|
|
r < conf.getMapIndexHigh(); r++) {
|
|
|
|
Map map;
|
|
map.set_proj_pointer(&proj);
|
|
map.set_conf_pointer(&conf);
|
|
Landscape land;
|
|
land.set_conf_pointer(&conf);
|
|
|
|
land.set_sealevel((double) conf.get_sealevel());
|
|
land.set_sealevel2((double) conf.get_sealevel2());
|
|
land.set_sealevel3((double) conf.get_sealevel3());
|
|
|
|
|
|
land.set_proj_pointer(&proj);
|
|
|
|
land.setdownscalefactor(conf.getdownscalefactor());
|
|
|
|
if (conf.getMapFilename(r)[conf.getMapFilename(r).size() - 3] == 'j') {
|
|
|
|
map.readMap_jpeg(conf.getMapFilename(r),
|
|
conf.getmap_width(r),
|
|
conf.getmap_height(r));
|
|
|
|
} else {
|
|
|
|
map.readMap(conf.getMapFilename(r),
|
|
conf.getmap_width(r),
|
|
conf.getmap_height(r));
|
|
}
|
|
|
|
land.setcenter_lat(fd.getcenter_lat());
|
|
land.setcenter_lon(fd.getcenter_lon());
|
|
map.setcenter_lat(fd.getcenter_lat());
|
|
map.setcenter_lon(fd.getcenter_lon());
|
|
|
|
land.setmax_lat(conf.getmap_top(r));
|
|
land.setmin_lat(conf.getmap_bottom(r));
|
|
land.setmax_lon(conf.getmap_right(r));
|
|
land.setmin_lon(conf.getmap_left(r));
|
|
|
|
land.setgrid_lat(conf.getdem_grid_lat());
|
|
land.setgrid_lon(conf.getdem_grid_lon());
|
|
|
|
int ret = land.readDEM(conf.getDemFileName(),
|
|
conf.getdem_rows(),
|
|
conf.getdem_columns(),
|
|
conf.getdem_lat_min(),
|
|
conf.getdem_lat_max(),
|
|
conf.getdem_lon_min(),
|
|
conf.getdem_lon_max());
|
|
|
|
if (ret == 99) {
|
|
if (conf.DEBUG.get())
|
|
cout << "readDEM returned 99 " << endl << flush;
|
|
glEndList();
|
|
goto landscape_jump;
|
|
}
|
|
|
|
// load map, but do not set texture coordinates
|
|
// that will be done via land.setgltrainglestrip_tex
|
|
map.setglmap(fd.getzmin() +
|
|
((float) conf.offset.get() / 1000.0) -
|
|
0.01, conf.COMPRESSION.get(),
|
|
conf.MAPS_UNLIGHTED.get(),
|
|
conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get()
|
|
|| conf.BW.get(), false);
|
|
|
|
if (conf.getmax_h() != -9999) {
|
|
land.setmax_h(conf.getmax_h());
|
|
//cout << "max = "<< conf.getmax_h() << endl;
|
|
}
|
|
|
|
if (conf.getmin_h() != -9999) {
|
|
land.setmin_h(conf.getmin_h());
|
|
//cout << "min = "<<conf.getmin_h() << endl;
|
|
}
|
|
|
|
land.setgltrianglestrip_tex(conf.colmapnumber.
|
|
get(),
|
|
conf.colmap2number.
|
|
get(),
|
|
(conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.
|
|
get()
|
|
|| conf.BW.get()));
|
|
|
|
}
|
|
|
|
// restore values
|
|
if (conf.MODULATE.get()) {
|
|
conf.setmax_h(_max_h_bkp);
|
|
conf.setmin_h(_min_h_bkp);
|
|
}
|
|
}
|
|
// Terrain, only
|
|
if (conf.LANDSCAPE.get() && !conf.MAP.get()) {
|
|
|
|
Landscape land;
|
|
land.set_conf_pointer(&conf);
|
|
|
|
land.set_sealevel((double) conf.get_sealevel());
|
|
land.set_sealevel2((double) conf.get_sealevel2());
|
|
land.set_sealevel3((double) conf.get_sealevel3());
|
|
|
|
|
|
land.set_proj_pointer(&proj);
|
|
|
|
land.setdownscalefactor(conf.getdownscalefactor());
|
|
|
|
land.setcenter_lat(fd.getcenter_lat());
|
|
land.setcenter_lon(fd.getcenter_lon());
|
|
//adding a border in km (border_land)
|
|
float border_deg_lat = conf.getborder_land_lat() / DEGDIST;
|
|
float border_deg_lon =
|
|
(conf.getborder_land_lon() / DEGDIST) /
|
|
cos(fd.getcenter_lat() * PI_180);
|
|
land.setmin_lat(fd.getlatmin() - border_deg_lat);
|
|
land.setmin_lon(fd.getlonmin() - border_deg_lon);
|
|
land.setmax_lat(fd.getlatmax() + border_deg_lat);
|
|
land.setmax_lon(fd.getlonmax() + border_deg_lon);
|
|
|
|
if (conf.VERBOSE.get()) {
|
|
cout << "Terrain boundaries: " << land.getmax_lat() << " " << land.getmin_lat() <<
|
|
" " << land.getmin_lon() << " " << land.getmax_lon() << endl;
|
|
}
|
|
|
|
land.setgrid_lat(conf.getdem_grid_lat());
|
|
land.setgrid_lon(conf.getdem_grid_lon());
|
|
|
|
int ret = land.readDEM(conf.getDemFileName(), conf.getdem_rows(),
|
|
conf.getdem_columns(), conf.getdem_lat_min(),
|
|
conf.getdem_lat_max(), conf.getdem_lon_min(),
|
|
conf.getdem_lon_max());
|
|
|
|
|
|
if (ret == 99) {
|
|
if (conf.DEBUG.get())
|
|
cout << "readDEM returned 99 " << endl << flush;
|
|
glEndList();
|
|
goto landscape_jump;
|
|
}
|
|
|
|
if (conf.getmax_h() != -9999) {
|
|
land.setmax_h(conf.getmax_h());
|
|
//cout << "max = "<< conf.getmax_h() << endl;
|
|
}
|
|
|
|
if (conf.getmin_h() != -9999) {
|
|
land.setmin_h(conf.getmin_h());
|
|
//cout << "min = "<<conf.getmin_h() << endl;
|
|
}
|
|
|
|
if (conf.VERBOSE.get()) {
|
|
cout <<
|
|
"Max and Min Alt used for colors: (min, max): "
|
|
<< land.getmin_h() << ", " << land.
|
|
getmax_h() << endl;
|
|
|
|
|
|
/*
|
|
// these are derived from landscape.cpp
|
|
int latsteps = (int) (((float)
|
|
(land.getsteps_lat() -
|
|
3 *
|
|
conf.
|
|
getdownscalefactor()) /
|
|
(float) conf.
|
|
getdownscalefactor()) +
|
|
0.5);
|
|
int lonsteps = (int) (((float)
|
|
(land.getsteps_lon() -
|
|
2 *
|
|
conf.getdownscalefactor() -
|
|
1) /
|
|
(float) conf.
|
|
getdownscalefactor()) +
|
|
0.5);
|
|
|
|
cout << "The Surface is build with " <<
|
|
latsteps * lonsteps * 2
|
|
<< " Triangles." << endl;
|
|
*/
|
|
|
|
cout << "DEM data is read in byte order: ";
|
|
if (conf.BIGENDIAN.get()) {
|
|
cout << "big endian" << endl;
|
|
} else {
|
|
cout << "little endian" << endl;
|
|
}
|
|
|
|
if (conf.input_dem_factor.get() != 1.0)
|
|
cout << "DEM input scaling factor: " << conf.input_dem_factor.get() << endl;
|
|
|
|
|
|
}
|
|
|
|
land.setgltrianglestrip(conf.WIRE.get(),
|
|
conf.colmapnumber.get(),
|
|
conf.colmap2number.get(),
|
|
(conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get()
|
|
|| conf.BW.get()), false);
|
|
|
|
|
|
}
|
|
glEndList(); //end of the list
|
|
|
|
if (conf.DEBUG.get()) {
|
|
cout << "GenLandList END: " << flush;
|
|
#ifndef ONLY_OSMESA
|
|
glutReportErrors();
|
|
#endif
|
|
cout << endl << flush;
|
|
}
|
|
|
|
}
|
|
|
|
// mouse callback-function (when any button is clicked)
|
|
#ifndef ONLY_OSMESA
|
|
void mouseClickMove(int xmouse, int ymouse)
|
|
{
|
|
|
|
if (HELP || INFO) {
|
|
return;
|
|
}
|
|
|
|
if (!conf.MOUSE.get()) {
|
|
if (MOUSEWARPED) {
|
|
lastmx = conf.getwidth() / 2;
|
|
lastmy = conf.getheight() / 2;
|
|
MOUSEWARPED = false;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
if (lastmx == 0) { //nothing to do in first call
|
|
lastmx = xmouse; //but set the x and y in global lastmx
|
|
lastmy = ymouse; //and lastmy
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
//double factor;
|
|
if (lastmx == 0) { //nothing to do in first call
|
|
lastmx = xmouse; //but set the x and y in global lastmx
|
|
lastmy = ymouse; //and lastmy
|
|
return;
|
|
}
|
|
|
|
double _dx = xmouse - lastmx; //put differentials into _dx and _dy
|
|
double _dy = ymouse - lastmy;
|
|
lastmx = xmouse; //save present position
|
|
lastmy = ymouse;
|
|
|
|
//cout << "dx dy " << _dx << " " << _dy << endl;
|
|
if (abs(_dx) > 20 || abs(_dy) > 20) {
|
|
// we don't want the view to skip, so ignore what is most likely the first call
|
|
return;
|
|
}
|
|
|
|
|
|
if (!conf.ORTHOVIEW.get()) { // Only if we are not in ORTHO view
|
|
float _mstep;
|
|
|
|
|
|
// left button: move towards point (center) and back
|
|
|
|
if (middlebuttonstate == GLUT_DOWN && leftbuttonstate != GLUT_DOWN) {
|
|
double factor;
|
|
if(_dy < 0){
|
|
factor = pow(0.99, abs((int)_dy));
|
|
} else {
|
|
factor = pow(1.01, abs((int)_dy));
|
|
}
|
|
|
|
if (!conf.MARKER.get()) {
|
|
|
|
// move to central point
|
|
ego.setx(ego.getx() * factor);
|
|
ego.sety(ego.gety() * factor);
|
|
ego.setz(ego.getz() * factor);
|
|
|
|
//if (conf.DEBUG.get())
|
|
// cout << "wo marker ego.x: " << ego.getx() << " ego.y: " << ego.gety() << " ego.z: " << ego.getz() << endl;
|
|
|
|
} else {
|
|
//move towards markerpos
|
|
|
|
// z-koordinates is fscked, even for !MARKER!!!
|
|
//cout << "egoz/3: " << ego.getz()/3<< " markerz: "<<fd.getmarkerz()<< " fac" << factor << endl;
|
|
//cout << (ego.getz()/3) - fd.getmarkerz() << "diff " << endl;
|
|
//if (conf.DEBUG.get())
|
|
// cout << "w marker ego.x: " << ego.getx() << " ego.y: " << ego.gety() << " ego.z: " << ego.getz() << endl;
|
|
|
|
ego.setx( - fd.getmarkerx() + ( ego.getx() + fd.getmarkerx()) * factor );
|
|
ego.sety( - fd.getmarkery() + ( ego.gety() + fd.getmarkery()) * factor );
|
|
ego.setz( ( fd.getmarkerz() + ( ego.getz()/conf.z_scale.get() - fd.getmarkerz()) * factor ) * conf.z_scale.get() );
|
|
}
|
|
|
|
// this is probably not needed...
|
|
//ego.movef(0.2 * _dy);
|
|
|
|
}
|
|
|
|
if (middlebuttonstate == GLUT_DOWN && leftbuttonstate == GLUT_DOWN) {
|
|
ego.moveu(0.2 * _dy);
|
|
ego.moves(0.2 * _dx);
|
|
} else if (leftbuttonstate == GLUT_DOWN && middlebuttonstate != GLUT_DOWN) { // left button is down
|
|
if (args_info.smooth_mouse_given) {
|
|
_mstep = 10;
|
|
} else {
|
|
_mstep = 3;
|
|
}
|
|
if (!conf.MARKER.get()) {
|
|
ego.spinmoveradial(_dx / _mstep); //spin the ego around the view centre while adjusting view angle
|
|
ego.spinmovevertical(_dy / _mstep); // grosser Teiler = sanfte Bewegung
|
|
} else {
|
|
ego.spinmoveradialpoint(_dx / _mstep, fd.getmarkerx(), fd.getmarkery()); //spin the ego around the view centre while adjusting view angle
|
|
ego.spinmoveverticalpoint(_dy / _mstep, fd.getmarkerx(), fd.getmarkery()); // grosser Teiler = sanfte Bewegung
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (conf.FOLLOW.get()) {
|
|
update_diff_pos();
|
|
}
|
|
|
|
|
|
if (!conf.MOUSE.get()) {
|
|
// warp pointer to center of window
|
|
glutWarpPointer(conf.getwidth() / 2, conf.getheight() / 2);
|
|
MOUSEWARPED = true;
|
|
}
|
|
|
|
glutPostRedisplay(); //update display
|
|
}
|
|
|
|
void mouseClickState(int button, int state, int xmouse, int ymouse)
|
|
{
|
|
if (button == GLUT_RIGHT_BUTTON) {
|
|
rightbuttonstate = state;
|
|
}
|
|
if (button == GLUT_MIDDLE_BUTTON) {
|
|
middlebuttonstate = state;
|
|
}
|
|
|
|
if (button == GLUT_LEFT_BUTTON) {
|
|
leftbuttonstate = state;
|
|
}
|
|
|
|
}
|
|
|
|
// mouse callback-function
|
|
void mouseMove(int xmouse, int ymouse)
|
|
{
|
|
|
|
if (HELP || INFO) {
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
// return imediatley if any menu is in use
|
|
if (MENUSTATE) {
|
|
//cout << "menu acitve" << endl;
|
|
return;
|
|
}
|
|
|
|
// if menu was used right before avoid "jumping"
|
|
if (MENUPOPPED) {
|
|
//cout << "mouse move called after menu POPPPED" << endl;
|
|
lastmx = 0;
|
|
lastmy=0;
|
|
MENUPOPPED = false;
|
|
|
|
//glutWarpPointer(conf.getwidth() / 2, conf.getheight() / 2);
|
|
//MOUSEWARPED = true;
|
|
return;
|
|
}
|
|
|
|
//if pointer was warped before (callback is triggered by warping...)
|
|
//
|
|
if (MOUSEWARPED) {
|
|
lastmx = conf.getwidth() / 2;
|
|
lastmy = conf.getheight() / 2;
|
|
MOUSEWARPED = false;
|
|
return;
|
|
}
|
|
|
|
if (lastmx == 0) { //nothing to do in first call
|
|
lastmx = xmouse; //but set the x and y in global lastmx
|
|
lastmy = ymouse; //and lastmy
|
|
return;
|
|
}
|
|
|
|
double _dx = xmouse - lastmx; //put differences to _dx and _dy
|
|
double _dy = ymouse - lastmy;
|
|
lastmx = xmouse; //save actual position
|
|
lastmy = ymouse;
|
|
|
|
//cout << "dx dy " << _dx << " " << _dy << endl;
|
|
|
|
|
|
// this should prevent "jumps" if the curser enters the window again!
|
|
// seems to be effective
|
|
if (abs(_dx)+abs(_dy) > 100) {
|
|
return;
|
|
}
|
|
|
|
if (!conf.ORTHOVIEW.get()) {
|
|
float _mstep;
|
|
if (args_info.smooth_mouse_given) {
|
|
_mstep = 10;
|
|
} else {
|
|
_mstep = 3;
|
|
}
|
|
ego.spinz(_dx / _mstep); //spin the ego!
|
|
ego.spinx(-_dy / _mstep); // grosser Teiler = sanfte Bewegung
|
|
} else {
|
|
ego.shiftx(_dx * conf.getorthoshift());
|
|
ego.shifty(_dy * conf.getorthoshift());
|
|
|
|
if (conf.FOLLOW.get())
|
|
update_diff_pos(); // ????
|
|
InitGL(conf.getwidth(), conf.getheight());
|
|
|
|
}
|
|
|
|
// warp pointer to center of window
|
|
glutWarpPointer(conf.getwidth() / 2, conf.getheight() / 2);
|
|
MOUSEWARPED = true;
|
|
|
|
|
|
glutPostRedisplay(); //update display
|
|
}
|
|
#endif
|
|
//mouse functions excluded for ONLY_OSMESA
|
|
|
|
//Draw only.
|
|
void Draw(void)
|
|
{
|
|
|
|
//Timecheck drawtime("Draw", &conf);
|
|
|
|
//call the lists
|
|
glCallList(landscape_displ_list);
|
|
|
|
|
|
if (conf.FLIGHT.get()) {
|
|
if (conf.MARKER.get()) {
|
|
if (!conf.ORTHOVIEW.get()) {
|
|
fd.draw_marker(conf.offset.get(),
|
|
conf.z_scale.get(),
|
|
conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get()
|
|
|| conf.BW.get());
|
|
} else {
|
|
fd.draw_marker_ortho();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
if (conf.LIFTS.get()) {
|
|
lifts.drawLifts(conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get() || conf.BW.get());
|
|
lifts.drawLiftsTxt(conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get() || conf.BW.get(), &ego);
|
|
}
|
|
|
|
if (conf.WAYPOINTS.get()) {
|
|
waypoints.drawWaypoints(conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get() || conf.BW.get());
|
|
waypoints.drawWaypointsTxt(conf.STEREO_RB.get()
|
|
|| conf.STEREO_RG.get() || conf.BW.get(), &ego);
|
|
}
|
|
|
|
//glCallList(lifts_displ_list);
|
|
glCallList(flightdata_displ_list);
|
|
glCallList(airspace_displ_list);
|
|
|
|
//lifts.drawLifts(1);
|
|
|
|
if (conf.INFO.get()) {
|
|
DrawInfo();
|
|
}
|
|
|
|
//drawtime.checknow("end of Draw");
|
|
|
|
}
|
|
|
|
|
|
// set the position and view-direction...
|
|
void setpos(void)
|
|
{
|
|
|
|
glLoadIdentity();
|
|
glRotatef(ego.getspinx(), 1.0, 0.0, 0.0); //do the viewpoint transformation
|
|
glRotatef(ego.getspiny(), 0.0, 1.0, 0.0);
|
|
glRotatef(ego.getspinz(), 0.0, 0.0, 1.0);
|
|
|
|
glTranslatef(ego.getx(), ego.gety(), -ego.getz());
|
|
glScalef(1.0, 1.0, conf.z_scale.get()); //do z-axis scaling
|
|
|
|
|
|
}
|
|
|
|
void DrawBackground(int bgType)
|
|
{
|
|
// Use an orthographic view, and save all matrices
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glOrtho(-1, 1, -1, 1, -1, 1);
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
|
|
// we also save the enables, as we plan to enable/disable a lot of things
|
|
glPushAttrib(GL_ENABLE_BIT);
|
|
|
|
// disable the expensive tests
|
|
glDisable(GL_CULL_FACE);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_BLEND);
|
|
glDisable(GL_LIGHTING);
|
|
|
|
// vertical gradient
|
|
//int bgType = 2;
|
|
|
|
switch (bgType) {
|
|
|
|
case 1:
|
|
// solid background // like the old one
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
glColor3f(conf.background_color_1r.get(), conf.background_color_1g.get(), conf.background_color_1b.get());
|
|
glBegin(GL_QUADS);
|
|
glVertex2i( 1, -1);
|
|
glVertex2i( 1, 1);
|
|
glVertex2i(-1, 1);
|
|
glVertex2i(-1, -1);
|
|
glEnd();
|
|
break;
|
|
|
|
case 2:
|
|
// vertical gradient
|
|
glDisable(GL_TEXTURE_2D);
|
|
glBegin(GL_QUADS);
|
|
glColor3f(conf.background_color_1r.get(), conf.background_color_1g.get(), conf.background_color_1b.get()); // lighter!
|
|
glVertex2i(-1, 1);
|
|
glVertex2i( 1, 1);
|
|
|
|
glColor3f(conf.background_color_2r.get(), conf.background_color_2g.get(), conf.background_color_2b.get());
|
|
glVertex2i( 1, -1);
|
|
glVertex2i(-1, -1);
|
|
glEnd();
|
|
break;
|
|
|
|
case 3:
|
|
// horizontal gradient
|
|
glDisable(GL_TEXTURE_2D);
|
|
glBegin(GL_QUADS);
|
|
glColor3f(conf.background_color_1r.get(), conf.background_color_1g.get(), conf.background_color_1b.get());
|
|
glVertex2i(-1, 1);
|
|
glVertex2i(-1, -1);
|
|
|
|
glColor3f(conf.background_color_2r.get(), conf.background_color_2g.get(), conf.background_color_2b.get());
|
|
glVertex2i( 1, -1);
|
|
glVertex2i( 1, 1);
|
|
glEnd();
|
|
break;
|
|
|
|
}
|
|
|
|
//
|
|
// restore our states
|
|
// this is done so as to leave the modelview matrix as the last active
|
|
// matrix
|
|
//
|
|
glPopAttrib();
|
|
|
|
glMatrixMode (GL_PROJECTION);
|
|
glPopMatrix();
|
|
|
|
glMatrixMode (GL_MODELVIEW);
|
|
glPopMatrix();
|
|
|
|
}
|
|
|
|
// rendering routine
|
|
void DrawGLScene(void)
|
|
{
|
|
// temporary
|
|
/* if (conf.DEBUG.get()) {
|
|
cout << "entered DRAWGLSCENE" << endl;
|
|
}
|
|
*/
|
|
//Timecheck drawgl("DrawGLScene", &conf);
|
|
if (HELP) {
|
|
HelpScreen();
|
|
return;
|
|
}
|
|
|
|
if (INFO) {
|
|
InfoScreen();
|
|
return;
|
|
}
|
|
|
|
if (conf.ORTHOVIEW.get())
|
|
InitGL(conf.getwidth(), conf.getheight());
|
|
|
|
if (conf.STEREO_RB.get() || conf.STEREO_RG.get() || conf.BW.get()) {
|
|
glClearColor(0.144f, 0.144f, 0.144f, 0.0f); //Background is set to nice blue sky (grayscaled :)
|
|
} else {
|
|
|
|
glClearColor(0.1f, 0.1f, 0.5f, 0.0f); //Background is set to nice blue sky
|
|
}
|
|
|
|
|
|
if (!conf.OFFSCREEN.get() && !conf.OSMESA.get()) {
|
|
|
|
glDrawBuffer(GL_BACK);
|
|
|
|
} else {
|
|
glDrawBuffer(GL_FRONT);
|
|
}
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear screen and depth buffer
|
|
|
|
glLoadIdentity(); //load identity matrix
|
|
|
|
if(! (conf.BW.get() || conf.FOG.get() || conf.STEREO_RB.get() || conf.STEREO_RG.get())) {
|
|
DrawBackground(conf.background.get());
|
|
}
|
|
|
|
if (!conf.ORTHOVIEW.get()) {
|
|
setpos();
|
|
}
|
|
|
|
|
|
// light position was here.... maybe here again for dynamic light-pos moving?
|
|
GLfloat light_position[4] = { 5.0, 5.0, 1.0, 0.0 }; //set the light position
|
|
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
|
|
|
|
|
|
// stereoscopic drawing with 2 images
|
|
if (conf.STEREO.get() && !conf.ORTHOVIEW.get()) {
|
|
|
|
float _ed = conf.eye_dist.get();
|
|
if (conf.SWAP_STEREO.get())
|
|
_ed *= -1.0;
|
|
|
|
|
|
// render left image!
|
|
glViewport(0, 0, conf.getwidth() / 2, conf.getheight());
|
|
ego.moves(-_ed / 2);
|
|
setpos();
|
|
Draw();
|
|
ego.moves(_ed / 2);
|
|
|
|
//render right image!
|
|
glViewport(conf.getwidth() / 2, 0, conf.getwidth() / 2,
|
|
conf.getheight());
|
|
ego.moves(_ed / 2);
|
|
setpos();
|
|
Draw();
|
|
ego.moves(-_ed / 2);
|
|
|
|
glViewport(0, 0, conf.getwidth(), conf.getheight());
|
|
|
|
|
|
}
|
|
// stereoscopic drawing with hardware
|
|
#ifndef ONLY_OSMESA
|
|
if (conf.STEREO_HW.get() && !conf.ORTHOVIEW.get()) {
|
|
|
|
float _ed = conf.eye_dist.get();
|
|
if (conf.SWAP_STEREO.get())
|
|
_ed *= -1.0;
|
|
|
|
|
|
// render left image!
|
|
glDrawBuffer(GL_BACK_LEFT);
|
|
ego.moves(_ed / 2);
|
|
setpos();
|
|
Draw();
|
|
ego.moves(-_ed / 2);
|
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
|
//render right image!
|
|
glDrawBuffer(GL_BACK_RIGHT);
|
|
ego.moves(-_ed / 2);
|
|
setpos();
|
|
Draw();
|
|
ego.moves(_ed / 2);
|
|
|
|
|
|
|
|
|
|
}
|
|
#endif
|
|
|
|
// stereoscopic red/green or red/blue
|
|
if ((conf.STEREO_RB.get() || conf.STEREO_RG.get())
|
|
&& !conf.ORTHOVIEW.get()) {
|
|
|
|
float _ed = conf.eye_dist.get();
|
|
if (conf.SWAP_STEREO.get())
|
|
_ed *= -1.0;
|
|
|
|
|
|
//render red image
|
|
ego.moves(-_ed / 2);
|
|
setpos();
|
|
glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
|
|
|
|
|
|
Draw();
|
|
ego.moves(_ed / 2);
|
|
|
|
glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
|
//render green or blue image
|
|
ego.moves(_ed / 2);
|
|
setpos();
|
|
|
|
if (conf.STEREO_RB.get()) {
|
|
glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE);
|
|
}
|
|
|
|
if (conf.STEREO_RG.get()) {
|
|
glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
|
|
}
|
|
|
|
Draw();
|
|
ego.moves(-_ed / 2);
|
|
|
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
|
}
|
|
|
|
// normal rendering , if no stereo or ortho-mode
|
|
if ((!conf.STEREO.get() && !conf.STEREO_RB.get()
|
|
&& !conf.STEREO_RG.get() && !conf.STEREO_HW.get())
|
|
|| conf.ORTHOVIEW.get()) {
|
|
Draw();
|
|
//cout << "normal" << endl;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!conf.OFFSCREEN.get() && !conf.OSMESA.get()) {
|
|
#ifndef ONLY_OSMESA
|
|
glutSwapBuffers();
|
|
#endif
|
|
} //and swap the buffers
|
|
|
|
|
|
// every frame will be written as jpeg
|
|
if (conf.MOVIE.get()) {
|
|
screenshot();
|
|
}
|
|
|
|
//drawgl.checknow("end");
|
|
|
|
}
|
|
|
|
#ifndef ONLY_OSMESA
|
|
void ReSizeGLScene(int nwidth, int nheight)
|
|
{
|
|
if (nheight == 0) // this shouldnt happen
|
|
nheight = 1;
|
|
|
|
conf.setwidth(nwidth);
|
|
conf.setheight(nheight);
|
|
|
|
//glViewport(0, 0, conf.getwidth(), conf.getheight()); // Reset The Current Viewport
|
|
|
|
InitGL(conf.getwidth(), conf.getheight());
|
|
glutPostRedisplay();
|
|
}
|
|
#endif
|
|
|
|
|
|
// initialize openGL
|
|
void InitGL(int Width, int Height) //set GL-Window size
|
|
{
|
|
|
|
if (conf.DEBUG.get()) {
|
|
cout << "entered void InitGL(WxH)" << Width << "x" << Height << endl << flush;
|
|
//cout << "going to call glPixelstorei(GL_PACK_ALIGNEMENT, 1) ..." << flush;
|
|
}
|
|
|
|
//#ifndef __OSX__
|
|
glPixelStorei(GL_PACK_ALIGNMENT, 1); //Prevents some strange crashes in the glReadPixels in the screenshot-function
|
|
//#else
|
|
// if (conf.DEBUG.get()) {
|
|
// cout << "... (SKIPPED __OSX__) ..." << flush;
|
|
// }
|
|
//#endif
|
|
|
|
/*if (conf.DEBUG.get()) {
|
|
cout << "... returned from glPixelstorei(GL...)" << endl << flush;
|
|
}*/
|
|
|
|
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
|
|
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
|
|
glEnable(GL_NORMALIZE); // Enables normalizing of normal vectors
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
glPolygonMode(GL_FRONT, GL_FILL);
|
|
glDisable(GL_COLOR_MATERIAL);
|
|
glLineWidth(1.0);
|
|
|
|
if (conf.SHADE.get()) {
|
|
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
|
|
} else {
|
|
glShadeModel(GL_FLAT);
|
|
}
|
|
|
|
if (conf.FOG.get()) {
|
|
glEnable(GL_FOG);
|
|
glFogi(GL_FOG_MODE, GL_EXP2);
|
|
glFogf(GL_FOG_DENSITY, conf.fogdensity.get());
|
|
GLfloat fogcolor[4] = { 0.1, 0.1, 0.5, 1.0 };
|
|
|
|
if (!(conf.BW.get() || conf.STEREO_RG.get()
|
|
|| conf.STEREO_RB.get())) {
|
|
glFogfv(GL_FOG_COLOR, fogcolor);
|
|
} else {
|
|
glFogfv(GL_FOG_COLOR, graycolor(fogcolor));
|
|
}
|
|
|
|
|
|
} else {
|
|
glDisable(GL_FOG);
|
|
}
|
|
|
|
|
|
|
|
GLfloat light_ambient[4] = { 0.5, 0.5, 0.5, 1.0 };
|
|
GLfloat light_color[4] = { 0.8, 0.8, 0.8, 1.0 };
|
|
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);
|
|
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
|
|
glEnable(GL_LIGHTING);
|
|
glEnable(GL_LIGHT0);
|
|
//light-position is set in DrawGLScene, after setpos
|
|
|
|
|
|
//set viewport and projection
|
|
glViewport(0, 0, Width, Height);
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity(); // Reset the projection Matrix
|
|
|
|
if (!conf.ORTHOVIEW.get()) {
|
|
|
|
int _q=0;
|
|
double _far;
|
|
glGetIntegerv(GL_DEPTH_BITS, (GLint*) &_q);
|
|
|
|
float screenfactor;
|
|
|
|
float _near;
|
|
|
|
//maybe this can be exactly calculated!
|
|
if (_q < 24) {
|
|
_near = 1.0;
|
|
} else {
|
|
_near = 0.2;
|
|
}
|
|
|
|
if (_q < 24) {
|
|
_far = 300.0;
|
|
} else {
|
|
//_far = 500.0;
|
|
_far = 600.0;
|
|
// cout << "FAR: 600 " <<_q << endl;
|
|
}
|
|
if (_q > 24) {
|
|
_far = 2000.0;
|
|
// cout << "FAR: 2000 " << _q <<endl;
|
|
}
|
|
|
|
if (args_info.clipping_far_given) {
|
|
_far = args_info.clipping_far_arg;
|
|
}
|
|
|
|
if (args_info.clipping_near_given) {
|
|
_near = args_info.clipping_near_arg;
|
|
}
|
|
|
|
if (conf.DEBUG.get()){
|
|
cout << "Depth buffer: " << _q << " bit." <<endl
|
|
<< "Clipping near: " << _near << endl << "Clipping far: "<< _far <<endl;
|
|
|
|
double _s = pow(2.0, _q);
|
|
cout << "depth values: " << _s << endl;;
|
|
double zf = _far * _near / ((1/(double)_s)*(_far-_near) -_far);
|
|
double zb = _far * _near / ((((double)_s-1)/_s) * (_far-_near) -_far);
|
|
cout << "next near: " << zf <<endl<<"next far: "<< zb<<endl;
|
|
|
|
|
|
}
|
|
|
|
float _front_clip_width =
|
|
2.0 * _near * tan(((float) conf.aov.get() / 2.0) *
|
|
(M_PI / 180.0));
|
|
|
|
|
|
if (conf.STEREO.get()) {
|
|
screenfactor =
|
|
((_front_clip_width) *
|
|
((float) conf.getheight() /
|
|
((float) conf.getwidth() / 2.0))) / 2.0;
|
|
} else {
|
|
screenfactor =
|
|
((_front_clip_width) *
|
|
((float) conf.getheight() /
|
|
(float) conf.getwidth())) / 2.0;
|
|
}
|
|
|
|
glFrustum(-_front_clip_width / 2.0,
|
|
_front_clip_width / 2.0, -screenfactor,
|
|
screenfactor, _near,
|
|
_far * conf.getdownscalefactor());
|
|
} else {
|
|
//experimental for now
|
|
|
|
float xclip = (conf.orthoclipping.get() / 2.0); //*(conf.getwidth() / conf.getheight()) ;
|
|
float yclip =
|
|
(conf.orthoclipping.get() / 2.0) *
|
|
((float) conf.getheight() / (float) conf.getwidth());
|
|
|
|
glOrtho(ego.getOx() - xclip, ego.getOx() + xclip,
|
|
ego.getOy() - yclip, ego.getOy() + yclip, -20.0,
|
|
20.0);
|
|
|
|
}
|
|
|
|
//reset MatrixModel to our default state policy
|
|
glMatrixMode(GL_MODELVIEW);
|
|
}
|
|
|
|
void screenshot() {
|
|
|
|
Timecheck sshottime("Screenshot",&conf);
|
|
if ( (strcasecmp(conf.get_image_format().c_str(), "jpg") == 0)
|
|
|| (strcasecmp(conf.get_image_format().c_str(), "jpeg") == 0) )
|
|
screenshot_jpeg();
|
|
|
|
if ( strcasecmp(conf.get_image_format().c_str(),"rgb") == 0)
|
|
screenshot_rgb();
|
|
|
|
sshottime.checknow("");
|
|
|
|
|
|
}
|
|
|
|
|
|
// ersetzt von screenshot_jpeg
|
|
//framebuffer schreibt den framebuffer in ein *.rgb file
|
|
void screenshot_rgb() {
|
|
|
|
short int* rgbmap = new short int[conf.getwidth()*conf.getheight()*3];
|
|
|
|
|
|
glReadPixels(0,0,conf.getwidth(),conf.getheight(),GL_RGB,GL_UNSIGNED_SHORT,rgbmap);
|
|
|
|
|
|
char name[1024];
|
|
//char _buff[2];
|
|
|
|
cout << "writing a rgb " << conf.getwidth() << "x" << conf.getheight() << " picture with 6 Byte per Pixel" << endl;
|
|
|
|
std::string basename = conf.get_basename();
|
|
std::string path = conf.get_save_path();
|
|
if (args_info.basename_given) { basename = args_info.basename_arg; }
|
|
if (args_info.save_path_given) { path = args_info.save_path_arg + SEPERATOR; }
|
|
|
|
|
|
if (args_info.os_outfile_given) {
|
|
sprintf(name, "%s", args_info.os_outfile_arg);
|
|
} else {
|
|
|
|
ifstream testfile;
|
|
|
|
while (1) {
|
|
sprintf(name, "%s%s%d.rgb", path.c_str(), basename.c_str(), conf.getnextframewriternumber());
|
|
//cout << name << " geht nixht" << endl;
|
|
testfile.open(name, ios::binary);
|
|
if (!testfile) {break;}
|
|
testfile.close();
|
|
//cout << name << " NEIN gibt schon" << endl;
|
|
}
|
|
//cout << name << " geht!!!!" << endl;
|
|
}
|
|
|
|
ofstream framefile;
|
|
framefile.open(name, ios::binary);
|
|
|
|
// for (int _z=0 ;_z < (width*height*3); _z++){
|
|
// framefile.write((char*)&rgbmap[_z],2);
|
|
// }
|
|
|
|
for (int _z=(conf.getwidth()*(conf.getheight()-1)*3); _z>=0; _z=_z-conf.getwidth()*3) {
|
|
for (int _s=0; _s<conf.getwidth()*3; _s++) {
|
|
framefile.write((char*)&rgbmap[_z+_s],2);
|
|
}
|
|
}
|
|
|
|
|
|
cout << name << " written." << endl <<flush;
|
|
//cout << sizeof (GLushort) << endl;
|
|
delete [] rgbmap;
|
|
|
|
}
|
|
|
|
|
|
|
|
void screenshot_jpeg()
|
|
{
|
|
|
|
// rendering in the GL_BACK buffer and reading from it will only work on
|
|
// software GL. If GL_BACK is a hardware buffer it wont work
|
|
// maybe they dont render overlayed regions of the buffer.
|
|
// we will read from (GL_FRONT)
|
|
|
|
glFinish();
|
|
|
|
unsigned char *tmpArray, *jpegArray;
|
|
int quality = conf.jpeg_quality.get();
|
|
char name[1024];
|
|
int index = 0;
|
|
|
|
tmpArray =
|
|
new unsigned char[conf.getwidth() * conf.getheight() * 3];
|
|
jpegArray =
|
|
new unsigned char[conf.getwidth() * conf.getheight() * 3];
|
|
|
|
if (conf.OSMESA.get())
|
|
glReadBuffer(GL_FRONT);
|
|
|
|
if (conf.OFFSCREEN.get())
|
|
glReadBuffer(GL_FRONT);
|
|
|
|
glFinish();
|
|
|
|
|
|
|
|
glReadPixels(0, 0, conf.getwidth(), conf.getheight(), GL_RGB,
|
|
GL_UNSIGNED_BYTE, tmpArray);
|
|
|
|
|
|
|
|
index = 0;
|
|
for (int _z = (conf.getwidth() * (conf.getheight() - 1) * 3);
|
|
_z >= 0; _z = _z - conf.getwidth() * 3) {
|
|
for (int _s = 0; _s < conf.getwidth() * 3; _s++) {
|
|
jpegArray[index] = tmpArray[_z + _s];
|
|
index++;
|
|
}
|
|
}
|
|
|
|
|
|
if (conf.VERBOSE.get()) {
|
|
cout << "writing a " << conf.getwidth() << "x" << conf.
|
|
getheight() << " jpg image" << endl;
|
|
cout << "jpeg quality: " << conf.jpeg_quality.get() << endl;
|
|
}
|
|
|
|
std::string basename = conf.get_basename();
|
|
std::string path = conf.get_save_path();
|
|
if (args_info.basename_given) { basename = args_info.basename_arg; }
|
|
if (args_info.save_path_given) { path = args_info.save_path_arg + SEPERATOR; }
|
|
|
|
if (args_info.os_outfile_given) {
|
|
sprintf(name, "%s", args_info.os_outfile_arg);
|
|
} else {
|
|
ifstream testfile;
|
|
while (1) {
|
|
sprintf(name, "%s%s%d.jpg", path.c_str(), basename.c_str(), conf.getnextframewriternumber());
|
|
//cout << name << " geht nixht" << endl;
|
|
testfile.open(name, ios::binary);
|
|
if (!testfile) {break;}
|
|
testfile.close();
|
|
//cout << name << " NEIN gibt schon" << endl;
|
|
}
|
|
//cout << name << " geht!!!!" << endl;
|
|
}
|
|
|
|
//sprintf(name, "%s%s%d.jpg", path.c_str(), basename.c_str(), conf.getnextframewriternumber());
|
|
|
|
//sprintf(name, "frame%d.jpg", conf.getnextframewriternumber());
|
|
|
|
//if (args_info.os_outfile_given) {
|
|
|
|
// sprintf(name, "%s", args_info.os_outfile_arg);
|
|
|
|
//}
|
|
|
|
write_JPEG_file(conf.getwidth(), conf.getheight(), quality, name,
|
|
(JSAMPLE *) jpegArray);
|
|
|
|
if (conf.VERBOSE.get())
|
|
cout << "jpeg: " << name << " written ! " << endl <<
|
|
flush;
|
|
|
|
delete tmpArray;
|
|
delete jpegArray;
|
|
|
|
}
|
|
|
|
|
|
#ifndef ONLY_OSMESA
|
|
void IdleFunc(void)
|
|
{
|
|
|
|
//needed in movie mode, to decide whether to repeat frame, or to move marker forward
|
|
bool FORWARD=false;
|
|
bool REPEAT=false;
|
|
|
|
if (conf.JOYSTICK.get() && !conf.ORTHOVIEW.get()) {
|
|
glutForceJoystickFunc();
|
|
}
|
|
|
|
// determine framerate;
|
|
|
|
timeval now;
|
|
timeval last;
|
|
//timezone zone;
|
|
|
|
//zone.tz_minuteswest = 0;
|
|
//zone.tz_dsttime = DST_NONE;
|
|
|
|
gettimeofday(&now, NULL);
|
|
|
|
last = conf.get_time_mem();
|
|
conf.set_time_mem(now);
|
|
|
|
//cout << "last : " << last.tv_sec << " " << last.tv_usec << endl;
|
|
//cout << "now : " << now.tv_sec << " " << now.tv_usec << endl;
|
|
|
|
float rate =
|
|
1.0 / (((float) now.tv_sec - (float) last.tv_sec)
|
|
+
|
|
(((float) now.tv_usec -
|
|
(float) last.tv_usec) / 1000000.0));
|
|
|
|
//cout << "rate: " << rate << endl;
|
|
conf.set_framerate(rate);
|
|
conf.set_fps(rate);
|
|
|
|
|
|
|
|
// conf.movi_msec is millisecs usleep is in microseconds!
|
|
if (conf.FLYING.get() && !conf.GPSD.get() ) {
|
|
usleep((unsigned long int) conf.movie_msecs.get() * 1000);
|
|
|
|
if (conf.FLYING_REPEAT.get())
|
|
REPEAT=true;
|
|
if (conf.FLYING_AUTO_REPEAT.get()) {
|
|
if (conf.get_fps() > conf.idle_auto_repeat_limit.get()) {
|
|
//cout << "fps exceeeds limit" << endl;
|
|
REPEAT=true;
|
|
}
|
|
}
|
|
|
|
if (REPEAT) {
|
|
movie_repeat_counter++;
|
|
//cout << "repeater : "<< movie_repeat_counter << endl;
|
|
if (movie_repeat_counter >= conf.movie_repeat_factor.get()) {
|
|
movie_repeat_counter=0;
|
|
FORWARD=true;
|
|
}
|
|
} else {
|
|
FORWARD=true;
|
|
}
|
|
}
|
|
/*
|
|
// update date in GPSD mode
|
|
if (conf.GPSD.get())
|
|
fd.querygps();
|
|
|
|
// FLYING with GPSD: marker is kept at recent position!
|
|
if (conf.FLYING.get() && conf.GPSD.get() ) {
|
|
fd.marker_head();
|
|
}
|
|
*/
|
|
if (conf.SPINNING.get() != 0) {
|
|
ego.spinmoveradialpoint(conf.SPINNING.get(), fd.getmarkerx(), fd.getmarkery() ); //spin the ego around the marker
|
|
if (conf.FOLLOW.get())
|
|
update_diff_pos();
|
|
}
|
|
|
|
|
|
if (conf.GPSD.get()) {
|
|
if (fd.querygps() == 0) { // new data;
|
|
if (conf.FLYING.get())
|
|
fd.marker_head();
|
|
GenFlightList();
|
|
|
|
// leaving area!
|
|
|
|
//cout << fd.getlat() << " " << fd.getlon() << endl;
|
|
//cout <<"lim: "<< fd.getcenter_lat()+(conf.getborder_land_lat()/DEGDIST) <<
|
|
//" " << fd.getcenter_lat()-(conf.getborder_land_lat()/DEGDIST) << endl;
|
|
//cout << "lim2: " << fd.getcenter_lon()+(conf.getborder_land_lon()/DEGDIST)
|
|
//<< " " << fd.getcenter_lon()-(conf.getborder_land_lon()/DEGDIST) << endl;
|
|
|
|
if (conf.LANDSCAPE.get() && !conf.MAP.get()) {
|
|
// hier noch die limits checken
|
|
// in lat gehts manchmal ueber die kante..? ZZZZZ
|
|
// immer noch? sieht ganz gut aus soweit
|
|
if (fd.getlat() > fd.getcenter_lat()-conf.getdem_grid_lat()*conf.getdownscalefactor()+((conf.getborder_land_lat()-0.0)/DEGDIST)
|
|
|| fd.getlat() < fd.getcenter_lat()+conf.getdem_grid_lat()*conf.getdownscalefactor()-((conf.getborder_land_lat()-0.0)/DEGDIST)
|
|
|| fd.getlon() > fd.getcenter_lon()-conf.getdem_grid_lon()*conf.getdownscalefactor()+(((conf.getborder_land_lon()-0.0)/DEGDIST)/
|
|
cos(fd.getcenter_lat() * PI_180))
|
|
|| fd.getlon() < fd.getcenter_lon()+conf.getdem_grid_lon()*conf.getdownscalefactor()-(((conf.getborder_land_lon()-0.0)/DEGDIST)/
|
|
cos(fd.getcenter_lat() * PI_180))
|
|
) {
|
|
|
|
//cout << "REBUILDING LANDSCAPE" << endl;
|
|
fd.setcenter_lat(fd.getlat());
|
|
fd.setcenter_lon(fd.getlon());
|
|
fd.setlatmin(fd.getlat());
|
|
fd.setlatmax(fd.getlat());
|
|
fd.setlonmax(fd.getlon());
|
|
fd.setlonmin(fd.getlon());
|
|
GenLandscapeList();
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
// forward exits only in flying mode without gpsd
|
|
if (FORWARD && conf.FLIGHT.get()) {
|
|
fd.forward_marker();
|
|
|
|
if (fd.getcycles() == 0)
|
|
Ende(0);
|
|
|
|
// wenn marker bewegt neue flightlist machen
|
|
if (conf.MARKER_RANGE.get()) {
|
|