|
|
|
#include <iostream>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <chrono>
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
#include <GL/glew.h>
|
|
|
|
#include <GL/freeglut.h>
|
|
|
|
|
|
|
|
#include "App.h"
|
|
|
|
#include "globals.h"
|
|
|
|
|
|
|
|
|
|
|
|
App* app_ptr = 0;
|
|
|
|
unsigned int const frames_per_second = 200.0;
|
|
|
|
|
|
|
|
|
|
|
|
typedef std::chrono::high_resolution_clock clock_type;
|
|
|
|
|
|
|
|
size_t frame_count = 0;
|
|
|
|
clock_type::time_point begin_time;
|
|
|
|
|
|
|
|
void begin() {
|
|
|
|
app_ptr = new App(kWindowWidth, kWindowHeight);
|
|
|
|
begin_time = clock_type::now();
|
|
|
|
}
|
|
|
|
|
|
|
|
void end() {
|
|
|
|
auto end = clock_type::now();
|
|
|
|
auto difference = end-begin_time;
|
|
|
|
auto time_elapsed = difference.count()*clock_type::duration::period::num/(double)clock_type::duration::period::den;
|
|
|
|
std::cout << "Did " << frame_count << " frames in " << time_elapsed << " seconds." << std::endl;
|
|
|
|
std::cout << "That's " << frame_count/time_elapsed << " frames per second." << std::endl;
|
|
|
|
delete app_ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
int mouse_button_mapping(int button){
|
|
|
|
switch(button){
|
|
|
|
case GLUT_LEFT_BUTTON: return 0;
|
|
|
|
case GLUT_MIDDLE_BUTTON: return 1;
|
|
|
|
case GLUT_RIGHT_BUTTON: return 2;
|
|
|
|
default: return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char** argv) {
|
|
|
|
// let glut create a window
|
|
|
|
glutInit(&argc, argv);
|
|
|
|
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_ALPHA);
|
|
|
|
glutInitWindowSize(kWindowWidth, kWindowHeight);
|
|
|
|
glutCreateWindow("OpenGL");
|
|
|
|
|
|
|
|
// we need glew for shaders
|
|
|
|
auto err = glewInit();
|
|
|
|
if(err != GLEW_OK) {
|
|
|
|
throw std::runtime_error("A glew error");
|
|
|
|
}
|
|
|
|
|
|
|
|
// all callbacks (c++0x lambdas woei)
|
|
|
|
glutDisplayFunc([] {
|
|
|
|
auto const time_step = std::chrono::milliseconds(1000/frames_per_second);
|
|
|
|
|
|
|
|
static auto previous_timepoint = clock_type::now();
|
|
|
|
auto const current_timepoint = clock_type::now();
|
|
|
|
auto const difference = current_timepoint - previous_timepoint;
|
|
|
|
|
|
|
|
if(difference > time_step) {
|
|
|
|
app_ptr->update();
|
|
|
|
app_ptr->draw();
|
|
|
|
glutSwapBuffers();
|
|
|
|
//glFlush();
|
|
|
|
|
|
|
|
++frame_count;
|
|
|
|
|
|
|
|
previous_timepoint = current_timepoint-(difference%time_step);
|
|
|
|
} else {
|
|
|
|
usleep((time_step-difference).count()*1000000*clock_type::duration::period::num/(double)clock_type::duration::period::den/2);
|
|
|
|
//std::sleep_for((time_step-difference)/2);
|
|
|
|
}
|
|
|
|
|
|
|
|
glutPostRedisplay();
|
|
|
|
});
|
|
|
|
glutReshapeFunc([](int w, int h) {app_ptr->resize(w, h);});
|
|
|
|
glutMouseFunc([](int button, int state, int x, int y) {
|
|
|
|
switch(state) {
|
|
|
|
case GLUT_DOWN: app_ptr->mouse_buttons[mouse_button_mapping(button)] = true; break;
|
|
|
|
case GLUT_UP: app_ptr->mouse_buttons[mouse_button_mapping(button)] = false; break;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
glutPassiveMotionFunc([](int x, int y) {
|
|
|
|
app_ptr->mouse[0] = x;
|
|
|
|
app_ptr->mouse[1] = y;
|
|
|
|
});
|
|
|
|
glutMotionFunc([](int x, int y) {
|
|
|
|
app_ptr->mouse[0] = x;
|
|
|
|
app_ptr->mouse[1] = y;
|
|
|
|
});
|
|
|
|
glutCloseFunc(end); // freeglut extension
|
|
|
|
|
|
|
|
// my app-object
|
|
|
|
begin();
|
|
|
|
|
|
|
|
// GO!
|
|
|
|
glutMainLoop();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|