KlassischeKeplerKriege/game/opengl.cpp

146 lines
4.1 KiB
C++
Raw Normal View History

2016-09-27 17:01:21 +00:00
#include "opengl.hpp"
#include <iostream>
#include <sys/time.h>
#include <unistd.h>
2016-09-27 18:56:17 +00:00
#include "options.hpp"
2016-09-27 18:56:17 +00:00
#define UNUSED(foo) (void) foo;
timespec diff(timespec start, timespec end) {
2016-09-27 18:56:17 +00:00
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;
}
namespace endofthejedi {
GLWindow::GLWindow(unsigned int width, unsigned int height) : m_width(width), m_height(height)
{
2016-09-27 18:56:17 +00:00
}
void GLWindow::open()
{
m_display = XOpenDisplay(NULL);
if (m_display == NULL) {
throw std::runtime_error("XOpenDisplay NULL");
}
m_rootwnd = DefaultRootWindow(m_display);
m_visualinfo = glXChooseVisual(m_display, 0, m_attributes);
if (m_visualinfo == NULL) {
throw std::runtime_error("glXChooseVisual NULL");
}
m_colormap =
XCreateColormap(m_display, m_rootwnd, m_visualinfo->visual, AllocNone);
m_swa.colormap = m_colormap;
m_swa.event_mask = ExposureMask | KeyPressMask;
m_window = XCreateWindow(
m_display, m_rootwnd, 0, 0, m_width, m_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);
XMapWindow(m_display, m_window);
XStoreName(m_display, m_window, "NAME");
m_glcontext = glXCreateContext(m_display, m_visualinfo, NULL, GL_TRUE);
XSync(m_display, False);
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";
m_running = true;
init();
XClearWindow(m_display, m_window);
XMapRaised(m_display, m_window);
}
GLWindow::~GLWindow() {
glXMakeCurrent(m_display, None, NULL);
glXDestroyContext(m_display, m_glcontext);
XFree(m_visualinfo);
XDestroyWindow(m_display, m_window);
XCloseDisplay(m_display);
2016-09-27 18:56:17 +00:00
}
void GLWindow::handleevents() {
if (XPending(m_display) > 0) {
XEvent xev;
XNextEvent(m_display, &xev);
handle(xev);
}
}
void 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) {
2016-10-03 16:45:24 +00:00
if (event.xclient.data.l[0] == (int) m_atomWmDeleteWindow) {
stop();
}
} else if (event.type == DestroyNotify) {
2016-09-27 18:56:17 +00:00
stop();
}
}
void GLWindow::swap() { glXSwapBuffers(m_display, m_window); }
void GLWindow::poll() {
clock_gettime(CLOCK_MONOTONIC_RAW, &prev);
clock_gettime(CLOCK_MONOTONIC_RAW, &current);
2016-09-27 18:56:17 +00:00
handleevents();
render(delta);
swap();
2016-09-27 18:56:17 +00:00
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);
}
}
2016-09-28 05:57:10 +00:00
clock_gettime(CLOCK_MONOTONIC_RAW, &current);
delta = diff(prev, current).tv_nsec;
prev = current;
if(delta > 0.0) {
m_fps = (1000000000.0/delta);
//std::cout << m_fps << "\n";
}
2016-09-28 05:57:10 +00:00
}
void GLWindow::stop() { m_running = false; }
bool GLWindow::running() { return m_running; }
void GLWindow::init() { }
void GLWindow::render(double time) { UNUSED(time) }
void GLWindow::resize() {}
}