1535 lines
33 KiB
C++
1535 lines
33 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/>
|
|
*
|
|
*/
|
|
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <cmath>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
|
|
#include "oglexfunc.h"
|
|
#include "GLexplorer.h"
|
|
#include "map.h"
|
|
#include "cmdline.h"
|
|
|
|
//const std::string rcsid_oglexfunc_cpp =
|
|
// "$Id: oglexfunc.cpp 3 2014-07-31 09:59:20Z kruegerh $";
|
|
//const std::string rcsid_oglexfunc_h = OGLEXFUNC_H;
|
|
|
|
|
|
#ifndef OPTIMIZER
|
|
|
|
void gltext(GLuint x, GLuint y, GLfloat scale, const char *txt, int _width,
|
|
int _height, float _r, float _g, float _b)
|
|
{
|
|
/*
|
|
cout << "gltext START: " << flush;
|
|
glutReportErrors();
|
|
cout << endl << flush;
|
|
*/
|
|
|
|
GLfloat font_scale = 119.05 + 33.33; //see glutStrkeCharacter 10.3 GLUT-spec
|
|
|
|
|
|
glMatrixMode(GL_PROJECTION); //switch to projection matrix
|
|
glPushMatrix(); //save projection matrix
|
|
glLoadIdentity(); //load identity matrix
|
|
|
|
//gluOrtho2D(0, glutGet(GLUT_WINDOW_WIDTH), 0, glutGet(GLUT_WINDOW_HEIGHT));
|
|
gluOrtho2D(0, _width, 0, _height);
|
|
|
|
//Orthographic projection
|
|
|
|
glMatrixMode(GL_MODELVIEW); //switch to modelview matrix
|
|
glPushMatrix(); //save modelview matrix
|
|
glLoadIdentity(); //load identity matrix in modelview
|
|
|
|
|
|
//glPushAttrib(GL_ENABLE_BIT);
|
|
glDisable(GL_LIGHTING);
|
|
glEnable(GL_LINE_SMOOTH);
|
|
|
|
//was ist +1?
|
|
glTranslatef(x, y, +1);
|
|
|
|
glColor3f(_r, _g, _b);
|
|
glScalef(scale / font_scale, scale / font_scale,
|
|
scale / font_scale);
|
|
|
|
//int sumwidth = 0;
|
|
for (const char *p = txt; *p; p++)
|
|
|
|
//#ifndef ONLY_OSMESA
|
|
glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
|
|
// glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, *p);
|
|
//sumwidth = sumwidth + glutStrokeWidth(GLUT_STROKE_MONO_ROMAN, *p);
|
|
//#endif
|
|
|
|
//glPopAttrib();
|
|
|
|
//cout << "sum is = " << sumwidth << endl;
|
|
|
|
glEnable(GL_LIGHTING);
|
|
glDisable(GL_LINE_SMOOTH);
|
|
|
|
|
|
glPopMatrix(); //restore modelview matrix
|
|
glMatrixMode(GL_PROJECTION); //switch to projrction matrix
|
|
glPopMatrix(); // restore projection matrix
|
|
glMatrixMode(GL_MODELVIEW); //switch to modelview matrix again
|
|
|
|
/*
|
|
cout << "gltext END: " << flush;
|
|
glutReportErrors();
|
|
cout << endl << flush;
|
|
*/
|
|
|
|
}
|
|
|
|
// This plots text on a transparent background...
|
|
void gltextvect(GLuint x, GLuint y, GLfloat scale, vector < string > lines, int _width, int _height, bool ortho)
|
|
{
|
|
/*
|
|
cout << "gltextvect START: " << flush;
|
|
glutReportErrors();
|
|
cout << endl << flush;
|
|
*/
|
|
|
|
//GLfloat font_scale = 119.05 + 33.33; //see glutStrkeCharacter 10.3 GLUT-spec
|
|
|
|
|
|
glMatrixMode(GL_PROJECTION); //switch to projection matrix
|
|
glPushMatrix(); //save projection matrix
|
|
glLoadIdentity(); //load identity matrix
|
|
|
|
//gluOrtho2D(0, glutGet(GLUT_WINDOW_WIDTH), 0, glutGet(GLUT_WINDOW_HEIGHT));
|
|
gluOrtho2D(0, _width, 0, _height);
|
|
|
|
//Orthographic projection
|
|
|
|
glMatrixMode(GL_MODELVIEW); //switch to modelview matrix
|
|
glPushMatrix(); //save modelview matrix
|
|
glLoadIdentity(); //load identity matrix in modelview
|
|
|
|
|
|
int font_height = (int) scale;
|
|
|
|
int max_text_width = 0;
|
|
for (int z = 0; z <= (int (lines.size() - 1)); z++) {
|
|
|
|
int len = strlen(lines[z].c_str());
|
|
if(len > max_text_width)
|
|
max_text_width = len;
|
|
}
|
|
|
|
float x0 = x - 5.0 ;
|
|
float y0 = (float) (_height - ((lines.size()+1)*font_height));
|
|
float x1 = (float) (max_text_width*font_height/2.0); // 1.35 seems good as a font height/width ratio
|
|
// I changed it to 2.0 seems better, I have to check for possible differences between glut and freeglut
|
|
float y1 = _height;
|
|
|
|
// Draw an alpha blended background for the text
|
|
//glPushAttrib(GL_ENABLE_BIT);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glEnable(GL_BLEND);
|
|
glDisable(GL_LIGHTING);
|
|
glEnable(GL_LINE_SMOOTH);
|
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
|
|
glBegin(GL_QUADS);
|
|
glColor4f(0.0, 0.0, 0.0, 0.5);
|
|
|
|
//was auch immer ich mir hier gedacht habe... 0.9 scheint OK zu sein
|
|
float _alt=0.9 ; //=0.0; // was -0.9
|
|
|
|
//Das war wohl Zeitverschwendung
|
|
/*if (ortho) {
|
|
_alt = 0.9;
|
|
cout << "orthomode..." << endl;
|
|
} else {
|
|
_alt= 0.9;
|
|
cout << "nicht orthomode " << endl;
|
|
}*/
|
|
|
|
glVertex3f(x0, y0, _alt); // at z=1, otherwise it is lower tham the surface in orthomode
|
|
glVertex3f(x1, y0, _alt);
|
|
glVertex3f(x1, y1, _alt);
|
|
glVertex3f(x0, y1, _alt);
|
|
glEnd();
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
//cerr << "lines: " << lines.size() << endl;
|
|
for (int z = 0; z <= (int (lines.size() - 1)); z++) {
|
|
|
|
gltext(x, _height - (font_height * (z+1)), font_height, lines[z].c_str(), _width, _height, 1.0,1.0,1.0);
|
|
}
|
|
|
|
//glPopAttrib();
|
|
glEnable(GL_LIGHTING);
|
|
glDisable(GL_LINE_SMOOTH);
|
|
|
|
|
|
glPopMatrix(); //restore modelview matrix
|
|
glMatrixMode(GL_PROJECTION); //switch to projrction matrix
|
|
glPopMatrix(); // restore projection matrix
|
|
glMatrixMode(GL_MODELVIEW); //switch to modelview matrix again
|
|
|
|
/*
|
|
cout << "gltextvect END: " << flush;
|
|
glutReportErrors();
|
|
cout << endl << flush;
|
|
*/
|
|
|
|
}
|
|
|
|
|
|
//wrapper for single values
|
|
int get_1gnd_elevation(float _lat, float _lon, Config* _conf)
|
|
{
|
|
vector<int> _alt;
|
|
vector<float>_llat;
|
|
vector<float>_llon;
|
|
|
|
_llat.push_back(_lat);
|
|
_llon.push_back(_lon);
|
|
_alt.push_back(0);
|
|
get_gnd_elevations(&_alt,&_llat,&_llon,_conf);
|
|
return (_alt[0]);
|
|
}
|
|
|
|
|
|
|
|
// what should this function return in case of sea-surface ???
|
|
// altitudes above NN or above seafloor?
|
|
// for now it will return elevations above NN
|
|
// how to distinguish between voids? in srtm-3 from seamless server a void is 0!
|
|
// otherwise a void is -32...
|
|
|
|
void
|
|
get_gnd_elevations(vector < int >*_gnd_elev, vector < float >*_lat,
|
|
vector < float >*_lon, Config * _conf)
|
|
{
|
|
|
|
// vector _gnd_elev will be altered....
|
|
|
|
if (_conf->DEBUG.get() ) {cout << "entering get_gnd_elevations " << (*_gnd_elev).size() << endl << flush ;}
|
|
|
|
ifstream demfile;
|
|
|
|
demfile.open(_conf->getDemFileName().c_str(), ios::binary);
|
|
if (!demfile) {
|
|
cerr <<
|
|
"Error opening DEM file: (in function get_gnd_elev) >"
|
|
<< _conf->getDemFileName() << "<" << endl;
|
|
exit(1);
|
|
}
|
|
|
|
|
|
int steps_lat, steps_lon, i1, i2, verschieber;
|
|
short int h1, h2, h3, h4;
|
|
short int watercounter;
|
|
short int seafloorcounter;
|
|
vector <short int> neighbours;
|
|
float lat_frac, lon_frac;
|
|
|
|
|
|
for (int i = 0; i < (int) _lat->size(); i++) {
|
|
//init vars for each loop
|
|
watercounter = 0;
|
|
seafloorcounter = 0;
|
|
|
|
second_try:
|
|
|
|
if ((*_lat)[i] < _conf->getdem_lat_min() ||
|
|
(*_lat)[i] > _conf->getdem_lat_max() ||
|
|
(*_lon)[i] < _conf->getdem_lon_min() ||
|
|
(*_lon)[i] > _conf->getdem_lon_max() ) {
|
|
|
|
if ((*_lon)[i] > 180.0) {
|
|
(*_lon)[i] -= 360.0;
|
|
goto second_try;
|
|
}
|
|
if ((*_lon)[i] < -180.0) {
|
|
(*_lon)[i] += 360.0;
|
|
goto second_try;
|
|
}
|
|
|
|
|
|
cerr << "get_gnd_elevations(...): outside of DEM requested!" << endl;
|
|
(*_gnd_elev)[i] = -9;
|
|
(*_gnd_elev).push_back(9999);
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
steps_lat = (int) (1.0 +
|
|
(_conf->getdem_lat_max() -
|
|
(*_lat)[i]) / _conf->getdem_grid_lat()
|
|
);
|
|
|
|
|
|
steps_lon = (int) (((*_lon)[i] -
|
|
_conf->getdem_lon_min()) /
|
|
_conf->getdem_grid_lon()
|
|
);
|
|
|
|
|
|
lat_frac =
|
|
fabs(-steps_lat * _conf->getdem_grid_lat() +
|
|
_conf->getdem_lat_max() - (*_lat)[i])
|
|
/ _conf->getdem_grid_lat();
|
|
|
|
|
|
lon_frac =
|
|
fabs(-steps_lon * _conf->getdem_grid_lon() -
|
|
_conf->getdem_lon_min() + (*_lon)[i])
|
|
/ _conf->getdem_grid_lon();
|
|
|
|
|
|
//cout << "lat: " << lat_frac << " lon: " << lon_frac << endl;
|
|
|
|
verschieber =
|
|
(steps_lat * _conf->getdem_columns() + steps_lon) * 2;
|
|
|
|
|
|
demfile.seekg(verschieber, ios::beg);
|
|
|
|
|
|
|
|
i1 = demfile.get();
|
|
i2 = demfile.get();
|
|
|
|
if (_conf->BIGENDIAN.get()) {
|
|
h1 = 256 * i1 + i2;
|
|
} else {
|
|
h1 = 256 * i2 + i1;
|
|
}
|
|
|
|
|
|
if (_conf->input_dem_factor.get() != 1.0) {
|
|
h1 = (int) ( (float)h1 * _conf->input_dem_factor.get()+0.5);
|
|
}
|
|
|
|
|
|
neighbours.push_back(h1);
|
|
if (h1 == -9999)// || h1 <= -16384)
|
|
watercounter++; //h1 = 0; // in this case this is OK warum nicht 0?
|
|
if (h1 <= -16384)
|
|
seafloorcounter++;
|
|
|
|
|
|
steps_lat = (int) (1.0 +
|
|
(_conf->getdem_lat_max() -
|
|
(*_lat)[i]) /
|
|
_conf->getdem_grid_lat());
|
|
|
|
|
|
steps_lon = (int) (1.0 +
|
|
((*_lon)[i] -
|
|
_conf->getdem_lon_min()) /
|
|
_conf->getdem_grid_lon());
|
|
|
|
verschieber =
|
|
(steps_lat * _conf->getdem_columns() + steps_lon) * 2;
|
|
|
|
|
|
demfile.seekg(verschieber, ios::beg);
|
|
|
|
|
|
i1 = demfile.get();
|
|
i2 = demfile.get();
|
|
|
|
if (_conf->BIGENDIAN.get()) {
|
|
h2 = 256 * i1 + i2;
|
|
} else {
|
|
h2 = 256 * i2 + i1;
|
|
}
|
|
//h2 = 256 * i1 + i2;
|
|
|
|
if (_conf->input_dem_factor.get() != 1.0) {
|
|
h2 = (int) ( (float)h2 * _conf->input_dem_factor.get()+0.5);
|
|
}
|
|
|
|
neighbours.push_back(h2);
|
|
if (h2 == -9999)// || h2 <= -16384)
|
|
watercounter++;//h2 = 0;
|
|
if (h2 <= -16384)
|
|
seafloorcounter++;
|
|
|
|
|
|
steps_lat = (int) ((_conf->getdem_lat_max() -
|
|
(*_lat)[i]) /
|
|
_conf->getdem_grid_lat());
|
|
|
|
|
|
steps_lon = (int) (((*_lon)[i] -
|
|
_conf->getdem_lon_min()) /
|
|
_conf->getdem_grid_lon());
|
|
|
|
verschieber =
|
|
(steps_lat * _conf->getdem_columns() + steps_lon) * 2;
|
|
|
|
demfile.seekg(verschieber, ios::beg);
|
|
|
|
|
|
i1 = demfile.get();
|
|
i2 = demfile.get();
|
|
if (_conf->BIGENDIAN.get()) {
|
|
h3 = 256 * i1 + i2;
|
|
} else {
|
|
h3 = 256 * i2 + i1;
|
|
}
|
|
//h3 = 256 * i1 + i2;
|
|
|
|
if (_conf->input_dem_factor.get() != 1.0) {
|
|
h3= (int) ( (float)h3 * _conf->input_dem_factor.get()+0.5);
|
|
}
|
|
|
|
neighbours.push_back(h3);
|
|
if (h3 == -9999)// || h3 <= -16384)
|
|
watercounter++;//h3 = 0;
|
|
if (h3 <= -16384)
|
|
seafloorcounter++;
|
|
|
|
steps_lat = (int) ((_conf->getdem_lat_max() -
|
|
(*_lat)[i]) /
|
|
_conf->getdem_grid_lat());
|
|
|
|
|
|
steps_lon = (int) (1.0 +
|
|
((*_lon)[i] -
|
|
_conf->getdem_lon_min()) /
|
|
_conf->getdem_grid_lon());
|
|
|
|
verschieber =
|
|
(steps_lat * _conf->getdem_columns() + steps_lon) * 2;
|
|
|
|
|
|
demfile.seekg(verschieber, ios::beg);
|
|
|
|
|
|
i1 = demfile.get();
|
|
i2 = demfile.get();
|
|
if (_conf->BIGENDIAN.get()) {
|
|
h4 = 256 * i1 + i2;
|
|
} else {
|
|
h4 = 256 * i2 + i1;
|
|
}
|
|
//h4 = 256 * i1 + i2;
|
|
if (_conf->input_dem_factor.get() != 1.0) {
|
|
h4 = (int) ( (float)h4 * _conf->input_dem_factor.get()+0.5);
|
|
}
|
|
|
|
neighbours.push_back(h4);
|
|
if (h4 == -9999) // || h4 <= -16384)
|
|
watercounter++;//h4 = 0;
|
|
if (h4 <= -16384)
|
|
seafloorcounter++;
|
|
|
|
|
|
// this implements bilinear-interpolation!
|
|
(*_gnd_elev)[i] = (int) (
|
|
((1.0 - lon_frac) * (1.0 - lat_frac) * (double) h1 +
|
|
lon_frac * (1.0 - lat_frac) * (double) h2 +
|
|
(1.0 - lon_frac) * lat_frac * (double) h3 +
|
|
lat_frac * lon_frac * (double) h4) +0.5);
|
|
// now rounded :-) rounding error?!
|
|
|
|
// if there is water
|
|
if (watercounter == 1 || watercounter == 2) {
|
|
(*_gnd_elev)[i] = 0;
|
|
}
|
|
|
|
if (watercounter > 2)
|
|
(*_gnd_elev)[i] = 0; // this schould fix the seabug (David)
|
|
// (*_gnd_elev)[i] = -22222;
|
|
|
|
// if one or two of the neighbours are seafloor, then we set the elevation to 0 (coast)
|
|
if (seafloorcounter > 0 ) {
|
|
if (seafloorcounter == 1 || seafloorcounter == 2)
|
|
(*_gnd_elev)[i] = 0;
|
|
|
|
//if three neighbours are seafloor, then we set elevation to -16384 (sea with 0)
|
|
// if -16383 => workaround... rounding error in interpolation?
|
|
if (seafloorcounter == 3 || (*_gnd_elev)[i] == -16383 )
|
|
|
|
(*_gnd_elev)[i] = -16384;
|
|
// if 4x seafloor, then its ok
|
|
}
|
|
|
|
|
|
|
|
// Add warning signs! if invalid elevations read
|
|
// this only works for data in srtm-3 from seamless server, which uses 0 for invalid data (stupid!)
|
|
int neg_counter=0;
|
|
if (_conf->GETELEV_WARN.get()) {
|
|
// count neighbours equal zero!
|
|
for(unsigned int a=0; a<= neighbours.size()-1; a++) {
|
|
if (neighbours[a] <= 0) {
|
|
neg_counter--;
|
|
}
|
|
}
|
|
// we return a negative integer, indicating how many points are invalid
|
|
if (neg_counter < 0) {(*_gnd_elev)[i] = neg_counter;}
|
|
}
|
|
|
|
// simple preliminary error-guess
|
|
if (_conf->GETELEV_ERROR.get()) {
|
|
int min=10000;
|
|
int max=0;
|
|
for(unsigned int a=0; a<= neighbours.size()-1; a++) {
|
|
if (neighbours[a] < min)
|
|
min = neighbours[a];
|
|
if (neighbours[a] > max)
|
|
max = neighbours[a];
|
|
}
|
|
|
|
// an error is added to the elevation array
|
|
if (neg_counter < 0) {
|
|
(*_gnd_elev).push_back(max);
|
|
if (max-min != max) {
|
|
cerr << "AAAAAAAAAAAAAAAALLLLLLLLLLLAAAAAAAAAARRRRRRRMMMMMMMM!!"<<endl;
|
|
}
|
|
|
|
}else{
|
|
(*_gnd_elev).push_back(max-min);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
demfile.close();
|
|
if (_conf->DEBUG.get() ) {cout << "get_gnd_elevations finished " << endl << flush ;}
|
|
}
|
|
|
|
|
|
// this function turns any color into gray!
|
|
float *graycolor(float *_color)
|
|
{
|
|
|
|
|
|
float red = _color[0];
|
|
float green = _color[1];
|
|
float blue = _color[2];
|
|
|
|
for (int z = 0; z < 3; z++)
|
|
_color[z] = 0.3 * red + 0.59 * green + 0.11 * blue;
|
|
|
|
return _color;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
float
|
|
great_circle_dist(float lat1, float lon1, float lat2, float lon2,
|
|
float radius)
|
|
{
|
|
|
|
return (radius
|
|
* (acos(cos(lat1 * (M_PI / 180.0)) *
|
|
cos(lat2 * (M_PI / 180.0)) *
|
|
cos(lon2 * (M_PI / 180.0) - lon1 * (M_PI / 180.0))
|
|
+ sin(lat1 * (M_PI / 180.0))
|
|
* sin(lat2 * (M_PI / 180.0)))
|
|
)
|
|
);
|
|
}
|
|
|
|
#ifndef OPTIMIZER
|
|
|
|
//this is translated from GPLIGCfunctions.pm
|
|
void
|
|
go(float lat1, float lon1, float heading, float distance, float &lat2,
|
|
float &lon2, float radius)
|
|
{
|
|
|
|
//distance needs to be in radians
|
|
float c = ((2 * M_PI) / (radius * 2 * M_PI)) * distance;
|
|
|
|
//get a in radians
|
|
float a = 90 - lat1;
|
|
a *= M_PI / 180.0;
|
|
|
|
float beta = heading * (M_PI / 180.0);
|
|
|
|
// berechnung nach Seitenkosinussatz
|
|
float b = acos(cos(c) * cos(a)
|
|
+ sin(c) * sin(a) * cos(beta)
|
|
);
|
|
|
|
|
|
|
|
float gamma = asin((sin(c) / sin(b)) * sin(beta)
|
|
);
|
|
|
|
b /= M_PI / 180.0;
|
|
gamma /= M_PI / 180.0;
|
|
|
|
lat2 = 90.0 - b;
|
|
lon2 = lon1 + gamma;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
// translation from GPLIGCfunctions.pm
|
|
float heading(float lat1, float lon1, float lat2, float lon2)
|
|
{
|
|
|
|
|
|
|
|
float b = 90 - lat1;
|
|
float a = 90 - lat2;
|
|
|
|
|
|
float gamma = lon1 - lon2;
|
|
if (gamma < 0) {
|
|
gamma = gamma * -1.0;
|
|
}
|
|
|
|
float c = (acos(cos(a * (M_PI / 180.0)) * cos(b * (M_PI / 180.0))
|
|
+
|
|
sin(a * (M_PI / 180.0)) * sin(b * (M_PI / 180.0)) *
|
|
cos(gamma * (M_PI / 180.0))
|
|
)) / (M_PI / 180.0);
|
|
|
|
float alpha = 0;
|
|
|
|
|
|
if (c != 0) { // c == 0 if there is no movement ?
|
|
float zwischenrechnung =
|
|
(sin(a * (M_PI / 180.0)) / sin(c * (M_PI / 180.0))) *
|
|
sin(gamma * (M_PI / 180.0));
|
|
if (zwischenrechnung > 1) {
|
|
zwischenrechnung = 1.0;
|
|
}
|
|
|
|
alpha = (asin(zwischenrechnung)) / (M_PI / 180.0);
|
|
}
|
|
//if ($lon2 < $lon1) {$alpha = 360-$alpha};
|
|
|
|
|
|
//print "a= $a, b= $b, gamma = $gamma, c = $c \n";
|
|
|
|
if (lat1 >= lat2 && lon2 >= lon1) {
|
|
alpha = 180 - alpha;
|
|
goto endmarke;
|
|
} // quadrant 2
|
|
|
|
if (lat1 >= lat2 && lon2 <= lon1) {
|
|
alpha = 180 + alpha;
|
|
goto endmarke;
|
|
} // quadrant 3
|
|
|
|
if (lat1 <= lat2 && lon1 >= lon2) {
|
|
alpha = 360 - alpha;
|
|
goto endmarke;
|
|
} // quadrant 4
|
|
|
|
|
|
endmarke:
|
|
|
|
return alpha;
|
|
|
|
}
|
|
|
|
void getcolor(float *colorpointer, int colormap, float value, float min, float max)
|
|
{
|
|
// we use 2 colorscales. One beneath sealevel and one above.
|
|
// to use different colormaps (e.g. No.1 beneath, No.2 above)
|
|
// we need to choose before getcolor is called.
|
|
|
|
// h value -22222 means: surface of ocean... (always blue)
|
|
|
|
// colormap 1
|
|
// For a start, this implements MATLABS eye-burning 'Jet'
|
|
// colormap with extension red->white for large values.
|
|
// Ripped out of GPEsim from Jan.Krueger@uni-konstanz.de
|
|
|
|
int color = 0;
|
|
int r = 0;
|
|
int g = 0;
|
|
int b = 0;
|
|
|
|
int select = 1;
|
|
float tmp = value - min;
|
|
|
|
if (value == -22222.0) {
|
|
b = 255;
|
|
goto ende;
|
|
}
|
|
|
|
|
|
if (max - min == 0) { // Avoid floating point exception (div by zero)
|
|
//cerr << "Will be single colour. max == min in getcolor" << endl;
|
|
//cerr << "Workaround max += 0.1";
|
|
max += 0.1;
|
|
//exit(1);
|
|
}
|
|
|
|
|
|
// modified Jet colormap
|
|
if (colormap == 1) {
|
|
color = (int) (8 * 255 * tmp / (max - min));
|
|
|
|
if (color < 0)
|
|
color = 0;
|
|
|
|
if (color >= 7 * 255) { // Color map exception (i.e. off limits...)
|
|
select = 10;
|
|
goto switchlabel_1;
|
|
}
|
|
|
|
if (color > (6 * 255)) { //red to white
|
|
select = 7;
|
|
goto switchlabel_1;
|
|
}
|
|
if (color > (5 * 255)) { //magenta to red
|
|
select = 6;
|
|
goto switchlabel_1;
|
|
}
|
|
if (color > (4 * 255)) { //blue to magenta
|
|
select = 5;
|
|
goto switchlabel_1;
|
|
}
|
|
if (color > (3 * 255)) { //turquoise to blue
|
|
select = 4;
|
|
goto switchlabel_1;
|
|
}
|
|
if (color > (2 * 255)) { //green to turquoise
|
|
select = 3;
|
|
goto switchlabel_1;
|
|
}
|
|
if (color > (255)) { //yellow to green
|
|
select = 2;
|
|
goto switchlabel_1;
|
|
}
|
|
select = 1; //red to yellow
|
|
goto switchlabel_1;
|
|
|
|
switchlabel_1:
|
|
switch (select) {
|
|
case 10:
|
|
{
|
|
r = 255; //exception to colormap jet for Psi^2<(minimum density)
|
|
g = 255; // white snowy peaks...
|
|
b = 255;
|
|
break;
|
|
}
|
|
case 9: //sealevel
|
|
{
|
|
r = 0;
|
|
g = 0;
|
|
b = 255;
|
|
break;
|
|
}
|
|
case 7:
|
|
{
|
|
r = 255; // red to white
|
|
g = color - 6 * 255;
|
|
b = color - 6 * 255;
|
|
break;
|
|
}
|
|
case 6:
|
|
{
|
|
r = 255; //magenta to red
|
|
g = 0;
|
|
b = 6 * 255 - color;
|
|
break;
|
|
}
|
|
case 5:
|
|
{
|
|
r = color - 4 * 255; //blue to magenta
|
|
g = 0;
|
|
b = 255;
|
|
break;
|
|
}
|
|
case 4:
|
|
{
|
|
r = 0; //turquoise to blue
|
|
g = 4 * 255 - color;
|
|
b = 255;
|
|
break;
|
|
}
|
|
case 3:
|
|
{
|
|
r = 0; //green to turquoise
|
|
g = 255;
|
|
b = color - 2 * 255;
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
r = 2 * 255 - color; //yellow to green
|
|
g = 255;
|
|
b = 0;
|
|
break;
|
|
}
|
|
case 1:
|
|
{
|
|
r = 255; //red to yellow
|
|
g = color;
|
|
b = 0;
|
|
break;
|
|
}
|
|
} // switch
|
|
}
|
|
|
|
|
|
|
|
if (colormap == 2) { // Atlas color map
|
|
color = (int) (4 * 255 * tmp / (max - min));
|
|
|
|
if (color < 0)
|
|
color = 0;
|
|
// tmp = 0;
|
|
|
|
if (color >= 3 * 255) { // Color map exception (i.e. off limits...)
|
|
select = 10;
|
|
goto switchlabel_2;
|
|
}
|
|
if (color > (2 * 255)) { //red to white
|
|
select = 3;
|
|
goto switchlabel_2;
|
|
}
|
|
if (color > (255)) { //yellow to red
|
|
select = 2;
|
|
goto switchlabel_2;
|
|
}
|
|
select = 1; //green to yellow
|
|
goto switchlabel_2;
|
|
|
|
switchlabel_2:
|
|
switch (select) {
|
|
case 10:
|
|
{
|
|
r = 255; //exception to colormap jet for Psi^2<(minimum density)
|
|
g = 255; // white snowy peaks...
|
|
b = 255;
|
|
break;
|
|
}
|
|
case 9: //sealevel
|
|
{
|
|
r = 0;
|
|
g = 0;
|
|
b = 255;
|
|
break;
|
|
}
|
|
case 3:
|
|
{
|
|
r = 255; // red to white
|
|
g = color - 2 * 255;
|
|
b = color - 2 * 255;
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
r = 240 + (int) (15.0 * (double) (color - 255) / 255.0); //yellow to red
|
|
g = 240 -
|
|
(int) (240.0 * (double) (color - 255) /
|
|
255.0);;
|
|
b = 0;
|
|
break;
|
|
}
|
|
case 1:
|
|
{
|
|
r = (int) (240.0 * (double) color / 255.0); // green to yellow
|
|
g = 180 +
|
|
(int) (60.0 * (double) color / 255.0);
|
|
b = 0;
|
|
break;
|
|
}
|
|
} // switch
|
|
} // map2
|
|
|
|
|
|
if (colormap == 3) { //this is Hannes' Moon-(Color)map :)
|
|
|
|
color = (int) ((255) * tmp / (max - min));
|
|
|
|
if (color > (255)) {
|
|
color = 255;
|
|
}
|
|
if (color < 0) {
|
|
color = 0;
|
|
}
|
|
|
|
|
|
|
|
r = 255 - (255 - color);
|
|
g = 255 - (255 - color);
|
|
b = 255 - (255 - color);
|
|
|
|
}
|
|
|
|
|
|
// Hannes - Colormap 4 - drk.green->yellow->red
|
|
if (colormap == 4) {
|
|
color =
|
|
(int) ((2 * 255 + 185) * tmp / (max - min));
|
|
|
|
if (color < 0) {
|
|
color = 0;
|
|
}
|
|
if (color > (2 * 255 + 185)) {
|
|
color = 2 * 255 + 185;
|
|
}
|
|
|
|
if (color >= (185 + 255)) {
|
|
select = 1;
|
|
goto switchlabel_4;
|
|
}
|
|
|
|
if (color > (185)) {
|
|
select = 2;
|
|
goto switchlabel_4;
|
|
}
|
|
|
|
if (color >= 0) {
|
|
select = 3;
|
|
goto switchlabel_4;
|
|
}
|
|
|
|
switchlabel_4:
|
|
|
|
switch (select) {
|
|
|
|
// yellow -> red
|
|
case 1:
|
|
{
|
|
r = 255;
|
|
g = 255 - (color - (185 + 255));
|
|
b = 0;
|
|
break;
|
|
}
|
|
|
|
case 2: // green -> yellow
|
|
{
|
|
r = color - 185;
|
|
g = 255;
|
|
b = 0;
|
|
break;
|
|
}
|
|
|
|
case 3: // drk green -> green
|
|
{
|
|
r = 0;
|
|
g = 70 + color;
|
|
b = 0;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// Hannes - Colormap 5 - violett -> blue -> l blue
|
|
if (colormap == 5) {
|
|
color = (int) ((2 * 255) * tmp / (max - min));
|
|
|
|
if (color > (2 * 255)) {
|
|
select = 3;
|
|
goto switchlabel_5;
|
|
}
|
|
|
|
if (color < 0) {
|
|
select = 4;
|
|
goto switchlabel_5;
|
|
}
|
|
|
|
|
|
if (color >= (255)) {
|
|
select = 1;
|
|
goto switchlabel_5;
|
|
}
|
|
|
|
if (color >= 0) {
|
|
select = 2;
|
|
goto switchlabel_5;
|
|
}
|
|
|
|
switchlabel_5:
|
|
|
|
switch (select) {
|
|
|
|
// d blue -> l blue
|
|
case 1:
|
|
{
|
|
r = 0;
|
|
g = (color - 255);
|
|
b = 255;
|
|
break;
|
|
}
|
|
|
|
case 2: // violett -> d blue
|
|
{
|
|
r = 255 - color;
|
|
g = 0;
|
|
b = 255;
|
|
break;
|
|
}
|
|
|
|
case 3: // out (upper end)
|
|
{
|
|
r = 0;
|
|
g = 255;
|
|
b = 255;
|
|
break;
|
|
}
|
|
|
|
case 4: // out lower end (magenta)
|
|
{
|
|
r = 255;
|
|
g = 0;
|
|
b = 255;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
// Hannes - Colormap 6 - killer rainbow
|
|
if (colormap == 6) {
|
|
color = (int) ((8 * 255) * tmp / (max - min));
|
|
|
|
if (color > (8 * 255)) {
|
|
color = 8 * 255;
|
|
}
|
|
if (color < 0) {
|
|
color = 0;
|
|
}
|
|
|
|
|
|
if (color >= (7 * 255)) {
|
|
select = 1;
|
|
goto switchlabel_6;
|
|
}
|
|
|
|
if (color > (6 * 255)) {
|
|
select = 2;
|
|
goto switchlabel_6;
|
|
}
|
|
if (color > (5 * 255)) {
|
|
select = 3;
|
|
goto switchlabel_6;
|
|
}
|
|
if (color > (4 * 255)) {
|
|
select = 4;
|
|
goto switchlabel_6;
|
|
}
|
|
if (color > (3 * 255)) {
|
|
select = 5;
|
|
goto switchlabel_6;
|
|
}
|
|
if (color > (2 * 255)) {
|
|
select = 6;
|
|
goto switchlabel_6;
|
|
}
|
|
if (color > (1 * 255)) {
|
|
select = 7;
|
|
goto switchlabel_6;
|
|
}
|
|
if (color >= (0)) {
|
|
select = 8;
|
|
goto switchlabel_6;
|
|
}
|
|
|
|
|
|
|
|
switchlabel_6:
|
|
|
|
switch (select) {
|
|
|
|
// red -> white
|
|
case 1:
|
|
{
|
|
r = 255;
|
|
g = 255 - (8 * 255 - color);
|
|
b = 255 - (8 * 255 - color);
|
|
break;
|
|
}
|
|
|
|
case 2: // magenta -> red
|
|
{
|
|
r = 255;
|
|
g = 0;
|
|
b = 7 * 255 - color;
|
|
break;
|
|
}
|
|
|
|
case 3: // blue -> magenta
|
|
{
|
|
r = 255 - (6 * 255 - color);
|
|
g = 0;
|
|
b = 255;
|
|
break;
|
|
}
|
|
|
|
case 4: // trk -> blue
|
|
{
|
|
r = 0;
|
|
g = 5 * 255 - color;
|
|
b = 255;
|
|
break;
|
|
}
|
|
|
|
case 5: // green -> trk
|
|
{
|
|
r = 0;
|
|
g = 255;
|
|
b = 255 - (4 * 255 - color);
|
|
break;
|
|
}
|
|
|
|
|
|
case 6: // yellow -> green
|
|
{
|
|
r = 3 * 255 - color;
|
|
g = 255;
|
|
b = 0;
|
|
break;
|
|
}
|
|
|
|
case 7: // red -> yellow
|
|
{
|
|
r = 255;
|
|
g = 255 - (2 * 255 - color);
|
|
b = 0;
|
|
break;
|
|
}
|
|
|
|
case 8: // black -> red
|
|
{
|
|
r = color;
|
|
g = 0;
|
|
b = 0;
|
|
break;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (colormap == 7) { // boaring all-white
|
|
r = 255;
|
|
g = 255;
|
|
b = 255;
|
|
}
|
|
|
|
// Hannes - Colormap 8 - black-red-yellow-white
|
|
if (colormap == 8) {
|
|
color = (int) ((3 * 255) * tmp / (max - min));
|
|
|
|
if (color > (3 * 255)) {
|
|
color = 3 * 255;
|
|
}
|
|
if (color < 0) {
|
|
color = 0;
|
|
}
|
|
|
|
|
|
if (color >= (2 * 255)) {
|
|
select = 1;
|
|
goto switchlabel_8;
|
|
}
|
|
|
|
if (color > (1 * 255)) {
|
|
select = 2;
|
|
goto switchlabel_8;
|
|
}
|
|
if (color >= 0) {
|
|
select = 3;
|
|
goto switchlabel_8;
|
|
}
|
|
|
|
|
|
|
|
switchlabel_8:
|
|
|
|
switch (select) {
|
|
|
|
// yellow -> white
|
|
case 1:
|
|
{
|
|
r = 255;
|
|
g = 255; // - (4 * 255 - color);
|
|
b = 255 - (3 * 255 - color);
|
|
break;
|
|
}
|
|
|
|
case 2: // red -> yellow
|
|
{
|
|
r = 255;
|
|
g = 255 - (2*255 - color);
|
|
b = 0;
|
|
break;
|
|
}
|
|
|
|
case 3: // black -> red
|
|
{
|
|
r = color;
|
|
g = 0;
|
|
b = 0;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ende:
|
|
colorpointer[0] = (float) r / 255.0;
|
|
colorpointer[1] = (float) g / 255.0;
|
|
colorpointer[2] = (float) b / 255.0;
|
|
}
|
|
|
|
|
|
void HelpScreen(void) {
|
|
#ifndef ONLY_OSMESA
|
|
vector<string> helptext;
|
|
int font_height= glutGet(GLUT_WINDOW_HEIGHT) / 30;
|
|
|
|
// make shure that the text appears right and left in hw-stereo-mode
|
|
glDrawBuffer(GL_BACK);
|
|
|
|
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
|
|
// the spaces are empirical...
|
|
helptext.push_back("g,s Move forward,backward");
|
|
helptext.push_back("space,a Move fast forward,backward");
|
|
helptext.push_back("d,f Move left,right");
|
|
helptext.push_back("t,z Move up,down");
|
|
helptext.push_back("q,ESC Exit");
|
|
helptext.push_back("w Fullscreen mode on/off ");
|
|
helptext.push_back("p Screenshot");
|
|
helptext.push_back("m Mouse control on/off ");
|
|
helptext.push_back("o toggle 2D/3D viewing mode");
|
|
helptext.push_back("u,i increase,decrease Flightstrip/Terrain offset ");
|
|
helptext.push_back("+,- increase,decrease z-axis scaling");
|
|
helptext.push_back("F1-F4 Move Marker (fast back, back, forward, fast forward)");
|
|
helptext.push_back("F5 Reset viewpoint");
|
|
helptext.push_back("shift-F3,shift-F4 decrease,increase Flightstrip linewidth");
|
|
helptext.push_back("shift-F1,shift-F2 decrease,increase Flying-Mode Framerepeat");
|
|
helptext.push_back("shift-Q, shift-W decrease,increase eye-distance in stereo-modes");
|
|
|
|
// this should be clear ;-)
|
|
//helptext.push_back(" ");
|
|
//helptext.push_back("Right mouse button = Access menu ");
|
|
|
|
helptext.push_back(" ");
|
|
helptext.push_back("for a full list read the manual (GPLIGC_Manual.pdf)");
|
|
helptext.push_back(" ");
|
|
helptext.push_back("To leave this menu press the \"ANY\"-key");
|
|
|
|
glLineWidth(1.5);
|
|
|
|
/*gltextvect(5, glutGet(GLUT_WINDOW_HEIGHT) - (font_height),
|
|
font_height, helptext, glutGet(GLUT_WINDOW_WIDTH),
|
|
glutGet(GLUT_WINDOW_HEIGHT));*/
|
|
|
|
for (int z=0; z<=(int(helptext.size()-1)); z++) {
|
|
gltext(5, glutGet(GLUT_WINDOW_HEIGHT) - (font_height*(z+1)),
|
|
font_height, helptext[z].c_str(), glutGet(GLUT_WINDOW_WIDTH),
|
|
glutGet(GLUT_WINDOW_HEIGHT));
|
|
}
|
|
|
|
glLineWidth(1.0);
|
|
glutSwapBuffers();
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
void InfoScreen(void) {
|
|
#ifndef ONLY_OSMESA
|
|
vector<string> infotext;
|
|
|
|
string logofile;
|
|
vector <string> logofiles;
|
|
bool LOGO = false;
|
|
|
|
string homestring;
|
|
|
|
// assemble path to logo (only in default install, or GPLIGCHOME (win32))
|
|
|
|
#ifdef __WIN32__
|
|
char* home;
|
|
home = getenv("GPLIGCHOME");
|
|
//logofiles.push_back(home+"\\logo.jpg");
|
|
//string homestring;
|
|
|
|
if (home != NULL) {
|
|
homestring=home;
|
|
//logofiles.push_back(homestring + "logo.jpg");
|
|
logofiles.push_back(homestring + "\\logo.jpg");
|
|
}else{
|
|
homestring = "";
|
|
}
|
|
|
|
logofiles.push_back("C:\\GPLIGC\\logo.jpg");
|
|
logofiles.push_back("D:\\GPLIGC\\logo.jpg");
|
|
logofiles.push_back("C:\\Programme\\GPLIGC\\logo.jpg");
|
|
logofiles.push_back("C:\\Program files\\GPLIGC\\logo.jpg");
|
|
logofiles.push_back("D:\\Programme\\GPLIGC\\logo.jpg");
|
|
logofiles.push_back("D:\\Program files\\GPLIGC\\logo.jpg");
|
|
|
|
#else
|
|
logofiles.push_back("/usr/local/share/gpligc/logo.jpg");
|
|
logofiles.push_back("/usr/share/gpligc/logo.jpg");
|
|
logofiles.push_back("/sw/usr/local/share/gpligc/logo.jpg");
|
|
logofiles.push_back("/sw/local/share/gpligc/logo.jpg");
|
|
logofiles.push_back("/sw/share/gpligc/logo.jpg");
|
|
logofiles.push_back("/opt/share/gpligc/logo.jpg");
|
|
logofiles.push_back("/opt/GPLIGC/logo.jpg");
|
|
logofiles.push_back("/home/kruegerh/GPLIGC/GPLIGC/perl/logo.jpg");
|
|
|
|
#endif
|
|
|
|
ifstream inlogo;
|
|
|
|
for (unsigned i=0; i<logofiles.size();i++) {
|
|
inlogo.clear();
|
|
inlogo.open(logofiles[i].c_str());
|
|
//cout << "trying to open: " << logofiles[i] << endl;
|
|
if (!inlogo) {
|
|
inlogo.close();
|
|
//cfile.clear();
|
|
} else {
|
|
logofile = logofiles[i];
|
|
LOGO=true;
|
|
//if (DEBUG.get()) {
|
|
//cout << "logofile Opened!!!: " << logofile << endl;
|
|
//}
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// set font size
|
|
int font_height= glutGet(GLUT_WINDOW_HEIGHT) / 30;
|
|
|
|
// make shure that the text appears right and left in hw-stereo-mode
|
|
glDrawBuffer(GL_BACK);
|
|
|
|
// clear to white and buffers
|
|
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
// display logo if available
|
|
if (LOGO) {
|
|
Map logo;
|
|
|
|
// we dont know this here... and otherwise -> segfault
|
|
logo.set_conf_pointer(NULL);
|
|
logo.readMap_jpeg((char*) logofile.c_str(), -1,-1); // -1,-1 -> no rescaling is needed (not a texture!)
|
|
|
|
float logoratio = (float) logo.getHeight() / (float) logo.getWidth();
|
|
float windowratio = ((float) glutGet(GLUT_WINDOW_HEIGHT) / 2.0) / (float) glutGet(GLUT_WINDOW_WIDTH);
|
|
|
|
//cout << "logo read....fg" << endl << flush;
|
|
// logo is heigher than half window (maximal height is windowheight/2)
|
|
if (logoratio > windowratio) {
|
|
int targetheight = (int) (( (float) glutGet(GLUT_WINDOW_HEIGHT) / 2.0) +0.5) ;
|
|
int targetwidth = (int) (((float)targetheight / logoratio)+0.5);
|
|
//int xoffset = (int) (((float)glutGet(GLUT_WINDOW_WIDTH) - (float) targetwidth) / 2.0);
|
|
logo.map_to_colBuffer(0,0,targetwidth, targetheight);
|
|
|
|
// logo is wider than window (maximal width is windowwidth)
|
|
} else {
|
|
int targetwidth = glutGet(GLUT_WINDOW_WIDTH);
|
|
int targetheight = (int)(((float)targetwidth * logoratio)+0.5);
|
|
logo.map_to_colBuffer(0,0,targetwidth,targetheight);
|
|
}
|
|
}
|
|
|
|
// display text
|
|
string EX = "OGIE (openGLIGCexplorer) ";
|
|
EX += OGIE_VERSION;
|
|
EX += DEVELOPEMENT;
|
|
EX += " (build:";
|
|
EX += __DATE__;
|
|
EX += ")";
|
|
infotext.push_back(EX);
|
|
EX = COPYRIGHT;
|
|
EX += " by ";
|
|
EX += AUTHOR;
|
|
EX += " ";
|
|
EX += MAIL;
|
|
infotext.push_back(EX);
|
|
|
|
// infotext.push_back(WEB2);
|
|
infotext.push_back(WEB);
|
|
infotext.push_back(" ");
|
|
infotext.push_back("This program is free software: you can redistribute it and/or modify");
|
|
infotext.push_back("it under the terms of the GNU General Public License as published by");
|
|
infotext.push_back("the Free Software Foundation, either version 3 of the License, or");
|
|
infotext.push_back("(at your option) any later version.");
|
|
infotext.push_back(" ");
|
|
infotext.push_back(" ");
|
|
infotext.push_back("For details read the manual (GPLIGC_Manual.pdf)");
|
|
|
|
infotext.push_back("To leave this information press the \"ANY\"-key");
|
|
|
|
glLineWidth(1.5);
|
|
/*gltextvect(5, glutGet(GLUT_WINDOW_HEIGHT) - (font_height),
|
|
font_height, infotext, glutGet(GLUT_WINDOW_WIDTH),
|
|
glutGet(GLUT_WINDOW_HEIGHT));
|
|
*/
|
|
for (int z=0; z<=(int(infotext.size()-1)); z++) {
|
|
gltext(5, glutGet(GLUT_WINDOW_HEIGHT) - (font_height*(z+1)),
|
|
font_height, infotext[z].c_str(), glutGet(GLUT_WINDOW_WIDTH),
|
|
glutGet(GLUT_WINDOW_HEIGHT));
|
|
}
|
|
|
|
glLineWidth(1.0);
|
|
glutSwapBuffers();
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
// this is taken from
|
|
// "Avoiding 16 Common OpenGL Pitfalls" by Mark J. Kilgard of Nvidia
|
|
|
|
void
|
|
glWindowPos4fMESAemulate(GLfloat x,GLfloat y,GLfloat z,GLfloat w)
|
|
{
|
|
GLfloat fx, fy;
|
|
|
|
/* Push current matrix mode and viewport attributes. */
|
|
glPushAttrib(GL_TRANSFORM_BIT | GL_VIEWPORT_BIT);
|
|
|
|
/* Setup projection parameters. */
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPushMatrix();
|
|
glLoadIdentity();
|
|
glDepthRange(z, z);
|
|
glViewport((int) x - 1, (int) y - 1, 2, 2);
|
|
/* Set the raster (window) position. */
|
|
fx = x - (int) x;
|
|
fy = y - (int) y;
|
|
glRasterPos4f(fx, fy, 0.0, w);
|
|
/* Restore matrices, viewport and matrix mode. */
|
|
glPopMatrix();
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPopMatrix();
|
|
glPopAttrib();
|
|
}
|
|
|
|
void
|
|
glWindowPos2fMESAemulate(GLfloat x, GLfloat y)
|
|
{
|
|
glWindowPos4fMESAemulate(x, y, 0, 1);
|
|
}
|
|
|
|
|
|
string
|
|
dec2humantime (float t, int n) {
|
|
int hh = (int) t;
|
|
float rest = t - hh;
|
|
int mm = int(60 * rest);
|
|
rest= 60 * rest - mm;
|
|
int ss = int (60*rest);
|
|
|
|
rest=60 * rest -ss;
|
|
|
|
if (rest > 0.5) {ss++;}
|
|
|
|
if (ss == 60) {ss=0;mm++;}
|
|
|
|
char ret[8];
|
|
|
|
if (n==1)
|
|
sprintf(ret,"%02d",hh);
|
|
|
|
if (n==2)
|
|
sprintf(ret,"%02d:%02d",hh,mm);
|
|
|
|
if (n==3)
|
|
sprintf(ret,"%02d:%02d:%02d",hh,mm,ss);
|
|
|
|
if (n==4)
|
|
sprintf(ret,"%02d%02d%02d",hh,mm,ss);
|
|
|
|
return ((string)ret);
|
|
}
|
|
|
|
|
|
|
|
|
|
Timecheck::Timecheck() {}
|
|
|
|
Timecheck::Timecheck(string _name, Config* _c) {
|
|
|
|
name = _name;
|
|
gettimeofday(&start,NULL);
|
|
last = start;
|
|
conf = _c;
|
|
|
|
if (conf->DEBUG.get())
|
|
cout << "########## " << name << " ##### started............" <<endl<<flush;
|
|
|
|
}
|
|
|
|
|
|
void Timecheck::checknow(string _here) {
|
|
|
|
gettimeofday(&now,NULL);
|
|
float _time = (((float) now.tv_sec - (float) start.tv_sec)
|
|
+
|
|
(((float) now.tv_usec -
|
|
(float) start.tv_usec) / 1000000.0));
|
|
|
|
float _timelast = (((float) now.tv_sec - (float) last.tv_sec)
|
|
+
|
|
(((float) now.tv_usec -
|
|
(float) last.tv_usec) / 1000000.0));
|
|
last = now;
|
|
|
|
if (conf->DEBUG.get())
|
|
cout <<"########## " << name << " ====> " <<_here << " ====> " << _time << "(" << _timelast << ")" << "secs" <<endl<<flush;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|