gpligc/src/GLexplorer.cpp

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()) {
GenFlightList();
}
#ifndef __WIN32__
update_shmem();
#endif
}
if (conf.FOLLOW.get())
update_locked_pos();
glutPostRedisplay();
}
#endif
#ifndef ONLY_OSMESA
//joystick function
void joystick(unsigned int buttonMask, int x, int y, int z)
{
if (conf.DEBUG.get())
cout << "Joystick: ButtonMask: " << buttonMask << " X=" << x
<< " Y=" << y << " Z=" << z << " " << '\r' << flush;
ego.movef(0.2 * conf.joyfac_y.get() * (float) y * conf.getdownscalefactor());
ego.moves(-0.2 * conf.joyfac_x.get() * (float) x * conf.getdownscalefactor());
ego.movez(-0.05 * conf.joyfac_z.get() * (float) z * conf.getdownscalefactor());
// here is something wrong...
// "flying-mode, follow-mode... ?!
// update the diff-pos, only if we really have moved!
if (conf.FOLLOW.get() && (x != 0 || y!=0 || z!=0))
update_diff_pos();
}
#endif
#ifndef ONLY_OSMESA
// Keyboard callback
void keyPressed(unsigned char key, int x, int y)
{
//not too fast
usleep(100);
/*if (conf.DEBUG.get())
cout << "Key: \"" << key << "\" pressed." << endl << flush;*/
if (HELP || INFO) {
HELP = false;
INFO = false;
glutPostRedisplay();
return;
}
// escape?
if (key == ESCAPE || key == 'q') {
Ende(0);
}
// MOVING
// some things do not make sense in ORTHO-MODE
if (!conf.ORTHOVIEW.get()) {
if (key == 't') {
ego.movez(0.05 * conf.getdownscalefactor());
if (conf.FOLLOW.get()) {
update_diff_pos();
}
}
if (key == 'z') {
ego.movez(-0.05 * conf.getdownscalefactor());
if (conf.FOLLOW.get()) {
update_diff_pos();
}
}
if (key == 'd') {
ego.moves(0.2 * conf.getdownscalefactor());
if (conf.FOLLOW.get()) {
update_diff_pos();
}
}
if (key == 'f') {
ego.moves(-0.2 * conf.getdownscalefactor());
if (conf.FOLLOW.get()) {
update_diff_pos();
}
}
}
if (key == 'g') {
if (!conf.ORTHOVIEW.get()) {
ego.movef(-0.2 * conf.getdownscalefactor());
if (conf.FOLLOW.get()) {
update_diff_pos();
}
} else {
float zoomfac = 1;
if (conf.orthoclipping.get() < 5) {
zoomfac = conf.orthoclipping.get()/50.0;
}
conf.orthoclipping.dec(2.0 *
conf.getdownscalefactor()
* zoomfac
);
//InitGL(conf.getwidth(), conf.getheight());
}
}
if (key == 's') {
if (!conf.ORTHOVIEW.get()) {
ego.movef(0.2 * conf.getdownscalefactor());
if (conf.FOLLOW.get()) {
update_diff_pos();
}
} else {
float zoomfac = 1;
if (conf.orthoclipping.get() < 5) {
zoomfac = conf.orthoclipping.get()/50.0;
}
conf.orthoclipping.inc(2.0 *
conf.getdownscalefactor()
* zoomfac
);
//InitGL(conf.getwidth(), conf.getheight());
}
}
if (key == ' ') {
if (!conf.ORTHOVIEW.get()) {
ego.movef(-1.0 * conf.getdownscalefactor());
if (conf.FOLLOW.get()) {
update_diff_pos();
}
} else {
conf.orthoclipping.dec(10.0 *
conf.getdownscalefactor());
//InitGL(conf.getwidth(), conf.getheight());
}
}
if (key == 'a') {
if (!conf.ORTHOVIEW.get()) {
ego.movef(1.0 * conf.getdownscalefactor());
if (conf.FOLLOW.get()) {
update_diff_pos();
}
} else {
conf.orthoclipping.inc(10.0 *
conf.getdownscalefactor());
//InitGL(conf.getwidth(), conf.getheight());
}
}
if (!conf.ORTHOVIEW.get()) {
if (key == '+')
conf.z_scale.inc(0.1);
// GenPointsList();
if (key == '-')
conf.z_scale.dec(0.1);
// GenPointsList();
}
// You cant get lower than fd.getzmin()+0.02
if (ego.getz() <
(fd.getzmin() + ((float) conf.offset.get() / 1000.0) +
0.05) * conf.z_scale.get()) {
ego.setz((fd.getzmin() +
((float) conf.offset.get() / 1000.0) +
0.05) * conf.z_scale.get());
}
if (key == 'P')
conf.MOVIE.toggle();
//Curtain
if (key == 'h') {
menuMain(21);
}
if (key == 'p') {
screenshot();
}
if (key == 'm') {
conf.MOUSE.toggle();
if (conf.MOUSE.get()) {
glutPassiveMotionFunc(NULL);
//glutMotionFunc(&mouseClickMove);
glutSetCursor(GLUT_CURSOR_INHERIT);
} else {
//lastmx =0; lastmy =0;
glutWarpPointer(conf.getwidth() / 2,
conf.getheight() / 2);
MOUSEWARPED = true;
glutPassiveMotionFunc(&mouseMove);
//glutMotionFunc(NULL);
glutSetCursor(GLUT_CURSOR_NONE);
}
}
//adjusting offset
if (key == 'u') {
conf.offset.inc(1);
GenFlightList();
}
if (key == 'i') {
conf.offset.dec(1);
GenFlightList();
}
if (key == 'w') {
if (conf.FULLSCREEN.get()) {
glutReshapeWindow(conf.getinitwidth(),
conf.getinitheight());
conf.setwidth(conf.getinitwidth());
conf.setheight(conf.getinitheight());
conf.FULLSCREEN.toggle();
} else {
glutFullScreen();
//glutEnterGameMode();
conf.FULLSCREEN.toggle();
}
}
//switch on/off textured maps
if (key == 'b') {
menuMain(1);
}
if (key == 'j') {
menuMain(12);
}
if (key == '9') {
conf.fogdensity.dec(0.001);
InitGL(conf.getwidth(), conf.getheight());
//cout << conf.fogdensity.get() << endl;
}
if (key == '0') {
conf.fogdensity.inc(0.001);
InitGL(conf.getwidth(), conf.getheight());
//cout << conf.fogdensity.get() << endl;
}
if (key == '7') {
conf.aov.inc(1);
//cout << conf.getFrust()<< endl;
InitGL(conf.getwidth(), conf.getheight());
}
if (key == '8') {
conf.aov.dec(1);
//cout << conf.getFrust()<< endl;
InitGL(conf.getwidth(), conf.getheight());
}
if (key == 'l') {
menuMain(11);
}
if (key == 'L') {
conf.WIRE.toggle();
if ((!conf.MAP.get() || conf.LANDSCAPE.get())
&& !(conf.MAP.get() && conf.LANDSCAPE.get())) {
GenFlightList();
GenLandscapeList();
}
}
if (key == 'o') {
menuMain(41);
}
if (key == 'O') {
conf.SHADE.toggle();
InitGL(conf.getwidth(), conf.getheight());
}
if (key == '1' && conf.colmapnumber.get() != 1) {
menuColormap(1);
}
if (key == '2' && conf.colmapnumber.get() != 2) {
menuColormap(2);
}
if (key == '3' && conf.colmapnumber.get() != 3) {
menuColormap(3);
}
if (key == '4' && conf.colmapnumber.get() != 4) {
menuColormap(4);
}
if (key == '5' && conf.colmapnumber.get() != 5) {
menuColormap(5);
}
if (key == '6' && conf.colmapnumber.get() != 6) {
menuColormap(6);
}
if (key == 'x') {
int tmp = conf.ActiveMapSet.get();
conf.ActiveMapSet.dec(1);
if ((tmp != conf.ActiveMapSet.get()) && conf.MAP.get()) {
GenLandscapeList();
}
}
if (key == 'X') {
conf.NOLIGHTING.toggle();
GenLandscapeList();
}
if (key == 'c') {
int tmp = conf.ActiveMapSet.get();
conf.ActiveMapSet.inc(1);
if ((tmp != conf.ActiveMapSet.get()) && conf.MAP.get()) {
GenLandscapeList();
}
}
if (key == 'y') {
conf.COMPRESSION.toggle();
if (conf.MAP.get()) {
GenLandscapeList();
}
}
if (key == 'A') {
conf.SWAP_STEREO.toggle();
}
if (key == 'S') {
if (conf.STEREO.get()) {
menuStereo(1);
} else {
menuStereo(2);
}
}
// Black and white
if (key == 'B') {
conf.BW.toggle();
if (!(conf.STEREO_RG.get() || conf.STEREO_RB.get())) {
GenLandscapeList();
GenFlightList();
GenAirspaceList();
InitGL(conf.getwidth(), conf.getheight());
}
}
if (key == 'D') {
if (conf.STEREO_RG.get()) {
menuStereo(1);
} else {
menuStereo(3);
}
}
if (key == 'F') {
if (conf.STEREO_RB.get()) {
menuStereo(1);
} else {
menuStereo(4);
}
}
if (key == 'Q') {
conf.eye_dist.dec(0.05);
}
if (key == 'W') {
conf.eye_dist.inc(0.05);
}
//cout << int(key) << " key" << endl;
if (key == 'U') {
menuMain(34);
}
if (key == 'M') {
menuMain(33);
}
if (key == 'I') {
menuMain(35);
}
if (key == 'J')
menuMain(36);
glutPostRedisplay();
}
#endif
#ifndef ONLY_OSMESA
void SpecialKeyPressed(int key, int x, int y)
{
if (HELP || INFO) {
HELP = false;
INFO = false;
glutPostRedisplay();
return;
}
// no modifiers!
if (glutGetModifiers() != GLUT_ACTIVE_SHIFT &&
glutGetModifiers() != GLUT_ACTIVE_CTRL &&
glutGetModifiers() != GLUT_ACTIVE_ALT) {
if (key == GLUT_KEY_F1) {
fd.fbackward_marker();
if (conf.FOLLOW.get()) {
update_locked_pos();
}
if (conf.MARKER_RANGE.get()) {
GenFlightList();
}
//cout << fd.getmarker() << endl;
#ifndef __WIN32__
update_shmem();
#endif
}
if (key == GLUT_KEY_F2) {
fd.backward_marker();
if (conf.FOLLOW.get()) {
update_locked_pos();
}
if (conf.MARKER_RANGE.get()) {
GenFlightList();
}
//cout << fd.getmarker() << endl;
#ifndef __WIN32__
update_shmem();
#endif
}
if (key == GLUT_KEY_F3) {
fd.forward_marker();
if (conf.FOLLOW.get()) {
update_locked_pos();
}
if (conf.MARKER_RANGE.get()) {
GenFlightList();
}
//cout << fd.getmarker() << endl;
#ifndef __WIN32__
update_shmem();
#endif
}
if (key == GLUT_KEY_F4) {
fd.fforward_marker();
if (conf.FOLLOW.get()) {
update_locked_pos();
}
if (conf.MARKER_RANGE.get()) {
GenFlightList();
}
//cout << fd.getmarker() << endl;
#ifndef __WIN32__
update_shmem();
#endif
}
if (key == GLUT_KEY_F5) {
setinitpos();
}
if (key == GLUT_KEY_F6) {
menuMain(32);
}
if (key == GLUT_KEY_F7) {
menuMain(31);
//cout << "toggel marker" << endl;
}
if (key == GLUT_KEY_F8) {
menuMain(2);
}
if (key == GLUT_KEY_F9) {
menuMain(13);
}
if (key == GLUT_KEY_F10) {
if (conf.colmap2number.get() >=
conf.colmap2number.getmin() + 1) {
//conf.colmap2number.dec(1);
menuColormap_sea(conf.colmap2number.get() -
1);
//GenLandscapeList();
}
}
if (key == GLUT_KEY_F11) {
if (conf.colmap2number.get() <=
conf.colmap2number.getmax() - 1) {
//conf.colmap2number.inc(1);
menuColormap_sea(conf.colmap2number.get() +
1);
//GenLandscapeList();
}
}
if (key == GLUT_KEY_F12) {
conf.WAYPOINTS.toggle();
}
// Rotations around marker pos (by A. Somers)
// arrow-keys without mofifiers
if (key == GLUT_KEY_LEFT) {
ego.spinmoveradialpoint(1, fd.getmarkerx(), fd.getmarkery() ); //spin the ego around the marker
if (conf.FOLLOW.get())
update_diff_pos();
}
if (key == GLUT_KEY_UP) {
ego.spinmoveverticalpoint(1, fd.getmarkerx(), fd.getmarkery() ); //spin the ego around the marker
if (conf.FOLLOW.get())
update_diff_pos();
}
if (key == GLUT_KEY_RIGHT) {
ego.spinmoveradialpoint(-1, fd.getmarkerx(), fd.getmarkery() ); //spin the ego around the marker
if (conf.FOLLOW.get())
update_diff_pos();
}
if (key == GLUT_KEY_DOWN) {
ego.spinmoveverticalpoint(-1, fd.getmarkerx(), fd.getmarkery() ); //spin the ego around the marker
if (conf.FOLLOW.get())
update_diff_pos();
}
if (key == GLUT_KEY_PAGE_UP) {
conf.MARKER_SIZE.inc(0.02);
}
if (key == GLUT_KEY_PAGE_DOWN) {
conf.MARKER_SIZE.dec(0.02);
}
if (key == GLUT_KEY_HOME) {
conf.lifts_info_mode.inc(1);
}
if (key == GLUT_KEY_END) {
conf.lifts_info_mode.dec(1);
}
if (key == GLUT_KEY_INSERT) {
cout << "insert unused" << endl;
}
} // end no modifiers
//modifier shift
if (glutGetModifiers() == GLUT_ACTIVE_SHIFT) {
if (key == GLUT_KEY_F1) {
conf.movie_repeat_factor.dec(2);
// warum dies?
//if (conf.FLYING.get()) {
// glutIdleFunc(&IdleFunc);
//}
}
if (key == GLUT_KEY_F2) {
conf.movie_repeat_factor.inc(2);
//if (conf.FLYING.get()) {
// glutIdleFunc(&IdleFunc);
//}
}
if (key == GLUT_KEY_F3) {
conf.flightstrip_width.dec(1.0);
GenFlightList();
}
if (key == GLUT_KEY_F4) {
conf.flightstrip_width.inc(1.0);
GenFlightList();
}
if (key == GLUT_KEY_F5) {
conf.flightstrip_mode.dec(1);
GenFlightList();
}
if (key == GLUT_KEY_F6) {
conf.flightstrip_mode.inc(1);
GenFlightList();
}
if (key == GLUT_KEY_F7) {
conf.flightstrip_colmap.dec(1);
GenFlightList();
}
if (key == GLUT_KEY_F8) {
conf.flightstrip_colmap.inc(1);
GenFlightList();
}
if (key == GLUT_KEY_F9) {
conf.AIRSPACE_WIRE.toggle();
GenAirspaceList();
}
if (key == GLUT_KEY_F10) {
cout << "shift-f10 unused" << endl;
}
if (key == GLUT_KEY_F11) {
cout << "shift-f11 unused" << endl;
}
if (key == GLUT_KEY_F12) {
cout << "Shift F12 glGetError" << endl;
cout << "glGetError: " << gluErrorString(glGetError()) << endl;
}
//rotations around the center of the scene
// with shift
if (key == GLUT_KEY_LEFT) {
ego.spinmoveradial(1); //spin the ego around the center
if (conf.FOLLOW.get())
update_diff_pos();
}
if (key == GLUT_KEY_UP) {
ego.spinmovevertical(1); //spin the ego around the center vertically
if (conf.FOLLOW.get())
update_diff_pos();
}
if (key == GLUT_KEY_RIGHT) {
ego.spinmoveradial(-1); //spin the ego around the center
if (conf.FOLLOW.get())
update_diff_pos();
}
if (key == GLUT_KEY_DOWN) {
ego.spinmovevertical(-1); //spin the ego around the center vertically
if (conf.FOLLOW.get())
update_diff_pos();
}
if (key == GLUT_KEY_PAGE_UP) {
conf.pTextSize.inc(0.0005);
}
if (key == GLUT_KEY_PAGE_DOWN) {
conf.pTextSize.dec(0.0005);
}
if (key == GLUT_KEY_HOME) {
conf.waypoints_info_mode.inc(1);
}
if (key == GLUT_KEY_END) {
conf.waypoints_info_mode.dec(1);
}
/*
if (key == GLUT_KEY_HOME) {
cout << "shift-home unused" << endl;
}
if (key == GLUT_KEY_END) {
cout << "shift-end unused" << endl;
}*/
if (key == GLUT_KEY_INSERT) {
cout << "shift-insert unused" << endl;
}
} // end shift modifier
glutPostRedisplay();
}
#endif
#ifndef ONLY_OSMESA
void update_diff_pos()
{
if (!conf.FLIGHT.get())
return;
double _x = 0, _y = 0, _z = 0;
for (int _i = fd.getmarker() - 10; _i <= fd.getmarker() + 10; _i++) {
int _c;
_c = _i;
if (_i < 0) {
_c = 0;
}
if (_i >= fd.getn()) {
_c = fd.getn() - 1;
}
_x += -fd.getx(_c);
_y += -fd.gety(_c);
_z += fd.getz(_c) * conf.z_scale.get();
}
_x /= 21;
_y /= 21;
_z /= 21;
ego.setdx(ego.getx() - _x); //fd.getx(fd.getmarker()));
ego.setdy(ego.gety() - _y); //fd.gety(fd.getmarker()));
ego.setdz(ego.getz() - _z);
// (fd.getz(fd.getmarker()) * conf.z_scale.get()));
ego.setdox(ego.getOx() + _x);
ego.setdoy(ego.getOy() + _y);
//cout << "diff updated" << endl;
}
#endif
#ifndef ONLY_OSMESA
void update_locked_pos()
{
if (!conf.FLIGHT.get())
return;
double _x = 0, _y = 0, _z = 0;
for (int _i = fd.getmarker() - 10; _i <= fd.getmarker() + 10; _i++) {
int _c;
_c = _i;
if (_i < 0) {
_c = 0;
}
if (_i >= fd.getn()) {
_c = fd.getn() - 1;
}
_x += -fd.getx(_c);
_y += -fd.gety(_c);
_z += fd.getz(_c) * conf.z_scale.get();
}
_x /= 21;
_y /= 21;
_z /= 21;
ego.setx(ego.getdx() + _x);
ego.sety(ego.getdy() + _y);
ego.setz(ego.getdz() + _z);
ego.setOx(ego.getdox() - _x);
ego.setOy(ego.getdoy() - _y);
if (conf.ORTHOVIEW.get())
InitGL(conf.getwidth(), conf.getheight());
}
#endif
void DrawInfo(void)
{
//int font_height = int(glutGet(GLUT_WINDOW_HEIGHT) / 30);
int font_height = conf.getheight() / conf.info_fontsize.get();
//cout << font_height << "fh" << endl;
vector < string > lines;
char buf[256];
if (args_info.text_given) {
//if (args_info.text_arg.length() < 256) {
//sprintf(buf, args_info.text_arg);
//lines.push_back(buf);
lines.push_back(args_info.text_arg);
//} else {lines.push_back("too long");}
}
if (!args_info.no_position_info_given) {
if (!conf.ORTHOVIEW.get()) {
sprintf(buf, "Heading: %.0f", ego.getspinz());
lines.push_back(buf);
sprintf(buf, "Dive angle: %.0f", 270 - ego.getspinx());
lines.push_back(buf);
int alt =
int ((ego.getz() * 1000 / conf.z_scale.get()) *
conf.getalt_unit_fac());
sprintf(buf, "Altitude: %d %s", alt,
conf.getalt_unit_name().c_str());
lines.push_back(buf);
float lat, lon;
proj.get_latlon(-ego.getx(), -ego.gety(), lat, lon);
sprintf(buf, "Lat: %.4f", lat);
lines.push_back(buf);
sprintf(buf, "Lon: %.4f", lon);
lines.push_back(buf);
sprintf(buf, "Angle of view %d", conf.aov.get());
lines.push_back(buf);
if (conf.JOYSTICK.get()) {
sprintf(buf, "Joystick mode on");
lines.push_back(buf);
}
if (conf.STEREO_HW.get () || conf.STEREO.get () || conf.STEREO_RG.get () || conf.STEREO_RB.get ()) {
sprintf(buf, "Eye distance: %.2f",conf.eye_dist.get());
lines.push_back(buf);
}
} else {
float lat, lon;
proj.get_latlon(ego.getOx(), ego.getOy(), lat, lon);
sprintf(buf, "Lat: %.4f", lat);
lines.push_back(buf);
sprintf(buf, "Lon: %.4f", lon);
lines.push_back(buf);
}
}
if (!args_info.no_marker_pos_info_given) {
if (conf.MARKER.get()) {
if (!args_info.no_position_info_given) {
lines.push_back("----------"); }
if (conf.GPSD.get() ) {
lines.push_back(fd.serverstring.c_str());
}
if (conf.GPSD.get() && conf.FLYING.get() ) {
sprintf(buf, "GPS live mode / Position:");
lines.push_back(buf);
}
if (conf.GPSD.get() && !conf.FLYING.get() ) {
sprintf(buf, "GPS live mode / Marker:");
lines.push_back(buf);
}
sprintf(buf, "Lat: %.4f", fd.getlat());
lines.push_back(buf);
sprintf(buf, "Lon: %.4f", fd.getlon());
lines.push_back(buf);
float offsetgps, offsetbaro;
if (conf.GPSALT.get()) {
offsetgps = conf.offset.get();
offsetbaro = 0;
} else {
offsetgps = 0;
offsetbaro = conf.offset.get();
}
if (!conf.GPSALT.get()) {
sprintf(buf, "Alt (baro, MSL): %.0f %s",
(fd.getalt() +
offsetbaro) * conf.getalt_unit_fac(),
conf.getalt_unit_name().c_str());
lines.push_back(buf);
sprintf(buf, "Alt (baro, GND): %.0f %s",
((fd.getalt() + offsetbaro) -
fd.getgndelevation()) *
conf.getalt_unit_fac(),
conf.getalt_unit_name().c_str());
lines.push_back(buf);
} else {
sprintf(buf, "Alt (GPS, MSL): %.0f %s",
(fd.getgpsalt() +
offsetgps) * conf.getalt_unit_fac(),
conf.getalt_unit_name().c_str());
lines.push_back(buf);
sprintf(buf, "Alt (GPS, GND): %.0f %s",
((fd.getgpsalt() + offsetgps) -
fd.getgndelevation()) *
conf.getalt_unit_fac(),
conf.getalt_unit_name().c_str());
lines.push_back(buf);
}
if (conf.offset.get() != 0) {
sprintf(buf, "Calibration offset: %d m",
conf.offset.get());
lines.push_back(buf);
}
sprintf(buf, "Surface elevation (MSL): %.0f %s",
fd.getgndelevation() * conf.getalt_unit_fac(),
conf.getalt_unit_name().c_str());
lines.push_back(buf);
if (conf.GPSD.get()) {
sprintf(buf, "Sat_vis/Sat_used/Mode: %.0f/%.0f/%.0fD",
fd.getsatvis(), fd.getsatused(), fd.getgpsmode());
lines.push_back(buf);
sprintf(buf, "eph/epv: %.0f/%.0f m",
fd.geteph(), fd.getepv());
lines.push_back(buf);
/* // rubbish?
sprintf(buf, "eps/epc: %.2fkm/h / %.2fm/s",
fd.geteps(), fd.getepc());
lines.push_back(buf);
*/
sprintf(buf,"GPS interruptions: %d",fd.getgpsinterruptions());
lines.push_back(buf);
}
sprintf(buf, "Markerpos: %d",
fd.getmarker());
lines.push_back(buf);
sprintf(buf, "Time (%s): %s", conf.getTimeZoneName().c_str(), fd.gettime().c_str());
lines.push_back(buf);
double drawvario, drawintvario;
string gpsadd = "(baro)";
if (conf.GPSALT.get()) {
drawvario = fd.getgpsvario();
drawintvario = fd.getgpsintvario(10);
gpsadd = "(gps)";
} else {
drawvario = fd.getvario();
drawintvario = fd.getintvario(10);
}
sprintf(buf, "Vario %s: %.2f %s", gpsadd.c_str(),
drawvario * conf.getvspeed_unit_fac(),
conf.getvspeed_unit_name().c_str());
lines.push_back(buf);
sprintf(buf, "Int.Vario %s: %.2f %s", gpsadd.c_str(),
drawintvario * conf.getvspeed_unit_fac(),
conf.getvspeed_unit_name().c_str());
lines.push_back(buf);
sprintf(buf, "Groundspeed: %.0f %s",
fd.getspeed() * conf.getspeed_unit_fac(),
conf.getspeed_unit_name().c_str());
lines.push_back(buf);
}
}
if (conf.FLYING.get() || conf.JOYSTICK.get() || conf.GPSD.get()) {
if (conf.VERBOSE.get()) {
sprintf(buf, "FPS: %.1f", conf.get_fps());
lines.push_back(buf);
}
if (conf.FLYING.get() && conf.VERBOSE.get() && !conf.GPSD.get()) {
sprintf(buf, "Framerepeat: %dx", conf.movie_repeat_factor.get());
lines.push_back(buf);
}
}
if (conf.GPSD.get()) {
if (fd.getvalidfix() == 0) {
sprintf(buf,"NO GPS SIGNAL!");
lines.push_back(buf);
}
}
//glLineWidth(2.0);
glLineWidth(conf.info_fontwidth.get());
if (conf.style.get() == 1) {
gltextvect(5, conf.getheight(),
font_height, lines, conf.getwidth(),
conf.getheight(),conf.ORTHOVIEW.get());
}
if (conf.style.get() == 2) {
for (int z=0; z<=(int(lines.size()-1)); z++) {
gltext(5, conf.getheight()-(font_height*(z+1)),
font_height, lines[z].c_str(), conf.getwidth(),
conf.getheight());
}
}
glLineWidth(1.0);
}
// this function sets the initial position! (at start and at F5-key)
void setinitpos(void)
{
if (conf.DEBUG.get()) {
cout << "setinitpos() called..." << endl;
}
ego.setspinx(270); //initial dive angle = 0 ( 270-spinx)
// initial ortho-position is in center
ego.setOx(0);
ego.setOy(0);
// these are the dimnsions in lon and lat direction. In openGL-coordinates (x,y)
float _lon_dist, _lat_dist;
// these are used since we need to respect the projection
// calculate borders in lat/lon
float _latmax, _lonmax, _latmin, _lonmin;
//-------------------------------------------------------------------------------- !!!!
// hier gehts weiter
if (!conf.FLIGHT.get()) {
_latmax =
fd.getcenter_lat() +
(conf.getborder_land_lat() / DEGDIST);
_latmin =
fd.getcenter_lat() -
(conf.getborder_land_lat() / DEGDIST);
_lonmax = fd.getcenter_lon()
+ (conf.getborder_land_lon() /
(DEGDIST *
cos(fd.getcenter_lat() * (M_PI / 180.0))));
_lonmin =
fd.getcenter_lon() -
(conf.getborder_land_lon() /
(DEGDIST * cos(fd.getcenter_lat() * (M_PI / 180.0))));
} else {
proj.get_latlon(fd.getxmax(), fd.getymax(), _latmax,
_lonmax);
proj.get_latlon(fd.getxmin(), fd.getymin(), _latmin,
_lonmin);
_latmax += (conf.getborder_land_lat() / DEGDIST);
_latmin -= (conf.getborder_land_lat() / DEGDIST);
_lonmax +=
conf.getborder_land_lon() / (DEGDIST *
cos(fd.getcenter_lat() *
(M_PI / 180.0)));
_lonmin -=
conf.getborder_land_lon() / (DEGDIST *
cos(fd.getcenter_lat() *
(M_PI / 180.0)));
}
if (_latmax > 90) {
_latmax = 90;
}
if (_latmin < -90) {
_latmin = -90;
}
if (proj.get_projection() == PROJ_CYL_MERCATOR) {
if (_latmax > MERCATOR_MAX_LAT) {
_latmax = MERCATOR_MAX_LAT;
}
if (_latmin < -MERCATOR_MAX_LAT) {
_latmin = -MERCATOR_MAX_LAT;
}
}
float _screenratio =
(float) conf.getwidth() / (float) conf.getheight();
float _xmax, _xmin, _ymax, _ymin;
proj.get_xy(_latmax, _lonmax, _xmax, _ymax);
proj.get_xy(_latmin, _lonmin, _xmin, _ymin);
_lon_dist = -(_xmax - _xmin);
_lat_dist = -(_ymax - _ymin);
//cout << _lat_dist << " latdist londist->" << _lon_dist << endl;
float _landratio = _lon_dist / _lat_dist;
if (_screenratio < _landratio) {
conf.orthoclipping.set(_lon_dist);
//cout << "wide" << endl;
} else {
conf.orthoclipping.set(_lat_dist * _screenratio);
//cout << "hi " << _lat_dist * _screenratio << endl;
//cout << "screenra " << _screenratio << endl;
}
//cout << "otrhocliiping: " << conf.getorthoclipping() << endl;
// set orthoclipping END
// set position for 3D mode
// this is aequivalent to "S", default
if (conf.FLIGHT.get()) {
ego.setz(fd.getzmin() + 10 * conf.z_scale.get()); //set position 10km above minimum
ego.setx(0);
ego.sety(_ymin); //over south border
if (conf.DEBUG.get())
cout << "setinitpos: flight zmin: " << fd.getzmin() << endl;
}
if (!conf.FLIGHT.get()) {
ego.setz(10 * conf.z_scale.get()); // altitude is 10 km
ego.setx(0);
ego.sety(_ymin); // over south border
}
// check for user given position:
//position "north"
if (args_info.init_pos_N_given) {
if (conf.FLIGHT.get()) {
ego.setx(0);
ego.sety(_ymax); //over north border
} else {
ego.setx(0);
ego.sety(_ymax); // over north border
}
}
//position "south"
if (args_info.init_pos_S_given) {
if (conf.FLIGHT.get()) {
ego.setx(0);
ego.sety(_ymin);
} else {
ego.setx(0);
ego.sety(_ymin);
}
}
//position "West"
if (args_info.init_pos_W_given) {
if (conf.FLIGHT.get()) {
ego.setx(_xmin);
ego.sety(0); //-(conf.getborder_land_lat()+fd.getymax ()) );
} else {
ego.setx(_xmin);
ego.sety(0); //-conf.getborder_land_lat());
}
}
//position "east"
if (args_info.init_pos_E_given) {
if (conf.FLIGHT.get()) {
ego.setx(_xmax);
ego.sety(0); //-(conf.getborder_land_lat()+fd.getymax ()) );
} else {
ego.setx(_xmax);
ego.sety(0); //-conf.getborder_land_lat());
}
}
//position "NW"
if (args_info.init_pos_NW_given) {
if (conf.FLIGHT.get()) {
ego.setx(_xmin);
ego.sety(_ymax);
} else {
ego.setx(_xmin);
ego.sety(_ymax);
}
}
//position "SW"
if (args_info.init_pos_SW_given) {
if (conf.FLIGHT.get()) {
ego.setx(_xmin);
ego.sety(_ymin);
} else {
ego.setx(_xmin);
ego.sety(_ymin);
}
}
//position "NE"
if (args_info.init_pos_NE_given) {
if (conf.FLIGHT.get()) {
ego.setx(_xmax);
ego.sety(_ymax);
} else {
ego.setx(_xmax);
ego.sety(_ymax);
}
}
//position "SE"
if (args_info.init_pos_SE_given) {
if (conf.FLIGHT.get()) {
ego.setx(_xmax);
ego.sety(_ymin);
} else {
ego.setx(_xmax);
ego.sety(_ymin);
}
}
if (args_info.init_lat_given && args_info.init_lon_given) {
float _x, _y;
proj.get_xy(args_info.init_lat_arg, args_info.init_lon_arg,
_x, _y);
ego.sety(_y);
ego.setx(_x);
}
if (args_info.init_ortho_lat_given
&& args_info.init_ortho_lon_given) {
float _x2, _y2;
proj.get_xy(args_info.init_ortho_lat_arg,
args_info.init_ortho_lon_arg, _x2, _y2);
ego.setOy(-_y2);
ego.setOx(-_x2);
}
if (args_info.init_ortho_width_given)
conf.orthoclipping.set(args_info.init_ortho_width_arg);
if (args_info.init_alt_given)
ego.setz(((double) args_info.init_alt_arg / 1000.0) *
conf.z_scale.get());
//calculate dive
float _dist =
sqrt(ego.getx() * ego.getx() + ego.gety() * ego.gety());
float _alt;
if (conf.FLIGHT.get()) {
_alt = ego.getz() - (fd.getzmin() * conf.z_scale.get());
} else {
_alt = ego.getz() - (0.5 * conf.z_scale.get());
}
float _atanarg = _alt / _dist;
ego.setspinx((int) (270.0 + (atan(_atanarg)) / PI_180));
//calculate heading
// SW quadrant
if (ego.getx() >= 0 && ego.gety() >= 0) {
//cout << "SW Quadrant" << endl;
if (ego.gety() != 0) {
//cout << "y != 0" << endl;
ego.setspinz((int)
(atan(ego.getx() / ego.gety())
/ PI_180)
);
} else {
ego.setspinz(90);
}
}
// NW quadrant
if (ego.getx() >= 0 && ego.gety() < 0) {
//cout << "NW Quadrant" << endl;
if (ego.getx() != 0) {
//cout << "x != 0" << endl;
ego.setspinz((int)
(90.0 - (atan(ego.gety() / ego.getx())
/ PI_180)
)
);
} else {
//cout << "else?" << endl;
ego.setspinz(180);
}
}
// NE quadrant
if (ego.getx() < 0 && ego.gety() <= 0) {
//cout << "NE Quadrant" << endl;
if (ego.gety() != 0) {
//cout << "y != 0" << endl;
ego.setspinz((int)
(180.0 +
(atan(ego.getx() / ego.gety())
/ PI_180)
)
);
} else {
//cout << "else?" << endl;
ego.setspinz(270);
}
}
// SE quadrant
if (ego.getx() < 0 && ego.gety() > 0) {
//cout << "SE Quadrant" << endl;
if (ego.gety() != 0) {
//cout << "y != 0" << endl;
ego.setspinz((int)
(360.0 +
(atan(ego.getx() / ego.gety())
/ PI_180)
)
);
} else {
//cout << "else?" << endl;
ego.setspinz(270);
}
}
if (args_info.init_pos_center_given) {
ego.setx(0);
ego.sety(0);
ego.setspinz(0);
ego.setspinx(360);
}
if (args_info.init_heading_given) {
ego.setspinz((double) args_info.init_heading_arg);
ego.spinz(0.1);
ego.spinz(-0.1);
}
if (args_info.init_dive_given) {
ego.setspinx((double) 270 - args_info.init_dive_arg);
ego.spinx(0.1);
ego.spinx(-0.1);
}
if (conf.FOLLOW.get() && conf.FLIGHT.get()) {
#ifndef ONLY_OSMESA
update_diff_pos();
#endif
}
// this caused crashes on Mac OS X
// setinitpos is called before glutcreatewindow, therefore initGL
// causes gl... calls before the context is established!
// but this call is not necessary...
// InitGL(conf.getwidth(), conf.getheight());
}
void mesaonly_info (void) {
#ifdef ONLY_OSMESA
cout << endl << " This version of openGLIGCexplorer (ogie) can be used" << endl
<< " for offscreen-rendering with osmesa only!" << endl
<< " No interactive controlling, no output to the display!" << endl << endl;
#endif
}
//main startup!
//----------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
// if no argument is given, print help and exit
if (argc == 1) {
cmdline_parser_print_help();
#ifdef ONLY_OSMESA
mesaonly_info();
#endif
Ende(0);
//exit(0);
}
/* let's call our cmdline parser */
if (cmdline_parser(argc, argv, &args_info) != 0) {
Ende(1);
}
// check option (for GPLIGC)
if (args_info.check_given) {
Ende(0);
}
// build info...
if (args_info.compiler_given) {
char compiler[80] = "unkown";
char system[80] = "unknown";
char build[80] = "unknown";
#ifdef __GNUC__
#ifndef __GNUC_MINOR__
#define __GNUC_MINOR__ 0
#endif
#ifndef __GNUC_PATCHLEVEL__
#define __GNUC_PATCHLEVEL__ 0
#endif
#ifndef __VERSION__
#define __VERSION__ 0
#endif
sprintf(compiler, "gcc %d.%d.%d (%s)", __GNUC__,
__GNUC_MINOR__, __GNUC_PATCHLEVEL__, __VERSION__);
#endif
sprintf(build, "%s %s", __DATE__, __TIME__);
#ifdef __WIN32__
sprintf(system, "Windows (__WIN32__) is set");
#endif
#ifdef __linux__
sprintf(system, "Linux (__linux__) is set");
#endif
#ifdef __MACOSX__
sprintf(system, "Mac OS X (__MAC_OS_X__) is set");
#endif
std::cout << "Compiler: " << compiler << std::endl;
#ifdef __CYGWIN__
std::cout << "Cygwin (__CYGWIN__) is set" << std::endl;
#endif
std::cout << "Build: " << build << std::endl;
std::cout << "Platform: " << system << std::endl;
#ifdef __unix__
std::cout << "Unix (__unix__) is set" << std::endl;
#endif
// std::cout << "System: " << SYSINFO << endl;
Ende(0);
}
//-------------- THIS WILL FAIL without X!
// however, for osmesa offscreen, freeglut will fail without glutInit
// first call glutStrokeCharacter will stop the runtime
// no real offscreen without Xserver for now!
// see freeglut bug #204
// --no-info hilft!
#ifndef ONLY_OSMESA
glutInit(&argc, argv);
#endif
#ifndef __WIN32__
#ifndef ONLY_OSMESA
// register function for SIGUSR1
signal(SIGUSR1, SIGUSR1Handler);
#endif
#endif
// if verbose given turn it on...
// in reading configfile we will know, that --verbose was given,
// because otherwise the default verbose=off would be active...
if (args_info.verbose_given)
conf.VERBOSE.on();
// to be evaluated while reading configfile
// quiet should override --verbose !!!
if (args_info.quiet_given) {
conf.QUIET.on();
conf.VERBOSE.off();
}
// check for debugging option
// later if debug is given, but after reading configfile
// debug should override --quiet and activates VERBOSE
if (args_info.debug_given) {
conf.DEBUG.on();
conf.VERBOSE.on();
conf.QUIET.off();
cout << "Debugging output enabled..." << endl;
}
#ifdef ONLY_OSMESA
if (!conf.QUIET.get()){
mesaonly_info();
}
#endif
//openGL query
#ifndef ONLY_OSMESA
if (args_info.query_gl_given) {
// this needs to be created, to get the information
window = glutCreateWindow("");
cout << "Information on the openGL implementation:" <<
endl;
int _q;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&_q);
cout << "GL_MAX_TEXTURE_SIZE: " << _q << endl;
glGetIntegerv(GL_MAX_EVAL_ORDER, (GLint*)&_q);
cout << "GL_MAX_EVAL_ORDER: " << _q << endl;
glGetIntegerv(GL_MAX_LIGHTS, (GLint*)&_q);
cout << "GL_MAX_LIGHTS: " << _q << endl;
glGetIntegerv(GL_RED_BITS, (GLint*)&_q);
cout << "GL_RED_BITS: " << _q << endl;
glGetIntegerv(GL_GREEN_BITS, (GLint*)&_q);
cout << "GL_GREEN_BITS: " << _q << endl;
glGetIntegerv(GL_BLUE_BITS, (GLint*)&_q);
cout << "GL_BLUE_BITS: " << _q << endl;
glGetIntegerv(GL_ALPHA_BITS, (GLint*)&_q);
cout << "GL_ALPHA_BITS: " << _q << endl;
glGetIntegerv(GL_DEPTH_BITS, (GLint*)&_q);
cout << "GL_DEPTH_BITS: " << _q << endl;
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, (GLint*)&_q);
cout << "GL_MAX_VIEWPORT_DIMS: " << _q << endl;
glGetIntegerv(GL_AUX_BUFFERS, (GLint*)&_q);
cout << "GL_AUX_BUFFERS: " << _q << endl;
const GLubyte *_string;
_string = glGetString(GL_VENDOR);
cout << "GL_VENDOR: " << _string << endl;
_string = glGetString(GL_RENDERER);
cout << "GL_RENDERER: " << _string << endl;
_string = glGetString(GL_VERSION);
cout << "GL_VERSION: " << _string << endl;
_string = glGetString(GL_EXTENSIONS);
cout << "GL_EXTENSIONS: " << _string << endl;
#ifndef NOGLX
cout << endl << "Information on the GLX library" << endl;
//Xlib Diplay
Display *dpy;
//Get the Diplay...
dpy = XOpenDisplay(NULL); //will use env DIPLAY on posix .. man XOpenDisplay
int major, minor;
glXQueryVersion(dpy, &major, &minor);
cout << "glXQueryVersion: " << major << "." << minor <<
endl;
cout << "glXGetClientString(GLX_VENDOR): " <<
glXGetClientString(dpy, GLX_VENDOR) << endl;
cout << "glXGetClientString(GLX_VERSION): " <<
glXGetClientString(dpy, GLX_VERSION) << endl;
cout << "glXGetClientString(GLX_EXTENSIONS): " <<
glXGetClientString(dpy, GLX_EXTENSIONS) << endl;
// int screen ?
cout << "glXQueryExtensionsString(screen 0): " <<
glXQueryExtensionsString(dpy, 0) << endl;
//cout << "glXQueryExtensionsString(): " << glXQueryExtensionsString(dpy,1) << endl;
cout << "glXQueryServerString(screen 0, GLX_VENDOR): " <<
glXQueryServerString(dpy, 0, GLX_VENDOR) << endl;
cout << "glXQueryServerString(screen 0, GLX_VERSION): " <<
glXQueryServerString(dpy, 0, GLX_VERSION) << endl;
cout << "glXQueryServerString(screen 0, GLX_EXTENSIONS): "
<< glXQueryServerString(dpy, 0,
GLX_EXTENSIONS) << endl;
#endif
// and here some information from GLUT header files
// can be 1-5 (5 is glut.h in mesa 5.0.2 for example)
// cout << endl << "Information about GLUT (compiled in from glut.h)" << endl;
// cout << "GLUT_API_VERSION: " << GLUT_API_VERSION << endl;
// #ifdef FREEGLUT
// cout << "FREEGLUT: " << FREEGLUT << endl;
// #endif
// #ifdef FREEGLUT_VERSION_2_0
// cout << "FREEGLUT_VERSION_2_0: " << FREEGLUT_VERSION_2_0 << endl;
// #endif
// some information from GLUT at runtime....
cout << endl << "Some runtime GLUT information:" << endl;
// IN FREEGLUT 2.2.0 (GLUT_VERSION=20200) these are only lies (for X11) (see freeglut_state.c)
//cout << "glutDeviceGet(GLUT_HAS_MOUSE): " << glutDeviceGet(GLUT_HAS_MOUSE) << endl;
//cout << "glutDeviceGet(GLUT_HAS_JOYSTICK): " << glutDeviceGet(GLUT_HAS_JOYSTICK) << endl;
//cout << "glutDeviceGet(GLUT_OWNS_JOYSTICK): " << glutDeviceGet(GLUT_OWNS_JOYSTICK) << endl;
//cout << "glutDeviceGet(GLUT_JOYSTICK_BUTTONS): " << glutDeviceGet(GLUT_JOYSTICK_BUTTONS) << endl;
//cout << "glutDeviceGet(GLUT_JOYSTICK_AXES): " << glutDeviceGet(GLUT_JOYSTICK_AXES) << endl;
//cout << "glutDeviceGet(GLUT_JOYSTICK_POLL_RATE): " << glutDeviceGet(GLUT_JOYSTICK_POLL_RATE) << endl;
// will cause a warning on old-glut (because GLUT_VERSION isnt known to old-glut)
cout << "glutGet(GLUT_VERSION): " << glutGet(GLUT_VERSION) << endl;
#ifdef HAVE_LIBGPS
cout << endl << "GPSD supported"<< endl << "gpsd header version:" << endl;
cout << "GPSD_API_MAJOR_VERSION: " << GPSD_API_MAJOR_VERSION << endl;
cout << "GPSD_API_MINOR_VERSION: " << GPSD_API_MINOR_VERSION << endl;
#else
cout << endl << "GPSD _NOT_ supported"<< endl;
#endif
#ifdef HAVE_LIBOSMESA
cout << endl << "OSMesa supported" << endl;
#else
cout << endl << "OSMesa _NOT_ supported" << endl;
#endif
Ende(0);
}
#endif
// ----------------- READ CONFIGFILE ---- override compiled in defaults
// some things (projection for example) need to be known before loading any igc files
// check for config file first
if (args_info.config_file_given) {
//cout << "Configfile !!! :: " << conf.getConfigFileName() << endl;
conf.setConfigFileName(args_info.config_file_arg);
}
// read the configuration file first, then evaluate the cmdline
// cmdl can override configuration-file!
conf.readConfigFile();
//------------------------------------------------------------------------
if (args_info.get_elevation_given) {
if (args_info.lat_given && args_info.lon_given) {
vector<int>_alt;
vector<float>_lat;
vector<float>_lon;
// WARN on should be used for srtm-3 from seamless server
// off for SRTM30
// see get_gnd_elevation
conf.GETELEV_WARN.on();
// conf.GETELEV_WARN.off();
conf.GETELEV_ERROR.on();
_lat.push_back(args_info.lat_arg);
_lon.push_back(args_info.lon_arg);
_alt.push_back(0);
get_gnd_elevations(&_alt,&_lat,&_lon,&conf);
// smaller 0 is invalid
if (_alt[0] > 0) {
cout << _alt[0] << endl;
if (conf.GETELEV_ERROR.get())
cout << _alt[1] << endl;
} else {
if (conf.GETELEV_WARN.get()) {
cout << _alt[1] << endl;
cout << "INVALID" << (-1*_alt[0]) <<endl;
} else {
cout << _alt[0] << endl;
if (conf.GETELEV_ERROR.get())
cout << _alt[1] << endl;
}
}
exit (0);
} else {
cerr << "--get-elevation without --lat and --lon!" << endl ;
}
}
//air class knows the configuration...
air.setConfig(&conf);
fd.set_proj_pointer(&proj);
fd.set_conf_pointer(&conf);
lifts.set_proj_pointer(&proj);
lifts.set_conf_pointer(&conf);
waypoints.set_proj_pointer(&proj);
waypoints.set_conf_pointer(&conf);
if (args_info.cycles_given)
fd.setcycles(args_info.cycles_arg);
//-----cmd line options to be read before igc file is loaded-------
proj.set_projection(conf.get_projection());
if (args_info.projection_cyl_platt_given)
proj.set_projection(PROJ_CYL_PLATT);
if (args_info.projection_cyl_mercator_given)
proj.set_projection(PROJ_CYL_MERCATOR);
if (args_info.projection_cyl_no1_given)
proj.set_projection(PROJ_CYL_NO1);
if (args_info.projection_pseudo_cyl_no1_given)
proj.set_projection(PROJ_PSEUDO_CYL_NO1);
// handled at the beginning of main, and config-reading now...
//if (args_info.verbose_given)
// conf.VERBOSE.on();
//if (args_info.quiet_given)
// conf.VERBOSE.off();
//------------------------------------------------------------------------
// if only one argument is given, assume that it is an igc-file
if (argc == 2 && !args_info.gpsd_given && !args_info.gpsd_port_given && !args_info.gpsd_server_given) {
//cout << "nur 1 arg ? : " << argc << endl;
fd.readIGCFile(argv[1], args_info.use_all_fixes_given);
// no valid fixes? try invalid ones
if (fd.getn() == 0) {
cerr <<
"No valid position fixes found... looking for invalid ones"
<< endl;
fd.readIGCFile(argv[1], true);
}
//if no position fixes recognized....
if (fd.getn() == 0) {
cerr << "This seems not to be an igc-file!" <<
endl;
Ende(1);
}
conf.setIGCFileName(argv[1]);
}
if ( ! (argc==2 || args_info.igc_file_given || (args_info.lat_given && args_info.lon_given))
&& (! args_info.gpsd_given && !args_info.gpsd_port_given && !args_info.gpsd_server_given)
) {
cerr << "Not enough! Give -i igcfile or --lat and --lon" << endl;
Ende(1);
}
if (args_info.gpsd_given || args_info.gpsd_port_given || args_info.gpsd_server_given) {
#ifdef HAVE_LIBGPS
#if GPSD_API_MAJOR_VERSION != 5
cerr << "We need libgps with GPSD_API_MAJOR_VERSION == 5 !!!" << endl
<< "Version " << GPSD_API_MAJOR_VERSION << " was found ;-(" << endl;
Ende(1);
#endif
#endif
conf.GPSD.on();
conf.MARKER.on();
conf.FOLLOW.on();
conf.FLYING.on();
stringstream _sp;
if (args_info.gpsd_port_given) {
_sp << args_info.gpsd_port_arg;
}
if (args_info.gpsd_server_given && !args_info.gpsd_port_given) {
fd.initgps(args_info.gpsd_server_arg);
}
if (args_info.gpsd_server_given && args_info.gpsd_port_given) {
fd.initgps(args_info.gpsd_server_arg, _sp.str().c_str());
}
if (!args_info.gpsd_server_given && args_info.gpsd_port_given) {
fd.initgps("localhost", _sp.str().c_str());
}
if (!args_info.gpsd_server_given && !args_info.gpsd_port_given) {
fd.initgps();
}
}
// check for igc-file (-i option)
if (args_info.igc_file_given) {
fd.readIGCFile(args_info.igc_file_arg,
args_info.use_all_fixes_given);
// no valid fixes? try invalid ones
if (fd.getn() == 0) {
cerr <<
"No valid position fixes found... looking for invalid ones"
<< endl;
fd.readIGCFile(args_info.igc_file_arg, true);
}
//if no position fixes recognized....
if (fd.getn() == 0) {
cerr << "This seems not to be an igc-file!" <<
endl;
Ende(1);
}
conf.setIGCFileName(args_info.igc_file_arg);
}
// ------------------- READ CMDLINE ----- override CONFIGFILE options...
if (args_info.airspace_file_given)
conf.setAirspaceFileName(args_info.airspace_file_arg);
if (args_info.lifts_given) {
conf.LIFTS.on();
conf.setLiftsFileName(args_info.lifts_arg);
if (conf.VERBOSE.get()) {
cout << "Lifts: " << conf.getLiftsFileName() << endl;
}
}
if (args_info.waypoints_file_given) {
conf.WAYPOINTS.on();
conf.setWaypointsFileName(args_info.waypoints_file_arg);
if (conf.VERBOSE.get()) {
cout << "Waypoints: " << conf.getWaypointsFileName() << endl;
}
}
if (args_info.waypoints_given) { conf.WAYPOINTS.on();}
if (args_info.no_waypoints_given) { conf.WAYPOINTS.off();}
if (args_info.waypoints_offset_given) { conf.waypoints_offset.set(args_info.waypoints_offset_arg);}
if (args_info.waypoints_offset_spheres_given) { conf.waypoints_offset.set(args_info.waypoints_offset_spheres_arg);
conf.WAYPOINTS_OFFSET_TEXT_ONLY.off();
}
if (args_info.map_set_name_given) {
if (conf.set_ActiveMapSet(args_info.map_set_name_arg) != 0) {
cout << args_info.
map_set_name_arg << " not found ...." << endl;
}
}
// some output (if VERBOSE)
if (conf.VERBOSE.get()) {
cout << "Configfile: " << conf.
getConfigFileName() << endl;
cout << "OpenAir: " << conf.getAirspaceFileName() << endl;
cout << "DEM-File: " << conf.getDemFileName() << endl;
if (conf.getNumberOfMaps() != 0) {
cout << conf.getNumberOfMaps() << " Digital maps found, " << conf.getNumberOfMapSets() << " Map-Sets"
<< endl;
}
}
// landscape or flat?
if (args_info.landscape_given)
conf.LANDSCAPE.on();
if (args_info.flat_given) {
conf.LANDSCAPE.off();
//conf.toggleLANDSCAPE();
}
if (args_info.flat_given && args_info.landscape_given) {
cerr << "specify \"--flat\" _or_ \"--landscape\"" <<
endl;
Ende(1);
}
// ALTITUDE DATA used !
if (args_info.gpsalt_given)
conf.GPSALT.on();
if (args_info.baroalt_given)
conf.GPSALT.off();
if (args_info.ignore_elev_min_given && args_info.ignore_elev_max_given) {
conf.IGNORE_ELEV_RANGE.on();
conf.ignore_elev_max.set(args_info.ignore_elev_max_arg);
conf.ignore_elev_min.set(args_info.ignore_elev_min_arg);
}
// modulate or not?
if (args_info.modulate_given)
conf.MODULATE.on();
if (args_info.no_modulate_given)
conf.MODULATE.off();
// lighting of unmodulated maps
if (args_info.maps_unlighted_given)
conf.MAPS_UNLIGHTED.on();
if (args_info.maps_lighted_given)
conf.MAPS_UNLIGHTED.off();
// Airspace or not?
if (args_info.airspace_given)
conf.AIRSPACE.on();
if (args_info.no_airspace_given)
conf.AIRSPACE.off();
if (args_info.airspace_wire_given)
conf.AIRSPACE_WIRE.on();
if (args_info.airspace_transparent_given)
conf.AIRSPACE_WIRE.off();
if (args_info.airspace_limit_given)
conf.AirspaceLimit.set(args_info.airspace_limit_arg);
// dont start in this condition....
if (conf.AIRSPACE.get()
&& (conf.getAirspaceFileName() == "not available")) {
cerr << "No Airspace available..." << endl;
Ende(1);
}
// MAP
if (args_info.map_given) {
//conf.setLANDSCAPE();
//conf.toggleLANDSCAPE();
conf.MAP.on();
}
if (args_info.no_map_given) {
conf.MAP.off();
}
// Wireframe or filled polygons
if (args_info.wire_given)
conf.WIRE.on();
if (args_info.filled_given)
conf.WIRE.off();
// sealevel stuff
if (args_info.sealevel_given)
conf.set_sealevel(args_info.sealevel_arg);
if (args_info.sealevel2_given)
conf.set_sealevel2(args_info.sealevel2_arg);
if (args_info.sealevel3_given)
conf.set_sealevel3(args_info.sealevel3_arg);
// no --marker-pos without igc-file
if (args_info.marker_pos_given
&& !(args_info.igc_file_given || argc == 2)) {
cerr << "Can't use --marker-pos without flightdata" <<
endl;
Ende(1);
}
// no --marker without igc-file
// marker will be turned off later, if no flightdata is available... (see below)
/*
if (args_info.marker_given && !(args_info.igc_file_given || argc == 2) ) {
cerr << "Can't use --marker without flightdata" << endl;
Ende (1);
}
*/
// Marker on or off?
if (args_info.marker_given)
conf.MARKER.on();
if (args_info.no_marker_given)
conf.MARKER.off();
if (args_info.marker_size_given)
conf.MARKER_SIZE.set(args_info.marker_size_arg);
if (args_info.text_width_given)
conf.text_width.set(args_info.text_width_arg);
if (args_info.lifts_info_mode_given)
conf.lifts_info_mode.set(args_info.lifts_info_mode_arg);
if (args_info.waypoints_info_mode_given)
conf.waypoints_info_mode.set(args_info.waypoints_info_mode_arg);
if (args_info.text_size_given)
conf.pTextSize.set(args_info.text_size_arg);
//spinning for movie
if (args_info.spinning_given) {
conf.SPINNING.set(args_info.spinning_arg);
}
// Info Diplay on or off?
if (args_info.info_given)
conf.INFO.on();
if (args_info.no_info_given)
conf.INFO.off();
// avoid --lat --lon with igc-file
if ((args_info.lat_given && args_info.lon_given)
&& (args_info.igc_file_given || argc == 2)) {
cerr << "Can't use --lat, --lon and flightdata" << endl;
Ende(1);
}
// set marker position
if (args_info.marker_pos_given)
fd.setmarkerpos(args_info.marker_pos_arg);
if (args_info.marker_time_given)
fd.setmarkertime(args_info.marker_time_arg);
// fullscreen
if (args_info.fullscreen_given)
conf.FULLSCREEN.on();
if (args_info.window_given)
conf.FULLSCREEN.off();
// window geometry
if (args_info.width_given) {
conf.setwidth(args_info.width_arg);
conf.setinitwidth(args_info.width_arg);
}
if (args_info.height_given) {
conf.setheight(args_info.height_arg);
conf.setinitheight(args_info.height_arg);
}
// 3D or 2D
if (args_info.ortho_given)
conf.ORTHOVIEW.on();
if (args_info.perspective_given)
conf.ORTHOVIEW.off();
//grayscale
if (args_info.grayscale_given)
conf.BW.on();
if (args_info.color_given)
conf.BW.off();
//stereoscopic
if (args_info.stereo_given)
conf.STEREO.on();
if (args_info.no_stereo_given)
conf.STEREO.off();
//stereo rg
if (args_info.stereo_rg_given)
conf.STEREO_RG.on();
if (args_info.no_stereo_rg_given)
conf.STEREO_RG.off();
//stereo rb
if (args_info.stereo_rb_given)
conf.STEREO_RB.on();
if (args_info.no_stereo_rb_given)
conf.STEREO_RB.off();
//stereo hardware
if (args_info.stereo_hw_given)
conf.STEREO_HW.on();
if (args_info.no_stereo_hw_given)
conf.STEREO_HW.off();
// nur 1 von 4 ... STEREO modes...
// ??
int _nr = 0;
_nr +=
(int) conf.STEREO_RB.get() + (int) conf.STEREO_RG.get() +
(int) conf.STEREO.get() + (int) conf.STEREO_HW.get();
if (_nr >= 2) {
cerr << "Only one stereo-option can be used!" << endl;
Ende(1);
}
// image swapping! left <-> right
if (args_info.inverse_stereo_given)
conf.SWAP_STEREO.on();
if (args_info.no_inverse_stereo_given)
conf.SWAP_STEREO.off();
// eye-distance
if (args_info.eye_dist_given) {
if (args_info.eye_dist_arg > 0)
conf.eye_dist.set(args_info.eye_dist_arg);
}
// Offscreen rendering
if (args_info.offscreen_given)
conf.OFFSCREEN.on();
// Offscreen with mesa
if (args_info.osmesa_given)
conf.OSMESA.on();
if (conf.OSMESA.get() && conf.OFFSCREEN.get()) {
cerr << "only one offscreen rendering mode possible!" <<
endl;
Ende(1);
}
if (conf.STEREO_HW.get()
&& (conf.OSMESA.get() || conf.OFFSCREEN.get())) {
cerr <<
"Hardware stereo isn't possible in offscreen rendering mode"
<< endl;
Ende(1);
}
// jpeg quality for screenshots
if (args_info.jpeg_quality_given) {
if ( (args_info.jpeg_quality_arg >= 0) && (args_info.jpeg_quality_arg <= 100))
conf.jpeg_quality.set(args_info.jpeg_quality_arg);
}
// image format for output
if (args_info.image_format_given)
conf.set_image_format(args_info.image_format_arg);
// offset
if (args_info.offset_given)
conf.offset.set(args_info.offset_arg);
// airfield elevation
if (args_info.airfield_elevation_given) {
conf.setairfield_elevation(args_info.
airfield_elevation_arg);
}
// avoid --airfield-elevation and --offset
if (args_info.airfield_elevation_given && args_info.offset_given) {
cerr <<
"specify \"--offset\" _or_ \"--airfield-elevation\"" <<
endl;
Ende(1);
}
// gpsalt?
if (conf.GPSALT.get()) {
if (conf.VERBOSE.get())
cout << "gps-altitude is used." << endl;
fd.usegps();
}
// if we have an elevation and an igc-file. Calculate offset!
if (args_info.airfield_elevation_given
&& (args_info.igc_file_given || argc == 2)) {
conf.offset.set(-1 *
(fd.getstartelevation(conf.GPSALT.get()) -
args_info.airfield_elevation_arg));
if (conf.VERBOSE.get())
cout << "offset = " << (-1 *
(fd.
getstartelevation(conf.
GPSALT.
get()) -
args_info.
airfield_elevation_arg))
<< endl;
//cout << "offset = " << conf.getoffset() << endl;
}
// Z-Axis scaling!
if (args_info.scalez_given)
conf.z_scale.set(args_info.scalez_arg);
// Downscaling
if (args_info.downscaling_given)
conf.setdownscalefactor(args_info.downscaling_arg);
if (args_info.upscaling_given)
conf.setupscalefactor(args_info.upscaling_arg);
// don't allow Landscape, Map and downscaling!
// but it is possible to switch in this state later... (not very beautiful, but works)
/* if (conf.LANDSCAPE.get() && conf.MAP.get()
&& conf.getdownscalefactor() != 1) {
cerr << "Can't use textured maps, DEM and downscaling!" <<
endl;
Ende(1);
}
*/
// texture map compression!
if (args_info.compression_given) {
conf.COMPRESSION.on();
}
if (args_info.no_compression_given) {
conf.COMPRESSION.off();
//conf.toggleCOMPRESSION();
}
if (args_info.airspace_wire_col_r_given) {
conf.airspace_wire_color_r.set(args_info.airspace_wire_col_r_arg);
}
if (args_info.airspace_wire_col_g_given) {
conf.airspace_wire_color_g.set(args_info.airspace_wire_col_g_arg);
}
if (args_info.airspace_wire_col_b_given) {
conf.airspace_wire_color_b.set(args_info.airspace_wire_col_b_arg);
}
if (args_info.airspace_wire_width_given) {
conf.airspace_wire_width.set(args_info.airspace_wire_width_arg);
}
// set colormap
if (args_info.colormap_given) {
if (args_info.colormap_arg >= 1
&& args_info.colormap_arg <= 8) {
conf.colmapnumber.set(args_info.colormap_arg);
} else {
cerr << "Colormap " << args_info.
colormap_arg << " doesnt exist. using default."
<< endl;
}
}
// set colormap
if (args_info.colormap_sea_given) {
if (args_info.colormap_sea_arg >= 1
&& args_info.colormap_sea_arg <= 8) {
conf.colmap2number.set(args_info.colormap_sea_arg);
} else {
cerr << "Colormap " << args_info.
colormap_sea_arg <<
" doesnt exist. using default." << endl;
}
}
// Set border .....
if (args_info.border_given) {
conf.setborder_land_lat(args_info.border_arg);
conf.setborder_land_lon(args_info.border_arg);
}
if (args_info.border_lat_given)
conf.setborder_land_lat(args_info.border_lat_arg);
if (args_info.border_lon_given)
conf.setborder_land_lon(args_info.border_lon_arg);
// flat or gouraud-shading !
if (args_info.flat_shading_given) {
conf.SHADE.off();
}
if (args_info.gouraud_shading_given) {
conf.SHADE.on();
}
// lighting workaround for upscaling
if (args_info.no_lighting_given) {
conf.NOLIGHTING.on();
}
if (args_info.terrain_shading_given) {
conf.TERRAINSHADING.on();
conf.NOLIGHTING.on();
}
if (args_info.light_direction_given) {
conf.shadedirection.set(args_info.light_direction_arg);
}
if (args_info.shading_scale_given) {
conf.setshadescale(args_info.shading_scale_arg);
}
//quads
if (args_info.quads_given) {
conf.QUADS.on();
}
// Fog related stuff
if (args_info.haze_given)
conf.FOG.on();
if (args_info.no_haze_given)
conf.FOG.off();
if (args_info.haze_density_given) {
conf.fogdensity.set(args_info.haze_density_arg);
}
//curtain
if (args_info.curtain_given)
conf.CURTAIN.on();
if (args_info.no_curtain_given)
conf.CURTAIN.off();
// Angle of View
if (args_info.aov_given) {
if (args_info.aov_arg >= 1 && args_info.aov_arg <= 179) {
conf.aov.set(args_info.aov_arg);
} else {
cerr <<
"Angle of view is out of Range. Using default."
<< endl;
}
}
// no flightdata, but lat lon! (dummy fd needed!)
// avoid lat or lon!
if (args_info.lon_given && !args_info.lat_given) {
cerr << "specify --lon and --lat !" << endl;
Ende(1);
}
if (args_info.lat_given) {
if (!args_info.lon_given) {
cerr << "specify --lat and --lon !" << endl;
Ende(1);
}
conf.FLIGHT.off();
// maybe someone want to start without terrain (make sense since airspace and maps))
//conf.LANDSCAPE.on();
conf.setlat(args_info.lat_arg);
conf.setlon(args_info.lon_arg);
///set dummy values in fd!
proj.set_center_lat(conf.getlat()); // set center for projections....
proj.set_center_lon(conf.getlon());
fd.setcenter_lat(conf.getlat());
fd.setcenter_lon(conf.getlon());
fd.setxcenter(0);
fd.setycenter(0);
fd.setzcenter(0);
fd.setlatmin(conf.getlat());
fd.setlonmin(conf.getlon());
fd.setlatmax(conf.getlat());
fd.setlonmax(conf.getlon());
fd.setmarkerpos(0);
}
// if we have flightdata and DEM-data, we can calculate the ground-altitude!
if (conf.FLIGHT.get()) {
if (conf.DEM.get())
fd.readGNDElevation(&conf);
}
// initialize airspace class
if (conf.getAirspaceFileName() != "not available") {
float border_deg_lat = conf.getborder_land_lat() / DEGDIST;
float border_deg_lon =
(conf.getborder_land_lon() / DEGDIST) /
cos(fd.getcenter_lat() * PI_180);
float _latmin = (fd.getlatmin() - border_deg_lat);
float _lonmin = (fd.getlonmin() - border_deg_lon);
float _latmax = (fd.getlatmax() + border_deg_lat);
float _lonmax = (fd.getlonmax() + border_deg_lon);
air.initAirspace(fd.getcenter_lat(), fd.getcenter_lon(),
_latmax, _latmin, _lonmax, _lonmin);
air.set_proj_pointer(&proj);
air.readOpenAirFile(conf.getAirspaceFileName());
}
// some Verbosity!
if (conf.VERBOSE.get()) {
cout << fd.getn() << " = Number of position fixes" << endl;
/*cout << "some info from igc-file:" << endl << "center x; y; z " << fd.getxcenter () << " " << fd.
getycenter () << " " << fd.getzcenter () << endl << "xmin xmax ymin ymax zmin zmax " << fd.
getxmin () << " " << fd.getxmax () << " " << fd.getymin () << " " << fd.getymax () << " " << fd.
getzmin () << " " << fd.getzmax () << endl; */
}
// if no DEM-data available, turn off LANDSCAPE
if (!conf.DEM.get()) {
//no DEM File
cerr << "No Digital Elevation Model (DEM-File)" << endl
<< "Read documention how to set up the config file" <<
endl << "starting without Terrain" << endl;
conf.LANDSCAPE.off();
//conf.toggleLANDSCAPE();
}
// impossibel condition ?!
if (!conf.FLIGHT.get() && conf.MARKER.get()) {
cerr <<
"Can't use \"Marker\" with no flightdata. \"Marker\" turned off."
<< endl;
conf.MARKER.off();
}
// set colormap limits !
if (args_info.colormap_max_given) {
conf.setmax_h(args_info.colormap_max_arg);
//cout << "colormap max" << endl;
}
if (args_info.colormap_min_given) {
conf.setmin_h(args_info.colormap_min_arg);
//cout << "colormap min" << endl;
}
// set marker-range and follow
if (args_info.follow_given)
conf.FOLLOW.on();
if (args_info.no_follow_given)
conf.FOLLOW.off();
if (args_info.marker_range_given)
conf.MARKER_RANGE.on();
if (args_info.no_marker_range_given)
conf.MARKER_RANGE.off();
if (args_info.marker_ahead_given)
conf.set_marker_ahead(args_info.marker_ahead_arg);
if (args_info.marker_back_given)
conf.set_marker_back(args_info.marker_back_arg);
if (args_info.flighttrack_mode_given) {
if (args_info.flighttrack_mode_arg >= 0
&& args_info.flighttrack_mode_arg <= 3) {
conf.flightstrip_mode.set(args_info.flighttrack_mode_arg);
} else {
cerr << "Flighttrack mode " << args_info.
flighttrack_mode_arg << " doesnt exist. (0=classic 2 color,1=alt,2=speed,3=vario). using default now."
<< endl;
}
}
//flightstrip_linewidth
if (args_info.flighttrack_linewidth_given) {
conf.flightstrip_width.set(args_info.flighttrack_linewidth_arg);
}
if (args_info.flighttrack_colormap_given) {
conf.flightstrip_colmap.set(args_info.flighttrack_colormap_arg);
}
//set initial position...
if (conf.DEBUG.get()) {
cout << "end of preliminary work... calling setinitpos" << endl << flush;
}
setinitpos();
if (conf.DEBUG.get()) {
cout << "returned from setinipos()" << endl << flush;
}
if (conf.LIFTS.get()) {
lifts.readLiftsFile(conf.getLiftsFileName());
float border_deg_lat = conf.getborder_land_lat() / DEGDIST;
float border_deg_lon =
(conf.getborder_land_lon() / DEGDIST) /
cos(fd.getcenter_lat() * PI_180);
float _latmin = (fd.getlatmin() - border_deg_lat);
float _lonmin = (fd.getlonmin() - border_deg_lon);
float _latmax = (fd.getlatmax() + border_deg_lat);
float _lonmax = (fd.getlonmax() + border_deg_lon);
lifts.setDegRanges(_latmax,_latmin,_lonmax,_lonmin);
}
if (conf.getWaypointsFileName() != "not available") {
waypoints.readWaypointsFile(conf.getWaypointsFileName());
float border_deg_lat = conf.getborder_land_lat() / DEGDIST;
float border_deg_lon =
(conf.getborder_land_lon() / DEGDIST) /
cos(fd.getcenter_lat() * PI_180);
float _latmin = (fd.getlatmin() - border_deg_lat);
float _lonmin = (fd.getlonmin() - border_deg_lon);
float _latmax = (fd.getlatmax() + border_deg_lat);
float _lonmax = (fd.getlonmax() + border_deg_lon);
waypoints.setDegRanges(_latmax,_latmin,_lonmax,_lonmin);
}
// ------------------ END of setting options etc -------------------------------------------------------
// ------------------ rendering ---------------------------------------------------------------------------
#ifdef NOGLX
// if someone tries to offscreen via GLX on non-GLX platform...
if (conf.OFFSCREEN.get()) {
cerr << "GLX offscreen rendering is not available!" << endl;
Ende(1);
}
#endif
#ifndef NOGLX
#ifndef ONLY_OSMESA
// OFFRSCEEN Rendering (with GLX)
if (conf.OFFSCREEN.get()) {
// measuring time
//timeval start;
//timeval stop;
//gettimeofday(&start, NULL);
Timecheck offscreentime("offscreen_rendering", &conf);
//create GLX offscreen rendering context....
//Xlib Diplay
Display *dpy;
//Get the Diplay...
dpy = XOpenDisplay(NULL); //will use env DIPLAY on posix .. man XOpenDisplay
if (dpy == NULL) {
cerr << "Cannot open Display!" << endl;
Ende(1);
}
// check for GLX extensions
if (!glXQueryExtension(dpy, NULL, NULL)) {
cerr <<
"X-Server doesn't have an OpenGL GLX extension"
<< endl;
Ende(1);
}
// Check GLX Version (we need >=1.3)
int major, minor;
glXQueryVersion(dpy, &major, &minor);
if (conf.VERBOSE.get())
cout << "GLX Version " << major << " . " << minor
<< endl;
if ((major == 1 && minor < 3) || major < 1) {
cerr <<
"at least GLX 1.3 is needed for offscreen rendering using glx-pbuffers!"
<< endl;
cerr << "your version is: " << major << "." <<
minor << endl;
Ende(1);
}
// these are the attributes the GLXFBConfig should have
int attrib_list[] = {
GLX_MAX_PBUFFER_PIXELS,
conf.getheight() * conf.getwidth(),
GLX_DOUBLEBUFFER, GL_FALSE,
//GLX_RGBA, GL_TRUE,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
//GLX_DEPTH_SIZE, 8,
//GLX_X_RENDERABLE, GL_TRUE,
//GLX_X_VISUAL_TYPE, GLX_X_VISUAL_TYPE,
GLX_RED_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_DEPTH_SIZE, 16,
None
};
// these are the attributes the pbuffer should have
int pbuffattrib_list[] = {
GLX_PBUFFER_HEIGHT, conf.getheight(),
GLX_PBUFFER_WIDTH, conf.getwidth(),
GLX_PRESERVED_CONTENTS, GL_TRUE,
GLX_LARGEST_PBUFFER, GL_FALSE,
None
};
// number of GLXFBConfigs returned by glXChooseFBConfig
int elements;
GLXFBConfig *configs;
configs =
glXChooseFBConfig(dpy, 0, attrib_list, &elements);
if (elements < 1) {
cerr << "No GLXFBConfigs returned ... (" << elements << ")" << endl;
Ende(1);
}
// Pbuffer and GLXContext
GLXPbuffer pbuff;
GLXContext ctx;
// Create Pbuffer
pbuff =
glXCreatePbuffer(dpy, configs[0], pbuffattrib_list);
// this seems not to work? what will be returned if glXCreatePbuffer fails?
/*
if (pbuff == NULL) {
cerr << "Can't create pbuffer" << endl;
Ende(1);
}
*/
// Create Context ( NULL -> no share list, GL_TRUE -> try to get an direct rendering context
ctx =
glXCreateNewContext(dpy, configs[0], GLX_RGBA_TYPE,
NULL, GL_FALSE);
if (ctx == NULL) {
cerr << "context not created" << endl;
Ende(1);
}
//make the context current
//glXMakeContextCurrent(dpy, pbuff, pbuff, ctx);
// hier gibts nen badAlloc wenn man auf der console ist :(
glXMakeCurrent(dpy, pbuff, ctx);
//now we are ready to openGL!
InitGL(conf.getwidth(), conf.getheight());
if (conf.FLIGHT.get())
GenFlightList(); //call the list-creator // with igc filename
GenLandscapeList();
GenAirspaceList();
// GenPointsList();
DrawGLScene();
screenshot();
/*gettimeofday(&stop, NULL);
float _time = (((float) stop.tv_sec - (float) start.tv_sec)
+
(((float) stop.tv_usec -
(float) start.tv_usec) / 1000000.0));
if (conf.VERBOSE.get())
cout << "Rendering time: " << _time << " secs" <<
endl;*/
offscreentime.checknow("rendering finished");
Ende(0);
}
#endif
#endif
#ifdef HAVE_LIBOSMESA
// OFFRSCEEN Rendering with mesa (osmesa)
// MESAMESAMESAMESAMESAMESAMESAMESAMESAMESAMESAMESAMESAMESAMESA ###############################
if (conf.OSMESA.get()) {
Timecheck osmesatime("osmesa_offscreen_redering", &conf);
//create mesa offscreen rendering context....
OSMesaContext ctx;
void *buffer;
if (conf.VERBOSE.get())
cout << "Rendering offscreen using OSMesa." << endl;
// 32 depth buffer bits
ctx = OSMesaCreateContextExt(OSMESA_RGBA, 32,0,0,NULL);
if (!ctx) {
cerr << "creating osmesa context failed!" << endl;
Ende(1);
}
// check max viewport dimensions
int _osmaxh, _osmaxw;//, _maj, _min, _pat;
OSMesaGetIntegerv(OSMESA_MAX_HEIGHT, &_osmaxh);
OSMesaGetIntegerv(OSMESA_MAX_WIDTH, &_osmaxw);
//OSMesaGetIntegerv(OSMESA_MAJOR_VERSION, &_maj);
//OSMesaGetIntegerv(OSMESA_MINOR_VERSION, &_min);
//OSMesaGetIntegerv(OSMESA_PATCH_VERSION, &_pat);
if (conf.VERBOSE.get()){
//cout << "Mesa, Version " << _maj <<"."<<_min<<"."<<_pat<<endl;
cout << "OSMESA_MAX_HEIGHT: " << _osmaxh << endl;
cout << "OSMESA_MAX_WIDTH: " << _osmaxw << endl;
}
if (conf.getwidth() <= _osmaxw && conf.getheight() <= _osmaxh) {
buffer =
malloc(conf.getwidth() * conf.getheight() * 4 *
sizeof(GLubyte));
if (!buffer) {
cerr <<
"allocating buffer for osmesa failed!"
<< endl;
Ende(1);
} else {
if (conf.VERBOSE.get())
cout << "buffer created " << conf.
getwidth() * conf.getheight() *
4 * sizeof(GLubyte) << endl;
}
} else {
cerr <<
"width and/or height too big for osmesa (max "<< _osmaxw << "x" <<_osmaxh<<")" << endl;
Ende(1);
}
if (!OSMesaMakeCurrent
(ctx, buffer, GL_UNSIGNED_BYTE, conf.getwidth(),
conf.getheight())) {
cerr << "Make context current failed!" << endl;
Ende(1);
}
//now we are ready to openGL!
InitGL(conf.getwidth(), conf.getheight());
if (conf.VERBOSE.get()){
int _dpw, _dph, _dpbpp;
void *bp;
OSMesaGetDepthBuffer( ctx, &_dpw, &_dph, &_dpbpp, &bp );//, void **buffer );
cout << "Depth buffer: "<< _dpw << " " << _dph << " " << _dpbpp << endl;
int _q;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &_q);
cout << "GL_MAX_TEXTURE_SIZE: " << _q << endl;
//glGetIntegerv(GL_MAX_EVAL_ORDER, &_q);
//cout << "GL_MAX_EVAL_ORDER: " << _q << endl;
//glGetIntegerv(GL_MAX_LIGHTS, &_q);
//cout << "GL_MAX_LIGHTS: " << _q << endl;
glGetIntegerv(GL_RED_BITS, &_q);
cout << "GL_RED_BITS: " << _q << endl;
glGetIntegerv(GL_GREEN_BITS, &_q);
cout << "GL_GREEN_BITS: " << _q << endl;
glGetIntegerv(GL_BLUE_BITS, &_q);
cout << "GL_BLUE_BITS: " << _q << endl;
glGetIntegerv(GL_ALPHA_BITS, &_q);
cout << "GL_ALPHA_BITS: " << _q << endl;
glGetIntegerv(GL_DEPTH_BITS, &_q);
cout << "GL_DEPTH_BITS: " << _q << endl;
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &_q);
cout << "GL_MAX_VIEWPORT_DIMS: " << _q << endl;
glGetIntegerv(GL_AUX_BUFFERS, &_q);
cout << "GL_AUX_BUFFERS: " << _q << endl;
const GLubyte *_string;
_string = glGetString(GL_VENDOR);
cout << "GL_VENDOR: " << _string << endl;
_string = glGetString(GL_RENDERER);
cout << "GL_RENDERER: " << _string << endl;
_string = glGetString(GL_VERSION);
cout << "GL_VERSION: " << _string << endl;
//_string = glGetString(GL_EXTENSIONS);
//cout << "GL_EXTENSIONS: " << _string << endl;
}
if (conf.FLIGHT.get())
GenFlightList(); //call the list-creator // with igc filename
GenLandscapeList();
GenAirspaceList();
//GenPointsList();
DrawGLScene();
screenshot();
/* free the image buffer */
free(buffer);
/* destroy the context */
OSMesaDestroyContext(ctx);
osmesatime.checknow("rendering finished");
Ende(0);
}
#endif
#ifndef HAVE_LIBOSMESA
// OFFRSCEEN Rendering with mesa (osmesa)
if (conf.OSMESA.get()) {
cerr << "Osmesa support is not compiled into this binary..." << endl;
Ende(1);
}
#endif
#ifndef ONLY_OSMESA
//entering interactive mode....
if (conf.DEBUG.get()) {
cout << "entering interactive mode (no offscreen rendering)" << endl << flush;
}
if (args_info.movie_given ) {
conf.FLYING.on();
}
// do this check only if DEBUG or FGLUT_CHECK is given...
// if (conf.DEBUG.get() || conf.FGLUT_CHECK.get()) {
// check GLUT_VERSION... (maybe this should be tested earlier?!
// but checking needs glutInit called before...
int _glut_version = glutGet(GLUT_VERSION);
if (_glut_version > 10000 && _glut_version < 20801) {
cout <<" ****************************************************** " <<endl<<
" ** You are using an ancient version of Freeglut. ** " <<endl<<
" ** Most likely you'll encounter problems with **" <<endl<<
" ** the menus or worse. Consider updating **" <<endl<<
" ** Freeglut to at least 2.8.1 **" <<endl<<
" ******************************************************" << endl;
}
if (conf.DEBUG.get()) {
cout << "glutGet(GLUT_VERSION) called:" << _glut_version << endl << flush;
}
// in freeglut freeglut_state.c
// this is the case, when old-glut is used (+warning... because GLUT_VERSION not known)
if (_glut_version == -1) {
cout << "above warning is harmless... I just tried to glutGet(GLUT_VERSION), which is available"
<< " in freeglut only..." << endl;
} else {
// OK we got an GLUT_VERSION number, but is it sure that its freeglut then?
// maybe some strange gluts around, which have glutGet(GLUT_VERSION) ???
conf.FGLUT.on();
conf.fglut_version.set(_glut_version);
}
// } else {
// if (conf.VERBOSE.get())
// cout << "FGLUT_CHECK skipped. Neither --debug nor FGLUT_CHECK given. Assume old glut." << endl;
// }
if ( conf.DEBUG.get() || conf.VERBOSE.get() ){
cout << "glutGet(GLUT_VERSION): " << conf.fglut_version.get() << endl;
cout << "conf.FGLUT.get(): " << conf.FGLUT.get() << endl;
}
// try GLUT_STEREO if requestet by user
if (conf.DEBUG.get()) {
cout << "calling glutInitDisplayMode..." << endl << flush;
}
if (!conf.STEREO_HW.get()) {
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
} else {
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH |
GLUT_STEREO);
}
if (conf.DEBUG.get()) {
cout << "glutInitDisplayMode called..." << endl << flush;
}
// now with depth buffer !
if (conf.DEBUG.get()) {
cout << "calling glutInitWindowSize and InitWindowPosition" << endl << flush;
}
glutInitWindowSize(conf.getwidth(), conf.getheight());
// initial window position
glutInitWindowPosition(0, 0);
if (conf.DEBUG.get()) {
cout << "initwindowsize and initwindowposition finished" << endl << flush;
}
// open the GLUT window
char namestring[80];
sprintf(namestring, "%s %s%s %s by %s", OGIE_PACKAGE.c_str(), OGIE_VERSION.c_str(),
DEVELOPEMENT.c_str(), COPYRIGHT.c_str(), AUTHOR.c_str());
if (conf.DEBUG.get()) {
cout << "calling glutCreateWindow! :" << namestring << endl << flush;
}
window = glutCreateWindow(namestring);
if (conf.DEBUG.get()) {
cout << "glutCreateWindow called:" << window << endl << flush;
}
if (conf.DEBUG.get()) {
const GLubyte *_string;
_string = glGetString(GL_VENDOR);
cout << "GL_VENDOR: " << _string;
_string = glGetString(GL_RENDERER);
cout << " GL_RENDERER: " << _string;
_string = glGetString(GL_VERSION);
cout << " GL_VERSION: " << _string << endl;
}
if (conf.FULLSCREEN.get())
glutFullScreen();
// register the rendering routine
glutDisplayFunc(&DrawGLScene);
glutReshapeFunc(&ReSizeGLScene);
if (conf.GPSD.get() || conf.FLYING.get()) {
glutIdleFunc(&IdleFunc);
}
// Initialize the window.
InitGL(conf.getwidth(), conf.getheight());
// openGL commandos erst nach erzeugung des openGL contextes (hier Glutfenster)
if (conf.FLIGHT.get())
GenFlightList(); //call the list-creator // with igc filename
GenLandscapeList();
GenAirspaceList();
//GenPointsList();
DrawGLScene();
//create menus
glutMenuStatusFunc(&menuStatus);
GenMenu();
//mouse and keyboard callback registration
if (!conf.MOUSE.get()) {
glutPassiveMotionFunc(&mouseMove);
//glutMotionFunc(NULL);
glutSetCursor(GLUT_CURSOR_NONE);
}
glutMotionFunc(&mouseClickMove);
glutMouseFunc(&mouseClickState);
glutKeyboardFunc(&keyPressed);
glutSpecialFunc(&SpecialKeyPressed);
// start main loop
glutMainLoop();
#endif
return 1;
}
void Ende(int e)
{
#ifndef ONLY_OSMESA
if (window != -3992) {
glutDestroyWindow(window);
}
#endif
#ifndef __WIN32__
// this tells GPLIGC that OGIE exits
if (args_info.parent_pid_given) {
kill(args_info.parent_pid_arg, SIGUSR1);
}
#endif
exit(e);
}