+ added test triangle rendering

* on close mainloop is ended
This commit is contained in:
End 2016-09-13 21:03:36 +02:00
parent 91f32eff4e
commit 39af185188
20 changed files with 994 additions and 146 deletions

23
KKK/game/CMakeLists.txt Normal file
View file

@ -0,0 +1,23 @@
set(CMAKE_INCLUDE_CURRENT_DIRS ON)
set(CMAKE_AUTOMOC ON)
find_package(OpenGL REQUIRED)
find_package(epoxy REQUIRED)
find_package(X11 REQUIRED)
set(GAME_SRC
src/main.cpp
src/opengl.cpp
)
set(GAME_HEADERS
include/opengl.h
)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${OPENGL_INCLUDE_DIR})
add_executable(game ${GAME_SRC} ${GAME_HEADERS})
setup_target(game)
target_link_libraries(game X11 epoxy)

66
KKK/game/include/opengl.h Normal file
View file

@ -0,0 +1,66 @@
#pragma once
#include <stdexcept>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <epoxy/gl.h>
#include <epoxy/glx.h>
namespace endofthejedi {
class GLWindow {
private:
Display* m_display;
Window m_rootwnd;
GLint m_attributes[23] =
{
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 24,
GLX_STENCIL_SIZE, 8,
GLX_DOUBLEBUFFER, True,
None
};
XVisualInfo* m_visualinfo;
Colormap m_colormap;
XSetWindowAttributes m_swa;
Window m_window;
GLXContext m_glcontext;
XWindowAttributes m_gwa;
Atom m_atomWmDeleteWindow;
unsigned int m_width;
unsigned int m_height;
bool m_running = false;
protected:
virtual void handle(XEvent event);
virtual void init();
virtual void render(double time);
virtual void resize();
public:
GLWindow(unsigned int width, unsigned int height);
~GLWindow();
void loop();
void stop();
void swap();
unsigned int getheight() const {
return m_height;
}
unsigned int getwidth() const {
return m_width;
}
};
}

36
KKK/game/src/main.cpp Normal file
View file

@ -0,0 +1,36 @@
#include <include/opengl.h>
#include <iostream>
class MainWindow : public endofthejedi::GLWindow {
private:
protected:
void init() override {
glClearColor(0.5f, 0.6f, 0.7f, 1.0f);
resize();
glEnable(GL_DEPTH_TEST);
}
void render(double time) override {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, -1.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 0.0f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f);
glEnd();
}
void resize() override { glViewport(0, 0, getwidth(), getheight()); }
public:
MainWindow(unsigned int width, unsigned int height)
: endofthejedi::GLWindow(width, height) {}
};
int main(int argc, const char *argv[]) {
MainWindow window(500, 500);
window.loop();
window.stop();
}

122
KKK/game/src/opengl.cpp Normal file
View file

@ -0,0 +1,122 @@
#include <include/opengl.h>
#include <iostream>
#include <sys/time.h>
#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;
}
endofthejedi::GLWindow::GLWindow(unsigned int width, unsigned int height)
: m_width(width), m_height(height) {
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, 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);
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";
init();
XClearWindow(m_display, m_window);
XMapRaised(m_display, m_window);
}
endofthejedi::GLWindow::~GLWindow() {
glXMakeCurrent(m_display, None, NULL);
glXDestroyContext(m_display, m_glcontext);
XDestroyWindow(m_display, m_window);
XCloseDisplay(m_display);
}
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();
}
} else if (event.type == DestroyNotify) {
stop();
}
}
void endofthejedi::GLWindow::swap() { glXSwapBuffers(m_display, m_window); }
void endofthejedi::GLWindow::loop() {
m_running = true;
timespec prev;
clock_gettime(CLOCK_MONOTONIC_RAW, &prev);
timespec current;
clock_gettime(CLOCK_MONOTONIC_RAW, &current);
double delta = 0.0;
while (m_running) {
if (XPending(m_display) > 0) {
XEvent xev;
XNextEvent(m_display, &xev);
handle(xev);
}
render(delta);
swap();
clock_gettime(CLOCK_MONOTONIC_RAW, &current);
delta = diff(prev, current).tv_nsec;
prev = current;
}
}
void endofthejedi::GLWindow::stop() { m_running = false; }
void endofthejedi::GLWindow::init() {}
void endofthejedi::GLWindow::render(double time) { UNUSED(time) }
void endofthejedi::GLWindow::resize() {}