diff --git a/README.md b/README.md index 1b13b96..d418f56 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ Klassische Kepler Kriege -=== +======================== Game based on NewtonWars (https://github.com/Draradech/NewtonWars), rewritten in C++ with some more fancy OpenGL shitz. + +dependencies +------------ + +libepoxy-dev diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index 8d2e44f..627b003 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -10,7 +10,6 @@ set(GAME_SRC glclasses.cpp renderer.cpp game_window.cpp - triangle_window.cpp util.cpp game.cpp diff --git a/game/game.cpp b/game/game.cpp index 36ffc64..3733e47 100644 --- a/game/game.cpp +++ b/game/game.cpp @@ -6,8 +6,7 @@ #include -Game::Game() -{ +Game::Game() { // advance simulation with 100 Hz m_time_step = 1.0 / 100.0; m_time_for_next_step = 0.0; @@ -19,16 +18,15 @@ Game::Game() m_state->addPlayer(1); m_state->addPlayer(2); m_state->addPlayer(3); - //m_state->addPlayer(2); + // m_state->addPlayer(2); } -bool Game::cycle(float dt) -{ +bool Game::cycle(float dt) { static float acc = 0.0; acc += dt; float spawnInterval = 0.1; - while(acc > spawnInterval) { + while (acc > spawnInterval) { acc -= spawnInterval; float a = 2.0 * M_PI * util::randf_0_1(); @@ -38,27 +36,28 @@ bool Game::cycle(float dt) #if 1 if (dt >= 10.0) { - //std::cout<<"time to big: " << dt << std::endl; + // std::cout<<"time to big: " << dt << std::endl; dt = m_time_step; } - //std::cout<<"adding dt: " << dt << std::endl; + // std::cout<<"adding dt: " << dt << std::endl; m_time_for_next_step += dt; int steps = 0; - while(m_time_for_next_step >= m_time_step) { - //std::cout<<"time now: " << m_time_for_next_step << std::endl; + while (m_time_for_next_step >= m_time_step) { + // std::cout<<"time now: " << m_time_for_next_step << std::endl; m_time_for_next_step -= m_time_step; m_state->advance(m_time_step); steps++; } - //std::cout << m_time_for_next_step << " s remaining time, " << steps << " steps taken." << std::endl; + // std::cout << m_time_for_next_step << " s remaining time, " << steps << " + // steps taken." << std::endl; return true; #else - (void) dt; + (void)dt; m_state->advance(dt); diff --git a/game/game.hpp b/game/game.hpp index 9c9512a..c58b6cc 100644 --- a/game/game.hpp +++ b/game/game.hpp @@ -3,7 +3,7 @@ #include "state/state.hpp" class Game { -public: + public: Game(); // main method of the game. run this regulary @@ -13,7 +13,7 @@ public: // for rendering const game::State *state() const { return m_state; } -private: + private: game::State *m_state; float m_time_for_next_step; diff --git a/game/game_window.hpp b/game/game_window.hpp index b3072ce..4ee7ed5 100644 --- a/game/game_window.hpp +++ b/game/game_window.hpp @@ -12,8 +12,8 @@ #include "state/ship.hpp" class GameWindow : public endofthejedi::GLWindow { -private: -protected: + private: + protected: void init() override { glClearColor(0.5f, 0.6f, 0.7f, 1.0f); resize(); @@ -22,16 +22,16 @@ protected: } void render(double time) override { - //static bool once = false; - //if (!once) { + // static bool once = false; + // if (!once) { // once = true; // for (int i=0; i<1000; i++) { // m_game.cycle(time); // } //} - if (!m_game.cycle(static_cast(time/1000000000.0))) { - std::cout<<"stopping the game..." << std::endl; + if (!m_game.cycle(static_cast(time / 1000000000.0))) { + std::cout << "stopping the game..." << std::endl; stop(); } @@ -54,36 +54,35 @@ protected: void resize() override { glViewport(0, 0, getwidth(), getheight()); } - void drawShip(const glm::vec2 &pos) - { - //std::cout<<"draw ship @ " << pos.x << ", " << pos.y << std::endl; + void drawShip(const glm::vec2 &pos) { + // std::cout<<"draw ship @ " << pos.x << ", " << pos.y << std::endl; glm::vec3 color = glm::vec3(0.2, 1.0, 0.3); float radius = m_game.state()->shipRadius(); - m_renderer.drawCircle(pos.x, pos.y, radius, color.x, color.y, color.z, 12); + m_renderer.drawCircle(pos.x, pos.y, radius, color.x, color.y, color.z, + 12); } - void drawPlanet(const glm::vec2 &pos, float radius) - { + void drawPlanet(const glm::vec2 &pos, float radius) { glm::vec3 color = glm::vec3(0.7, 0.1, 0.2); - //std::cout<<"draw planet @ " << pos.x << ", " << pos.y << std::endl; - m_renderer.drawCircle(pos.x, pos.y, radius, color.x, color.y, color.z, 32); + // std::cout<<"draw planet @ " << pos.x << ", " << pos.y << std::endl; + m_renderer.drawCircle(pos.x, pos.y, radius, color.x, color.y, color.z, + 32); } - void drawMissile(const glm::vec2 &pos) - { + void drawMissile(const glm::vec2 &pos) { glm::vec3 color = glm::vec3(1.0, 1.0, 0.3); - m_renderer.drawCircle(pos.x, pos.y, 0.005, color.x, color.y, color.z, 5); + m_renderer.drawCircle(pos.x, pos.y, 0.005, color.x, color.y, color.z, + 5); } -public: + public: GameWindow(unsigned int width, unsigned int height) : endofthejedi::GLWindow(width, height) {} -private: - Game m_game; + private: + Game m_game; endofthejedi::Renderer m_renderer; }; - diff --git a/game/glclasses.cpp b/game/glclasses.cpp index 2d6e618..635dd7b 100644 --- a/game/glclasses.cpp +++ b/game/glclasses.cpp @@ -1,5 +1,8 @@ #include "glclasses.hpp" +#include +#include + endofthejedi::VAO::VAO() { glGenVertexArrays(1, &m_name); } endofthejedi::VAO::~VAO() { glDeleteVertexArrays(1, &m_name); } @@ -9,31 +12,44 @@ void endofthejedi::VAO::bind() { glBindVertexArray(m_name); } void endofthejedi::VAO::fill(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) { - glEnableVertexAttribArray(index); - glVertexAttribPointer(index, size, GL_FLOAT, normalized, stride, pointer); + glEnableVertexAttribArray(index); + glVertexAttribPointer(index, size, GL_FLOAT, normalized, stride, pointer); } -endofthejedi::Shader::Shader() { - m_program = glCreateProgram(); -} +endofthejedi::Shader::Shader() { m_program = glCreateProgram(); } endofthejedi::Shader::~Shader() {} -void endofthejedi::Shader::bind() { - glUseProgram(m_program); +bool endofthejedi::Shader::check() { + GLint len = 0; + GLint result = 0; + + glGetProgramiv(m_program, GL_LINK_STATUS, &result); + glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &len); + if (len > 1) { + char* error = (char*)malloc(len); + glGetProgramInfoLog(m_program, len, NULL, error); + std::string str(error); + std::cout << str << "\n"; + + } + + return (bool)result; } -void endofthejedi::Shader::unbind() { - glUseProgram(0); -} +bool endofthejedi::Shader::checkShader() { return false; } + +void endofthejedi::Shader::bind() { glUseProgram(m_program); } + +void endofthejedi::Shader::unbind() { glUseProgram(0); } void endofthejedi::Shader::load(std::string path, GLenum shadertype) { - GLuint cheddar = glCreateShader(shadertype); - const char* cheddardata = path.c_str(); - glShaderSource(cheddar, 1, &cheddardata, NULL); - glCompileShader(cheddar); - glAttachShader(m_program, cheddar); - glLinkProgram(m_program); - glDeleteShader(cheddar); + GLuint cheddar = glCreateShader(shadertype); + const char *cheddardata = path.c_str(); + glShaderSource(cheddar, 1, &cheddardata, NULL); + glCompileShader(cheddar); + glAttachShader(m_program, cheddar); + glLinkProgram(m_program); + glDeleteShader(cheddar); + check(); } - diff --git a/game/glclasses.hpp b/game/glclasses.hpp index 4f546ec..bf983b0 100644 --- a/game/glclasses.hpp +++ b/game/glclasses.hpp @@ -8,51 +8,55 @@ namespace endofthejedi { template class BufferObject { - private: - GLuint m_name; - GLvoid* m_mappointer; - protected: - public: - BufferObject(); - ~BufferObject(); - void bind(); - void bind(GLuint index, GLintptr offset = 0, GLsizeiptr size = 0); - void fill(GLenum usage, GLsizei size = 0, GLvoid* data = NULL); - void subfill(GLintptr offset, GLsizei size, const GLvoid* data); - void map(GLenum access); - void unmap(); + private: + GLuint m_name; + GLvoid *m_mappointer; + + protected: + public: + BufferObject(); + ~BufferObject(); + void bind(); + void bind(GLuint index, GLintptr offset = 0, GLsizeiptr size = 0); + void fill(GLenum usage, GLsizei size = 0, GLvoid *data = NULL); + void subfill(GLintptr offset, GLsizei size, const GLvoid *data); + void map(GLenum access); + void unmap(); }; typedef BufferObject VBO; typedef BufferObject IBO; class VAO { - private: - GLuint m_name; - protected: - public: - VAO(); - ~VAO(); - void bind(); - void fill(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride = 0, const GLvoid* pointer = NULL); + private: + GLuint m_name; + + protected: + public: + VAO(); + ~VAO(); + void bind(); + void fill(GLuint index, GLint size, GLenum type, GLboolean normalized, + GLsizei stride = 0, const GLvoid *pointer = NULL); }; - class Shader { - private: - GLuint m_program; - protected: - public: - Shader(); - ~Shader(); - void bind(); - void unbind(); - void load(std::string data, GLenum shadertype); - }; - +class Shader { + private: + GLuint m_program; + bool check(); + bool checkShader(); + protected: + public: + Shader(); + ~Shader(); + void bind(); + void unbind(); + void load(std::string data, GLenum shadertype); +}; } -#define TBufferObject_(pre, post) \ - template pre endofthejedi::BufferObject::post +#define TBufferObject_(pre, post) \ + template pre endofthejedi::BufferObject::post #define TBufferObject(...) TBufferObject_(__VA_ARGS__) TBufferObject(, BufferObject)() { glGenBuffers(1, &m_name); } @@ -62,22 +66,22 @@ TBufferObject(, ~BufferObject)() { glDeleteBuffers(1, &m_name); } TBufferObject(void, bind)() { glBindBuffer(T, m_name); } TBufferObject(void, bind)(GLuint index, GLintptr offset, GLsizeiptr size) { - // todo + // todo } TBufferObject(void, fill)(GLenum usage, GLsizei size, GLvoid *data) { - glBufferData(T, size, data, usage); + glBufferData(T, size, data, usage); } TBufferObject(void, subfill)(GLintptr offset, GLsizei size, const GLvoid *data) { - glBufferSubData(T, offset, size, data); + glBufferSubData(T, offset, size, data); } TBufferObject(void, map)(GLenum access) { - // todo + // todo } TBufferObject(void, unmap)() { - // todo + // todo } diff --git a/game/main.cpp b/game/main.cpp index 5714cc3..7f30ea2 100644 --- a/game/main.cpp +++ b/game/main.cpp @@ -1,12 +1,62 @@ #include "opengl.hpp" #include +#include #include "game_window.hpp" +#include "options.hpp" -int main(int argc, const char *argv[]) { - GameWindow window(500, 500); - window.set_maxfps(60.0); - window.loop(); - window.stop(); + +using namespace std; + +int main(int argc, char *argv[]) { + + char c; + + static struct option long_options[] = + { + /* These options set a flag. */ +// {"verbose", no_argument, &verbose_flag, 1}, +// {"brief", no_argument, &verbose_flag, 0}, + /* These options don’t set a flag. + We distinguish them by their indices. */ +// {"add", no_argument, 0, 'a'}, +// {"append", no_argument, 0, 'b'}, +// {"delete", required_argument, 0, 'd'}, +// {"create", required_argument, 0, 'c'}, + {"fps", no_argument, 0, 'f'}, + {0, 0, 0, 0} + }; + + int option_index = 0; + + while(1){ + c = getopt_long (argc, argv, "abc:d:f", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 'f': + SET_FLAG(SHOW_FPS,true); + break; + /*case 'c': + cvalue = optarg; + break; + */ + + case '?': + /* getopt_long already printed an error message. */ + break; + + default: + abort(); + } + } + + GameWindow window(500, 500); + window.set_maxfps(60.0); + window.loop(); + window.stop(); } diff --git a/game/main.fs b/game/main.fs new file mode 100644 index 0000000..9f7e2df --- /dev/null +++ b/game/main.fs @@ -0,0 +1,234 @@ +R"raw_string( +#version 120 + +struct intersection +{ + bool intersected; + vec3 point; + vec3 normal; + vec3 color; + float reflection; + int idx; + //todo different types +}; + +varying vec2 outvertex; + +//settings +uniform float aspectratio; +uniform float time; +uniform int supersamples; +uniform int reflections; +uniform bool shadows; +uniform vec3 backgroundcolor; + +//light +uniform vec3 l_position; +uniform float l_radius; + +//spheres +//todo ubo? +uniform int s_length; +uniform vec3 s_positions[100]; +uniform float s_radii[100]; +uniform vec4 s_colors[100]; +uniform float s_reflections[100]; + +const float PI = 3.14159265359; + +//din = german industrial normal +float light_diffuse(vec3 pos, vec3 din) +{ + vec3 l_dir = normalize(l_position - pos); + return max(dot(l_dir, din), 0.0f); +} + +//adapted from https://wiki.delphigl.com/index.php/shader_ConeVolumeShadow +float light_shadow(vec3 pos) +{ + float s = 1.0f; + + for(int l = 0; l < s_length; l++) + { + vec3 s_pos = s_positions[l]; + float s_rad = s_radii[l]; + + // project fragment (pos) on the cone axis => F_ + vec3 nvLO = s_pos - l_position; + float dLO = length(nvLO); + nvLO /= dLO; + vec3 vLF = pos - l_position; + float dLF_ = dot(vLF, nvLO); + if (dLF_ < dLO) { + // fragment before occluder => no shadow + continue; + } + vec3 F_ = l_position + dLF_ * nvLO; + float rF = distance(F_, pos); + + // compute outer and inner radius at F_ + float rF_outer = (s_rad + l_radius) * (dLF_ / dLO) - l_radius; + if (rF >= rF_outer) { + // outside the outer cone => no shadow + continue; + } + float rF_inner = (s_rad - l_radius) * (dLF_ / dLO) + l_radius; + if (rF_inner >= rF) { + // inside the inner cone => full shadow + return 0.0; + } + else if (rF_inner >= 0.0 || rF >= -rF_inner) { + // soft shadow, linear interpolation + s *= (rF - rF_inner) / (rF_outer - rF_inner); + } + else { + // light from both sides of the occluder + s *= (-2.0*rF_inner) / (rF_outer - rF_inner); + } + + } + + return s; +} + +intersection intersect_sphere(vec3 r_pos, vec3 r_dir, vec3 s_pos, float s_rad, inout float minimum) +{ + intersection result = intersection(false,vec3(0.0f, 0.0f, 0.0f), + vec3(0.0f, 0.0f, 0.0f), + vec3(0.0f, 0.0f, 0.0f), 0.0f, -1); + + vec3 v = r_pos - s_pos; + float a = dot(r_pos, r_pos); + float b = dot(v, r_dir); + float c = dot(v, v) - (s_rad * s_rad); + float d = b * b - c; + + if(d >= 0) + { + float w1 = -b - sqrt(d); + float w2 = -b + sqrt(d); + + if(w1 > 0.0f || w2 > 0.0f) + { + float w = min(w1, w2); + float o = max(w1, w2); + + if(w1 <= 0.0f) + w = w2; + else + if(w2 <= 0.0f) + w = w1; + + if(w < minimum) + { + minimum = w; + } + else + { + return intersection(false,vec3(0.0f, 0.0f, 0.0f), + vec3(0.0f, 0.0f, 0.0f), + vec3(0.0f, 0.0f, 0.0f), 0.0f, -1); + } + + vec3 p = r_pos + (w * r_dir); + result.intersected = true; + result.point = p; + result.normal = normalize((p - s_pos) / s_rad); + return result; + } + } + + return result; +} + +intersection intersect(vec3 r_pos, vec3 r_dir, int idx) +{ + intersection result = intersection(false,vec3(0.0f, 0.0f, 0.0f), + vec3(0.0f, 0.0f, 0.0f), + vec3(0.0f, 0.0f, 0.0f), 0.0f, -1); + float minimum = 1000.0f; + + for(int l = 0; l < s_length; l++) + { + if(idx == l) + continue; + + float maximum; + + intersection r = intersect_sphere(r_pos, r_dir, s_positions[l], s_radii[l], minimum); + if(r.intersected) + { + r.color = s_colors[l].rgb; + r.idx = l; + r.reflection = s_reflections[l]; + + result = r; + } + //todo other geometric objects + //todo handle min with other geometric objects + } + + return result; +} + +vec3 cast_ray(vec3 r_pos, vec3 r_pixel) +{ + vec3 r_dir = normalize(r_pixel - r_pos); + + vec3 color = backgroundcolor; + + intersection i = intersection(false,vec3(0.0f, 0.0f, 0.0f), + vec3(0.0f, 0.0f, 0.0f), + vec3(0.0f, 0.0f, 0.0f), 0.0f, -1); + + vec3 p = r_pos; + vec3 d = r_dir; + int idx = -1; + + for(int bounce = 0; bounce < reflections; bounce++) + { + intersection i = intersect(p,d, idx); + + if(i.intersected) + { + float l_factor = light_diffuse(i.point, i.normal); + + if(shadows && l_factor > 0.004f) + { + l_factor *= light_shadow(i.point); + } + + if(bounce == 0) + { + color = i.color * l_factor; + } + else + { + color = mix(color, color * i.color * l_factor, i.reflection); + } + + //d = 2*(dot(p, i.normal))*i.normal - p; + d = reflect(-p, i.normal); + p = i.point; + idx = i.idx; + } + else + break; + } + + return color; +} + +void main() +{ + vec2 rp = outvertex; + rp.x = rp.x * aspectratio; + vec4 outcolor = vec4(cast_ray(vec3(0.0f, 0.0f, 1.0f), vec3(rp, 0.0f)), 0.0f); + for(int supersample = 1; supersample < supersamples; supersample++) + { + outcolor = mix(outcolor, vec4(cast_ray(vec3(sin(supersample * PI/supersamples)/200, cos(supersample * PI/supersamples)/200, 1.0f), vec3(rp, 0.0f)), 0.0f), 0.5f); + } + gl_FragColor = outcolor; +} + +)raw_string" diff --git a/game/main.vs b/game/main.vs new file mode 100644 index 0000000..1dd8fbe --- /dev/null +++ b/game/main.vs @@ -0,0 +1,13 @@ +R"raw_string( +#version 120 + +attribute vec2 invertex; +varying vec2 outvertex; + +void main() { + gl_Position.xy = invertex; + gl_Position.zw = vec2(0.0f, 1.0); + outvertex = invertex; +} + +)raw_string" \ No newline at end of file diff --git a/game/opengl.cpp b/game/opengl.cpp index 7eecce7..17035da 100644 --- a/game/opengl.cpp +++ b/game/opengl.cpp @@ -3,136 +3,139 @@ #include #include #include +#include "options.hpp" -#define UNUSED(foo) (void)foo; +#define UNUSED(foo) (void) foo; timespec diff(timespec start, timespec end) { - timespec result; - if ((end.tv_nsec - start.tv_nsec) < 0) { - result.tv_sec = end.tv_sec - start.tv_sec - 1; - result.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec; - } else { - result.tv_sec = end.tv_sec - start.tv_sec; - result.tv_nsec = end.tv_nsec - start.tv_nsec; - } - return result; + timespec result; + if ((end.tv_nsec - start.tv_nsec) < 0) { + result.tv_sec = end.tv_sec - start.tv_sec - 1; + result.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec; + } else { + result.tv_sec = end.tv_sec - start.tv_sec; + result.tv_nsec = end.tv_nsec - start.tv_nsec; + } + return result; } endofthejedi::GLWindow::GLWindow(unsigned int width, unsigned int height) : m_width(width), m_height(height) { - m_display = XOpenDisplay(NULL); + m_display = XOpenDisplay(NULL); - if (m_display == NULL) { - throw std::runtime_error("XOpenDisplay NULL"); - } + if (m_display == NULL) { + throw std::runtime_error("XOpenDisplay NULL"); + } - m_rootwnd = DefaultRootWindow(m_display); + m_rootwnd = DefaultRootWindow(m_display); - m_visualinfo = glXChooseVisual(m_display, 0, m_attributes); + m_visualinfo = glXChooseVisual(m_display, 0, m_attributes); - if (m_visualinfo == NULL) { - throw std::runtime_error("glXChooseVisual NULL"); - } + if (m_visualinfo == NULL) { + throw std::runtime_error("glXChooseVisual NULL"); + } - m_colormap = - XCreateColormap(m_display, m_rootwnd, m_visualinfo->visual, AllocNone); + m_colormap = + XCreateColormap(m_display, m_rootwnd, m_visualinfo->visual, AllocNone); - m_swa.colormap = m_colormap; - m_swa.event_mask = ExposureMask | KeyPressMask; + m_swa.colormap = m_colormap; + m_swa.event_mask = ExposureMask | KeyPressMask; - m_window = XCreateWindow( - m_display, m_rootwnd, 0, 0, width, height, 0, m_visualinfo->depth, - InputOutput, m_visualinfo->visual, CWColormap | CWEventMask, &m_swa); + m_window = XCreateWindow( + m_display, m_rootwnd, 0, 0, width, height, 0, m_visualinfo->depth, + InputOutput, m_visualinfo->visual, CWColormap | CWEventMask, &m_swa); - m_atomWmDeleteWindow = XInternAtom(m_display, "WM_DELETE_WINDOW", False); - XSetWMProtocols(m_display, m_window, &m_atomWmDeleteWindow, 1); + m_atomWmDeleteWindow = XInternAtom(m_display, "WM_DELETE_WINDOW", False); + XSetWMProtocols(m_display, m_window, &m_atomWmDeleteWindow, 1); - XMapWindow(m_display, m_window); - XStoreName(m_display, m_window, "NAME"); + XMapWindow(m_display, m_window); + XStoreName(m_display, m_window, "NAME"); - m_glcontext = glXCreateContext(m_display, m_visualinfo, NULL, GL_TRUE); + m_glcontext = glXCreateContext(m_display, m_visualinfo, NULL, GL_TRUE); - XSync(m_display, False); + XSync(m_display, False); - glXMakeCurrent(m_display, m_window, m_glcontext); + glXMakeCurrent(m_display, m_window, m_glcontext); - std::cout << "GL Renderer: " << glGetString(GL_RENDERER) << "\n"; - std::cout << "GL Version: " << glGetString(GL_VERSION) << "\n"; - std::cout << "GLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) - << "\n"; + std::cout << "GL Renderer: " << glGetString(GL_RENDERER) << "\n"; + std::cout << "GL Version: " << glGetString(GL_VERSION) << "\n"; + std::cout << "GLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) + << "\n"; - init(); + init(); - XClearWindow(m_display, m_window); - XMapRaised(m_display, m_window); + XClearWindow(m_display, m_window); + XMapRaised(m_display, m_window); } endofthejedi::GLWindow::~GLWindow() { - glXMakeCurrent(m_display, None, NULL); - glXDestroyContext(m_display, m_glcontext); - XFree(m_visualinfo); - XDestroyWindow(m_display, m_window); - XCloseDisplay(m_display); + glXMakeCurrent(m_display, None, NULL); + glXDestroyContext(m_display, m_glcontext); + XFree(m_visualinfo); + XDestroyWindow(m_display, m_window); + XCloseDisplay(m_display); } void endofthejedi::GLWindow::handleevents() { - if (XPending(m_display) > 0) { - XEvent xev; - XNextEvent(m_display, &xev); - handle(xev); - } + if (XPending(m_display) > 0) { + XEvent xev; + XNextEvent(m_display, &xev); + handle(xev); + } } void endofthejedi::GLWindow::handle(XEvent event) { - if (event.type == Expose) { - XWindowAttributes attribs; - XGetWindowAttributes(m_display, m_window, &attribs); - m_width = attribs.width; - m_height = attribs.height; - resize(); - } else if (event.type == ClientMessage) { - if (event.xclient.data.l[0] == m_atomWmDeleteWindow) { - stop(); + if (event.type == Expose) { + XWindowAttributes attribs; + XGetWindowAttributes(m_display, m_window, &attribs); + m_width = attribs.width; + m_height = attribs.height; + resize(); + } else if (event.type == ClientMessage) { + if (event.xclient.data.l[0] == m_atomWmDeleteWindow) { + stop(); + } + } else if (event.type == DestroyNotify) { + stop(); } - } else if (event.type == DestroyNotify) { - stop(); - } } void endofthejedi::GLWindow::swap() { glXSwapBuffers(m_display, m_window); } void endofthejedi::GLWindow::loop() { - m_running = true; - - timespec prev; - timespec current; - clock_gettime(CLOCK_MONOTONIC_RAW, &prev); - clock_gettime(CLOCK_MONOTONIC_RAW, ¤t); - - double delta = 0.0; - double sleeptime = 0.0; - - while (m_running) { - handleevents(); - render(delta); - swap(); - - if (m_maxfps > 0) { - sleeptime = ((1000000000.0/m_maxfps) - delta) + sleeptime; - if (sleeptime > 0.0) { - usleep((unsigned int)(sleeptime/1000.0)); - sleeptime = sleeptime - (unsigned int)(sleeptime/1000.0); - } - } + m_running = true; + timespec prev; + timespec current; + clock_gettime(CLOCK_MONOTONIC_RAW, &prev); clock_gettime(CLOCK_MONOTONIC_RAW, ¤t); - delta = diff(prev, current).tv_nsec; - prev = current; - if(delta > 0.0) { - m_fps = (1000000000.0/delta); - std::cout << m_fps << "\n"; + + double delta = 0.0; + double sleeptime = 0.0; + + while (m_running) { + handleevents(); + render(delta); + swap(); + + if (m_maxfps > 0) { + sleeptime = ((1000000000.0 / m_maxfps) - delta) + sleeptime; + if (sleeptime > 0.0) { + usleep((unsigned int)(sleeptime / 1000.0)); + sleeptime = sleeptime - (unsigned int)(sleeptime / 1000.0); + } + } + + clock_gettime(CLOCK_MONOTONIC_RAW, ¤t); + delta = diff(prev, current).tv_nsec; + prev = current; + if (delta > 0.0) { + m_fps = (1000000000.0 / delta); + if (ISSET_FLAG(SHOW_FPS)) { + std::cout << m_fps << "\n"; + } + } } - } } void endofthejedi::GLWindow::stop() { m_running = false; } diff --git a/game/options.hpp b/game/options.hpp new file mode 100644 index 0000000..5cd04a6 --- /dev/null +++ b/game/options.hpp @@ -0,0 +1,22 @@ +#pragma once + +#define TEST_FLAG1 0 +#define SHOW_FPS 1 +#define TEST_FLAG2 2 +//... + + + + +#define SET_FLAG(x,y) optionsFlags&=(~((1)<