diff --git a/Makefile b/Makefile
index d9323ba..43aae9f 100644
--- a/Makefile
+++ b/Makefile
@@ -14,9 +14,9 @@
# along with this program. If not, see .
SOURCES = \
-cpp/opengl/render_context_glx.cpp \
-cpp/opengl/render_opengles.cpp \
+cpp/display/display_glx.cpp \
cpp/events/events_x11.cpp \
+cpp/render/render_opengles.cpp \
cpp/math.cpp
OUTPUTFILE = engine.so
diff --git a/__init__.py b/__init__.py
index eac4b35..bf9bf10 100644
--- a/__init__.py
+++ b/__init__.py
@@ -19,6 +19,31 @@ from pathlib import Path
_engine = ctypes.cdll.LoadLibrary(Path(__file__).parent / "engine.so")
+# types.hpp
+
+def _flag(x):
+ return 1 << x
+
+def buffer(type, size):
+ return (type * size)()
+
+def _voidp(x):
+ return x.buffer_info()[0]
+
+def _ubytep(x):
+ assert x.typecode == 'B'
+ return x.buffer_info()[0]
+
+def _ushortp(x):
+ assert x.typecode == 'H'
+ return x.buffer_info()[0]
+
+def _floatp(x):
+ assert x.typecode == 'f'
+ return x.buffer_info()[0]
+
+# math.hpp
+
class vec3(ctypes.Structure):
_fields_ = ('x', ctypes.c_float), ('y', ctypes.c_float), ('z', ctypes.c_float)
@@ -42,71 +67,14 @@ class mat3(ctypes.Structure):
class mat4(ctypes.Structure):
_fields_ = ('x', vec4), ('y', vec4), ('z', vec4), ('w', vec4)
-vec3_right = vec3(1.0, 0.0, 0.0)
-vec3_forward = vec3(0.0, 1.0, 0.0)
-vec3_up = vec3(0.0, 0.0, 1.0)
-
-def _flag(x):
- return 1 << x
-
-TEXTURE_FORMAT_SRGB8_A8 = 0
-TEXTURE_FORMAT_RGBA8 = 1
-TEXTURE_FORMAT_RGB10_A2 = 2
-TEXTURE_FORMAT_32F = 3
-
-TEXTURE_FORMAT_TYPECODE = ('B', 'B', 'I', 'f')
-TEXTURE_FORMAT_NELEMS = (4, 4, 1, 1)
-
-TEXTURE_FLAG_3D = _flag(0)
-TEXTURE_FLAG_MIPMAPS = _flag(1)
-TEXTURE_FLAG_MIN_NEAREST = 0
-TEXTURE_FLAG_MIN_LINEAR = _flag(2)
-TEXTURE_FLAG_MAG_NEAREST = 0
-TEXTURE_FLAG_MAG_LINEAR = _flag(3)
-
-VERTEX_FORMAT_VEC3_FLOAT = 1
-VERTEX_FORMAT_VEC3_INT10 = 2
-VERTEX_FORMAT_VEC3_UINT10 = 3
-VERTEX_FORMAT_NORMALIZE = _flag(7)
-
-def vertex_format(*format):
- return array('B', format).tobytes()
-
-PARAM_FORMAT_VEC3_FLOAT = 1
-PARAM_FORMAT_VEC3_SHORT = 2
-PARAM_FORMAT_VEC3_INT10 = 3
-PARAM_FORMAT_NORMALIZE = _flag(7)
-
-def params_format(*format):
- return array('B', format).tobytes()
-
-INSTANCE_FLAG_SPAWNED = _flag(0)
-INSTANCE_FLAG_VISIBLE = _flag(1)
-
-BATCH_MAX_SIZE = 65536
-
-def buffer(type, size):
- return (type * size)()
-
_vec3p = ctypes.POINTER(vec3)
_vec4p = ctypes.POINTER(vec4)
_mat3p = ctypes.POINTER(mat3)
_mat4p = ctypes.POINTER(mat4)
-def _voidp(x):
- return x.buffer_info()[0]
-
-def _ubytep(x):
- assert x.typecode == 'B'
- return x.buffer_info()[0]
-
-def _ushortp(x):
- assert x.typecode == 'H'
- return x.buffer_info()[0]
-
-def _floatp(x):
- assert x.typecode == 'f'
- return x.buffer_info()[0]
+vec3_right = vec3(1.0, 0.0, 0.0)
+vec3_forward = vec3(0.0, 1.0, 0.0)
+vec3_up = vec3(0.0, 0.0, 1.0)
vec3_rotate = _engine.rk_vec3_rotate
vec3_rotate.argtypes = (
@@ -173,13 +141,64 @@ mat4_mul_mat4.argtypes = (
_mat4p, # a
_mat4p) # b
-initialize = _engine.rk_initialize
-initialize.restype = ctypes.c_void_p
-initialize.argtypes = (
+# display.hpp
+
+create_display = _engine.rk_create_display
+create_display.restype = ctypes.c_void_p
+create_display.argtypes = (
ctypes.c_char_p, # name
ctypes.c_uint, # width
ctypes.c_uint) # height
+destroy_display = _engine.rk_destroy_display
+destroy_display.argtypes = (
+ ctypes.c_void_p,) # display
+
+swap_buffers = _engine.rk_swap_buffers
+swap_buffers.argtypes = (
+ ctypes.c_void_p,) # display
+
+# render.hpp
+
+TEXTURE_FORMAT_SRGB8_A8 = 0
+TEXTURE_FORMAT_RGBA8 = 1
+TEXTURE_FORMAT_RGB10_A2 = 2
+TEXTURE_FORMAT_32F = 3
+
+TEXTURE_FORMAT_TYPECODE = ('B', 'B', 'I', 'f')
+TEXTURE_FORMAT_NELEMS = (4, 4, 1, 1)
+
+TEXTURE_FLAG_3D = _flag(0)
+TEXTURE_FLAG_MIPMAPS = _flag(1)
+TEXTURE_FLAG_MIN_NEAREST = 0
+TEXTURE_FLAG_MIN_LINEAR = _flag(2)
+TEXTURE_FLAG_MAG_NEAREST = 0
+TEXTURE_FLAG_MAG_LINEAR = _flag(3)
+
+VERTEX_FORMAT_VEC3_FLOAT = 1
+VERTEX_FORMAT_VEC3_INT10 = 2
+VERTEX_FORMAT_VEC3_UINT10 = 3
+VERTEX_FORMAT_NORMALIZE = _flag(7)
+
+def vertex_format(*format):
+ return array('B', format).tobytes()
+
+PARAM_FORMAT_VEC3_FLOAT = 1
+PARAM_FORMAT_VEC3_SHORT = 2
+PARAM_FORMAT_VEC3_INT10 = 3
+PARAM_FORMAT_NORMALIZE = _flag(7)
+
+def params_format(*format):
+ return array('B', format).tobytes()
+
+INSTANCE_FLAG_SPAWNED = _flag(0)
+INSTANCE_FLAG_VISIBLE = _flag(1)
+
+BATCH_MAX_SIZE = 65536
+
+render_initialize = _engine.rk_render_initialize
+render_terminate = _engine.rk_render_terminate
+
_load_shader = _engine.rk_load_shader
_load_shader.restype = ctypes.c_void_p
_load_shader.argtypes = (
@@ -343,7 +362,7 @@ destroy_shader = _engine.rk_destroy_shader
destroy_shader.argtypes = (
ctypes.c_void_p,) # shader
-terminate = _engine.rk_terminate
+# events.hpp
EVENT_FOCUS_IN = 0
EVENT_FOCUS_OUT = 1
@@ -382,12 +401,24 @@ class _Events(ctypes.Union):
class Event(ctypes.Structure):
_fields_ = ('type', ctypes.c_uint), ('data', _Events)
-set_autorepeat = _engine.rk_set_autorepeat
-set_autorepeat.argtypes = (
- ctypes.c_bool,) # autorepeat
+create_events = _engine.rk_create_events
+create_events.restype = ctypes.c_void_p
+create_events.argtypes = (
+ ctypes.c_void_p,) # display
-set_acceleration = _engine.rk_set_acceleration
-set_acceleration.argtypes = (
+destroy_events = _engine.rk_destroy_events
+destroy_events.argtypes = (
+ ctypes.c_void_p, # display
+ ctypes.c_void_p) # events
+
+set_key_autorepeat = _engine.rk_set_key_autorepeat
+set_key_autorepeat.argtypes = (
+ ctypes.c_void_p, # events
+ ctypes.c_bool) # autorepeat
+
+set_motion_acceleration = _engine.rk_set_motion_acceleration
+set_motion_acceleration.argtypes = (
+ ctypes.c_void_p, # events
ctypes.c_uint, # numerator
ctypes.c_uint, # denominator
ctypes.c_uint) # threshold
@@ -395,5 +426,6 @@ set_acceleration.argtypes = (
consume_events = _engine.rk_consume_events
consume_events.restype = ctypes.c_uint
consume_events.argtypes = (
- ctypes.POINTER(Event), # events
+ ctypes.c_void_p, # events
+ ctypes.POINTER(Event), # buffer
ctypes.c_uint) # max_events
diff --git a/cpp/display.hpp b/cpp/display.hpp
new file mode 100644
index 0000000..a5e493f
--- /dev/null
+++ b/cpp/display.hpp
@@ -0,0 +1,34 @@
+// Copyright (C) 2022 RozK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#ifndef _RK_ENGINE_DISPLAY_H
+#define _RK_ENGINE_DISPLAY_H
+
+#include "types.hpp"
+
+typedef rk_handle_t rk_display_t;
+
+RK_EXPORT rk_display_t rk_create_display(
+ rk_char const * name,
+ rk_uint width,
+ rk_uint height);
+
+RK_EXPORT void rk_destroy_display(
+ rk_display_t display);
+
+RK_EXPORT void rk_swap_buffers(
+ rk_display_t display);
+
+#endif // _RK_ENGINE_DISPLAY_H
diff --git a/cpp/display/display_glx.cpp b/cpp/display/display_glx.cpp
new file mode 100644
index 0000000..05e2563
--- /dev/null
+++ b/cpp/display/display_glx.cpp
@@ -0,0 +1,243 @@
+// Copyright (C) 2022 RozK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+// Adapted from https://www.khronos.org/opengl/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)
+
+#include "../display.hpp"
+#include "display_glx.hpp"
+#include
+#include
+
+static bool rk_error_occured = false;
+
+#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
+typedef GLXContext (*rk_CreateContextAttribsFunc)(Display *, GLXFBConfig, GLXContext, Bool, int const *);
+
+rk_DrawElementsInstancedBaseInstanceFunc rk_DrawElementsInstancedBaseInstance = nullptr;
+rk_MultiDrawElementsIndirectFunc rk_MultiDrawElementsIndirect = nullptr;
+
+static int const rk_visual_attribs[] = {
+ GLX_X_RENDERABLE, True,
+ 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
+};
+
+static int const rk_context_attribs[] = {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 2,
+ GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES_PROFILE_BIT_EXT,
+ None
+};
+
+static void rk_glx_printf(
+ char const * messsage) {
+ printf("[GLX] %s\n", messsage);
+}
+
+static bool rk_extension_supported(
+ char const * extlist,
+ char const * extension) {
+ char const * where = strchr(extension, ' ');
+ if (where || *extension == '\0') {
+ return false;
+ }
+ for (char const * start = extlist;;) {
+ where = strstr(start, extension);
+ if (!where) {
+ break;
+ }
+ char const * const terminator = where + strlen(extension);
+ if ((where == start || *(where - 1) == ' ') && (*terminator == ' ' || *terminator == '\0')) {
+ return true;
+ }
+ start = terminator;
+ }
+ return false;
+}
+
+static int rk_error_handler(
+ Display * display,
+ XErrorEvent * event) {
+ rk_error_occured = true;
+ return 0;
+}
+
+rk_display_t rk_create_display(
+ rk_char const * name,
+ rk_uint width,
+ rk_uint height) {
+ if (!name || !width || !height) {
+ return nullptr;
+ };
+ rk_display_glx * const display = new rk_display_glx;
+ display->display = XOpenDisplay(nullptr);
+ display->window = 0;
+ display->colormap = 0;
+ display->context = nullptr;
+ if (!display->display) {
+ rk_glx_printf("Failed to open X display.");
+ rk_destroy_display(reinterpret_cast(display));
+ return nullptr;
+ }
+
+ int glx_major, glx_minor;
+ if (!glXQueryVersion(display->display, &glx_major, &glx_minor) ||
+ (glx_major == 1 && glx_minor < 3) || glx_major < 1) {
+ rk_glx_printf("Invalid GLX version.");
+ rk_destroy_display(reinterpret_cast(display));
+ return nullptr;
+ }
+ char const * const glx_exts = glXQueryExtensionsString(display->display, DefaultScreen(display->display));
+
+ int fbcount;
+ GLXFBConfig * const fbc = glXChooseFBConfig(
+ display->display, DefaultScreen(display->display), rk_visual_attribs, &fbcount);
+ if (!fbc) {
+ rk_glx_printf("Failed to retrieve framebuffer configs.");
+ rk_destroy_display(reinterpret_cast(display));
+ return nullptr;
+ }
+ printf("[GLX] Found %d framebuffer configs.\n", fbcount);
+
+ int best_fbc = -1;
+ int best_num_samp = -1;
+ for (int i = 0; i < fbcount; ++i) {
+ XVisualInfo * const vi = glXGetVisualFromFBConfig(display->display, fbc[i]);
+ if (vi) {
+ int samp_buf, samples;
+ glXGetFBConfigAttrib(display->display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
+ glXGetFBConfigAttrib(display->display, fbc[i], GLX_SAMPLES, &samples);
+ if (best_fbc < 0 || (samp_buf && samples > best_num_samp)) {
+ best_fbc = i;
+ best_num_samp = samples;
+ }
+ XFree(vi);
+ }
+ }
+ if (best_fbc == -1) {
+ XFree(fbc);
+ rk_glx_printf("Failed to find a suitable framebuffer config.");
+ rk_destroy_display(reinterpret_cast(display));
+ return nullptr;
+ }
+ GLXFBConfig const bestFbc = fbc[best_fbc];
+ XFree(fbc);
+ printf("[GLX] Select framebuffer config with %d samples.\n", best_num_samp);
+
+ XVisualInfo * const vi = glXGetVisualFromFBConfig(display->display, bestFbc);
+ display->colormap = XCreateColormap(
+ display->display, RootWindow(display->display, vi->screen), vi->visual, AllocNone);
+ XSetWindowAttributes swa;
+ swa.colormap = display->colormap;
+// swa.background_pixmap = None;
+// swa.border_pixel = 0;
+ swa.event_mask = RK_EVENTS_MASK;
+ display->window = XCreateWindow(display->display, RootWindow(display->display, vi->screen),
+ 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
+ /*CWBorderPixel |*/ CWColormap | CWEventMask, &swa);
+ XFree(vi);
+ if (!display->window) {
+ rk_glx_printf("Failed to create window.");
+ rk_destroy_display(reinterpret_cast(display));
+ return nullptr;
+ }
+ XStoreName(display->display, display->window, name);
+ XMapWindow(display->display, display->window);
+
+ rk_CreateContextAttribsFunc const glXCreateContextAttribs =
+ reinterpret_cast(
+ glXGetProcAddressARB(reinterpret_cast("glXCreateContextAttribsARB")));
+
+ if (!rk_extension_supported(glx_exts, "GLX_ARB_create_context") || !glXCreateContextAttribs) {
+ rk_glx_printf("glXCreateContextAttribsARB extension not found.");
+ rk_destroy_display(reinterpret_cast(display));
+ return nullptr;
+ } else {
+ rk_error_occured = false;
+ int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&rk_error_handler);
+ display->context = glXCreateContextAttribs(display->display, bestFbc, 0, True, rk_context_attribs);
+ XSync(display->display, False);
+ XSetErrorHandler(oldHandler);
+ if (rk_error_occured || !display->context) {
+ rk_glx_printf("Failed to create context.");
+ rk_destroy_display(reinterpret_cast(display));
+ return nullptr;
+ }
+ }
+
+ if (!glXIsDirect(display->display, display->context)) {
+ rk_glx_printf("Warning: Rendering context is indirect.");
+ }
+ glXMakeCurrent(display->display, display->window, display->context);
+
+ char const * const gl_exts = reinterpret_cast(glGetString(GL_EXTENSIONS));
+ if (rk_extension_supported(gl_exts, "GL_EXT_base_instance")) {
+ rk_DrawElementsInstancedBaseInstance =
+ reinterpret_cast(
+ glXGetProcAddressARB(reinterpret_cast("DrawElementsInstancedBaseInstance")));
+ if (rk_DrawElementsInstancedBaseInstance) {
+ rk_glx_printf("Using extension GL_EXT_base_instance::DrawElementsInstancedBaseInstance.");
+ if (rk_extension_supported(gl_exts, "GL_EXT_multi_draw_indirect")) {
+ rk_MultiDrawElementsIndirect =
+ reinterpret_cast(
+ glXGetProcAddressARB(reinterpret_cast("MultiDrawElementsIndirectEXT")));
+ if (rk_MultiDrawElementsIndirect) {
+ rk_glx_printf("Using extension GL_EXT_multi_draw_indirect::MultiDrawElementsIndirectEXT.");
+ }
+ }
+ }
+ }
+
+ return reinterpret_cast(display);
+}
+
+void rk_destroy_display(
+ rk_display_t _display) {
+ rk_display_glx * const display = reinterpret_cast(_display);
+ if (display) {
+ if (display->display) {
+ glXMakeCurrent(display->display, 0, nullptr);
+ if (display->context) {
+ glXDestroyContext(display->display, display->context);
+ }
+ if (display->window) {
+ XDestroyWindow(display->display, display->window);
+ }
+ if (display->colormap) {
+ XFreeColormap(display->display, display->colormap);
+ }
+ XCloseDisplay(display->display);
+ }
+ delete display;
+ }
+}
+
+void rk_swap_buffers(
+ rk_display_t _display) {
+ rk_display_glx const * const display = reinterpret_cast(_display);
+ if (display && display->display && display->window) {
+ glXSwapBuffers(display->display, display->window);
+ }
+}
diff --git a/cpp/opengl/render_context.hpp b/cpp/display/display_glx.hpp
similarity index 77%
rename from cpp/opengl/render_context.hpp
rename to cpp/display/display_glx.hpp
index 43409c4..33bcbc4 100644
--- a/cpp/opengl/render_context.hpp
+++ b/cpp/display/display_glx.hpp
@@ -13,10 +13,17 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-#ifndef _RK_ENGINE_RENDER_CONTEXT_H
-#define _RK_ENGINE_RENDER_CONTEXT_H
+#ifndef _RK_ENGINE_DISPLAY_GLX_H
+#define _RK_ENGINE_DISPLAY_GLX_H
-#include "../render.hpp"
+#include "../types.hpp"
+#include "display_x11.hpp"
+#include "../events/events_x11.hpp"
+#include
+
+struct rk_display_glx : public rk_display_x11 {
+ GLXContext context;
+};
typedef void (*rk_DrawElementsInstancedBaseInstanceFunc)(rk_uint, rk_uint, rk_uint, const void *, rk_uint, rk_uint);
typedef void (*rk_MultiDrawElementsIndirectFunc)(rk_uint, rk_uint, const void *, rk_uint, rk_uint);
@@ -24,12 +31,4 @@ typedef void (*rk_MultiDrawElementsIndirectFunc)(rk_uint, rk_uint, const void *,
extern rk_DrawElementsInstancedBaseInstanceFunc rk_DrawElementsInstancedBaseInstance;
extern rk_MultiDrawElementsIndirectFunc rk_MultiDrawElementsIndirect;
-extern rk_window_t rk_create_context(
- char const * name,
- unsigned width,
- unsigned height);
-
-extern void rk_swap_buffers();
-extern void rk_destroy_context();
-
-#endif // _RK_ENGINE_RENDER_CONTEXT_H
+#endif // _RK_ENGINE_DISPLAY_GLX_H
diff --git a/cpp/display/display_x11.hpp b/cpp/display/display_x11.hpp
new file mode 100644
index 0000000..c01cfa5
--- /dev/null
+++ b/cpp/display/display_x11.hpp
@@ -0,0 +1,27 @@
+// Copyright (C) 2022 RozK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#ifndef _RK_ENGINE_DISPLAY_X11_H
+#define _RK_ENGINE_DISPLAY_X11_H
+
+#include
+
+struct rk_display_x11 {
+ Display * display;
+ Window window;
+ Colormap colormap;
+};
+
+#endif // _RK_ENGINE_DISPLAY_X11_H
diff --git a/cpp/events.hpp b/cpp/events.hpp
index c6e7507..c00e8a6 100644
--- a/cpp/events.hpp
+++ b/cpp/events.hpp
@@ -17,6 +17,9 @@
#define _RK_ENGINE_EVENTS_H
#include "types.hpp"
+#include "display.hpp"
+
+typedef rk_handle_t rk_events_t;
enum rk_event_type : rk_uint {
RK_EVENT_FOCUS_IN = 0,
@@ -52,19 +55,26 @@ struct rk_event {
};
};
-extern bool rk_initialize_events();
-extern void rk_terminate_events();
+RK_EXPORT rk_events_t rk_create_events(
+ rk_display_t display);
-RK_EXPORT void rk_set_autorepeat(
+RK_EXPORT void rk_destroy_events(
+ rk_display_t display,
+ rk_events_t events);
+
+RK_EXPORT void rk_set_key_autorepeat(
+ rk_events_t events,
rk_bool autorepeat);
-RK_EXPORT void rk_set_acceleration(
+RK_EXPORT void rk_set_motion_acceleration(
+ rk_events_t events,
rk_uint numerator,
rk_uint denominator,
rk_uint threshold);
RK_EXPORT rk_uint rk_consume_events(
- rk_event * events,
+ rk_events_t events,
+ rk_event * buffer,
rk_uint max_events);
#endif // _RK_ENGINE_EVENTS_H
diff --git a/cpp/events/events_x11.cpp b/cpp/events/events_x11.cpp
index e427769..e357a41 100644
--- a/cpp/events/events_x11.cpp
+++ b/cpp/events/events_x11.cpp
@@ -14,144 +14,168 @@
// along with this program. If not, see .
#include "../events.hpp"
-#include
+#include "events_x11.hpp"
+#include "../display/display_x11.hpp"
+#include
-extern Display * rk_display;
-extern Window rk_window;
-
-unsigned rk_events_mask = FocusChangeMask |
- KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask;
-
-static XIM rk_input_manager = nullptr;
-static XIC rk_input_context = nullptr;
-
-static bool rk_focused = false;
-static bool rk_keyboard_autorepeat = false;
-static XKeyboardState rk_previous_keyboard_state;
-static int rk_previous_accel_numerator, rk_accel_numerator = 1;
-static int rk_previous_accel_denominator, rk_accel_denominator = 1;
-static int rk_previous_threshold, rk_accel_threshold = 0;
-
-static void rk_backup_setup() {
- XGetKeyboardControl(rk_display, &rk_previous_keyboard_state);
- XGetPointerControl(rk_display,
- &rk_previous_accel_numerator, &rk_previous_accel_denominator, &rk_previous_threshold);
+static void rk_x11_printf(
+ char const * messsage) {
+ printf("[X11] %s\n", messsage);
}
-static void rk_restore_setup() {
- if (AutoRepeatModeOn == rk_previous_keyboard_state.global_auto_repeat) {
- XAutoRepeatOn(rk_display);
+static void rk_backup(rk_events_x11 & events) {
+ XKeyboardState backup;
+ XGetKeyboardControl(events.display, &backup);
+ events.backup_autorepeat = (AutoRepeatModeOn == backup.global_auto_repeat);
+ XGetPointerControl(
+ events.display, &events.backup_numerator, &events.backup_denominator, &events.backup_threshold);
+}
+
+static void rk_restore(rk_events_x11 & events) {
+ if (events.backup_autorepeat) {
+ XAutoRepeatOn(events.display);
} else {
- XAutoRepeatOff(rk_display);
+ XAutoRepeatOff(events.display);
}
- XChangePointerControl(rk_display, True, True,
- rk_previous_accel_numerator, rk_previous_accel_denominator, rk_previous_threshold);
+ XChangePointerControl(
+ events.display, True, True, events.backup_numerator, events.backup_denominator, events.backup_threshold);
}
-static void rk_apply_setup() {
- if (rk_keyboard_autorepeat) {
- XAutoRepeatOn(rk_display);
+static void rk_apply(rk_events_x11 & events) {
+ if (events.key_autorepeat) {
+ XAutoRepeatOn(events.display);
} else {
- XAutoRepeatOff(rk_display);
+ XAutoRepeatOff(events.display);
}
- XChangePointerControl(rk_display, True, True, rk_accel_numerator, rk_accel_denominator, rk_accel_threshold);
+ XChangePointerControl(
+ events.display, True, True, events.motion_numerator, events.motion_denominator, events.motion_threshold);
}
-bool rk_initialize_events() {
- rk_focused = false;
- rk_backup_setup();
- rk_keyboard_autorepeat = (AutoRepeatModeOn == rk_previous_keyboard_state.global_auto_repeat);
- rk_accel_numerator = rk_previous_accel_numerator;
- rk_accel_denominator = rk_previous_accel_denominator;
- rk_accel_threshold = rk_previous_threshold;
- rk_input_manager = XOpenIM(rk_display, nullptr, nullptr, nullptr);
- if (!rk_input_manager) {
- return false;
- }
- rk_input_context = XCreateIC(rk_input_manager,
- XNInputStyle, XIMPreeditNone | XIMStatusNone,
- XNClientWindow, rk_window,
- NULL);
- if (!rk_input_context) {
- return false;
- }
- XSetICFocus(rk_input_context);
- return true;
-}
-
-void rk_terminate_events() {
- rk_restore_setup();
- if (rk_input_context) {
- XUnsetICFocus(rk_input_context);
- XDestroyIC(rk_input_context);
- rk_input_context = nullptr;
- }
- if (rk_input_manager) {
- XCloseIM(rk_input_manager);
- rk_input_manager = nullptr;
- }
-}
-
-static void rk_focus_in() {
- if (!rk_focused) {
- rk_backup_setup();
- rk_apply_setup();
- XGrabPointer(rk_display, rk_window, True,
+static void rk_focus_in(rk_events_x11 & events) {
+ if (!events.focused) {
+ rk_backup(events);
+ rk_apply(events);
+ XGrabPointer(events.display, events.window, True,
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
- GrabModeAsync, GrabModeAsync, rk_window, None, CurrentTime);
- rk_focused = true;
+ GrabModeAsync, GrabModeAsync, events.window, None, CurrentTime);
+ events.focused = true;
}
}
-static void rk_focus_out() {
- if (rk_focused) {
- XUngrabPointer(rk_display, CurrentTime);
- rk_restore_setup();
- rk_focused = false;
+static void rk_focus_out(rk_events_x11 & events) {
+ if (events.focused) {
+ XUngrabPointer(events.display, CurrentTime);
+ rk_restore(events);
+ events.focused = false;
}
}
-void rk_set_autorepeat(
+rk_events_t rk_create_events(
+ rk_display_t _display) {
+ rk_display_x11 const * const display = reinterpret_cast(_display);
+ if (!display || !display->display || !display->window) {
+ return nullptr;
+ }
+ rk_events_x11 * const events = new rk_events_x11;
+ events->display = display->display;
+ events->window = display->window;
+ events->input_manager = XOpenIM(display->display, nullptr, nullptr, nullptr);
+ if (!events->input_manager) {
+ rk_x11_printf("Failed to open input manager.");
+ delete events;
+ return nullptr;
+ }
+ events->input_context = XCreateIC(events->input_manager,
+ XNInputStyle, XIMPreeditNone | XIMStatusNone,
+ XNClientWindow, display->window,
+ NULL);
+ if (!events->input_context) {
+ rk_x11_printf("Failed to create input context.");
+ XCloseIM(events->input_manager);
+ delete events;
+ return nullptr;
+ }
+ events->focused = false;
+ rk_backup(*events);
+ events->key_autorepeat = events->backup_autorepeat;
+ events->motion_numerator = events->backup_numerator;
+ events->motion_denominator = events->backup_denominator;
+ events->motion_threshold = events->backup_threshold;
+ XSetICFocus(events->input_context);
+ return reinterpret_cast(events);
+}
+
+void rk_destroy_events(
+ rk_display_t _display,
+ rk_events_t _events) {
+ rk_display_x11 const * const display = reinterpret_cast(_display);
+ rk_events_x11 * const events = reinterpret_cast(_events);
+ if (display && events && display->display && display->display == events->display) {
+ rk_restore(*events);
+ if (events->input_context) {
+ XUnsetICFocus(events->input_context);
+ XDestroyIC(events->input_context);
+ }
+ if (events->input_manager) {
+ XCloseIM(events->input_manager);
+ }
+ }
+ if (events) {
+ delete events;
+ }
+}
+
+void rk_set_key_autorepeat(
+ rk_events_t _events,
rk_bool autorepeat) {
- rk_keyboard_autorepeat = autorepeat;
- if (rk_focused) {
- rk_apply_setup();
+ rk_events_x11 * const events = reinterpret_cast(_events);
+ if (events) {
+ events->key_autorepeat = autorepeat;
+ if (events->focused) {
+ rk_apply(*events);
+ }
}
}
-void rk_set_acceleration(
+void rk_set_motion_acceleration(
+ rk_events_t _events,
rk_uint numerator,
rk_uint denominator,
rk_uint threshold) {
- rk_accel_numerator = numerator;
- rk_accel_denominator = denominator;
- rk_accel_threshold = threshold;
- if (rk_focused) {
- rk_apply_setup();
+ rk_events_x11 * const events = reinterpret_cast(_events);
+ if (events) {
+ events->motion_numerator = numerator;
+ events->motion_denominator = denominator;
+ events->motion_threshold = threshold;
+ if (events->focused) {
+ rk_apply(*events);
+ }
}
}
rk_uint rk_consume_events(
- rk_event * events,
+ rk_events_t _events,
+ rk_event * buffer,
rk_uint max_events) {
static wchar_t string[256];
- if (!events || !max_events) {
+ rk_events_x11 * const events = reinterpret_cast(_events);
+ if (!events || !buffer || !max_events) {
return 0;
}
XEvent x11_event;
KeySym keysym;
Status status;
unsigned nevents = 0;
- while (nevents < max_events && XCheckWindowEvent(rk_display, rk_window, rk_events_mask, &x11_event)) {
+ while (nevents < max_events && XCheckWindowEvent(events->display, events->window, RK_EVENTS_MASK, &x11_event)) {
if (XFilterEvent(&x11_event, 0)) {
continue;
}
- rk_event & event = events[nevents];
+ rk_event & event = buffer[nevents];
switch (x11_event.type) {
case FocusIn:
if (NotifyNormal == x11_event.xfocus.mode) {
- rk_focus_in();
+ rk_focus_in(*events);
event.type = RK_EVENT_FOCUS_IN;
++nevents;
}
@@ -159,7 +183,7 @@ rk_uint rk_consume_events(
case FocusOut:
if (NotifyNormal == x11_event.xfocus.mode) {
- rk_focus_out();
+ rk_focus_out(*events);
event.type = RK_EVENT_FOCUS_OUT;
++nevents;
}
@@ -168,7 +192,7 @@ rk_uint rk_consume_events(
case KeyPress:
event.type = RK_EVENT_KEY_PRESS;
event.key.code = x11_event.xkey.keycode;
- XwcLookupString(rk_input_context, &x11_event.xkey, string, 256, &keysym, &status);
+ XwcLookupString(events->input_context, &x11_event.xkey, string, 256, &keysym, &status);
switch (status) {
case XLookupChars:
event.key.symbol = XLookupKeysym(&x11_event.xkey, 0);
diff --git a/cpp/events/events_x11.hpp b/cpp/events/events_x11.hpp
new file mode 100644
index 0000000..423165e
--- /dev/null
+++ b/cpp/events/events_x11.hpp
@@ -0,0 +1,44 @@
+// Copyright (C) 2022 RozK
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero 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 Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+#ifndef _RK_ENGINE_EVENTS_X11_H
+#define _RK_ENGINE_EVENTS_X11_H
+
+#include
+
+enum : unsigned {
+ RK_EVENTS_MASK = FocusChangeMask |
+ KeyPressMask | KeyReleaseMask |
+ ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask
+};
+
+struct rk_events_x11 {
+ Display * display;
+ Window window;
+ XIM input_manager;
+ XIC input_context;
+ bool focused;
+ bool key_autorepeat;
+ bool backup_autorepeat;
+ int motion_numerator;
+ int backup_numerator;
+ int motion_denominator;
+ int backup_denominator;
+ int motion_threshold;
+ int backup_threshold;
+};
+
+#endif // _RK_ENGINE_EVENTS_X11_H
diff --git a/cpp/opengl/render_context_glx.cpp b/cpp/opengl/render_context_glx.cpp
deleted file mode 100644
index 99d54bd..0000000
--- a/cpp/opengl/render_context_glx.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright (C) 2022 RozK
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero 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 Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-// Adapted from https://www.khronos.org/opengl/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)
-
-#include "render_context.hpp"
-#include "../events.hpp"
-#include
-#include
-#include
-#include
-#include
-
-extern unsigned rk_events_mask;
-
-Display * rk_display = nullptr;
-Window rk_window = 0;
-
-static Colormap rk_colormap = 0;
-static GLXContext rk_context = nullptr;
-static bool rk_error_occured = false;
-
-#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
-typedef GLXContext (*glXCreateContextAttribsARBProc)(Display *, GLXFBConfig, GLXContext, Bool, int const *);
-
-rk_DrawElementsInstancedBaseInstanceFunc rk_DrawElementsInstancedBaseInstance = nullptr;
-rk_MultiDrawElementsIndirectFunc rk_MultiDrawElementsIndirect = nullptr;
-
-static int const rk_visual_attribs[] = {
- GLX_X_RENDERABLE, True,
- 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
-};
-
-static int const rk_context_attribs[] = {
- GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
- GLX_CONTEXT_MINOR_VERSION_ARB, 2,
- GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES_PROFILE_BIT_EXT,
- None
-};
-
-static void rk_printf(
- char const * messsage) {
- printf("[GLX] %s\n", messsage);
-}
-
-static bool rk_extension_supported(
- char const * extlist,
- char const * extension) {
- char const * where = strchr(extension, ' ');
- if (where || *extension == '\0') {
- return false;
- }
- for (char const * start = extlist;;) {
- where = strstr(start, extension);
- if (!where) {
- break;
- }
- char const * const terminator = where + strlen(extension);
- if ((where == start || *(where - 1) == ' ') && (*terminator == ' ' || *terminator == '\0')) {
- return true;
- }
- start = terminator;
- }
- return false;
-}
-
-static int rk_error_handler(
- Display * display,
- XErrorEvent * event) {
- rk_error_occured = true;
- return 0;
-}
-
-rk_window_t rk_create_context(
- char const * name,
- unsigned width,
- unsigned height) {
- XSetLocaleModifiers("");
-
- rk_display = XOpenDisplay(nullptr);
- if (!rk_display) {
- rk_printf("Failed to open X display.");
- return nullptr;
- }
-
- int glx_major, glx_minor;
- if (!glXQueryVersion(rk_display, &glx_major, &glx_minor) || (glx_major == 1 && glx_minor < 3) || glx_major < 1) {
- rk_printf("Invalid GLX version.");
- rk_destroy_context();
- return nullptr;
- }
-
- int fbcount;
- GLXFBConfig * const fbc = glXChooseFBConfig(rk_display, DefaultScreen(rk_display), rk_visual_attribs, &fbcount);
- if (!fbc) {
- rk_printf("Failed to retrieve framebuffer configs.");
- rk_destroy_context();
- return nullptr;
- }
- printf("[GLX] Found %d framebuffer configs.\n", fbcount);
-
- int best_fbc = -1;
- int best_num_samp = -1;
- for (int i = 0; i < fbcount; ++i) {
- XVisualInfo * vi = glXGetVisualFromFBConfig(rk_display, fbc[i]);
- if (vi) {
- int samp_buf, samples;
- glXGetFBConfigAttrib(rk_display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
- glXGetFBConfigAttrib(rk_display, fbc[i], GLX_SAMPLES, &samples);
- if (best_fbc < 0 || (samp_buf && samples > best_num_samp)) {
- best_fbc = i;
- best_num_samp = samples;
- }
- XFree(vi);
- }
- }
- if (best_fbc == -1) {
- XFree(fbc);
- rk_printf("Failed to find a suitable framebuffer config.");
- rk_destroy_context();
- return nullptr;
- }
- GLXFBConfig const bestFbc = fbc[best_fbc];
- XFree(fbc);
- printf("[GLX] Select framebuffer config with %d samples.\n", best_num_samp);
-
- XVisualInfo * const vi = glXGetVisualFromFBConfig(rk_display, bestFbc);
- rk_colormap = XCreateColormap(rk_display, RootWindow(rk_display, vi->screen), vi->visual, AllocNone);
- XSetWindowAttributes swa;
- swa.colormap = rk_colormap;
- swa.background_pixmap = None;
- swa.border_pixel = 0;
- swa.event_mask = rk_events_mask;
- rk_window = XCreateWindow(rk_display, RootWindow(rk_display, vi->screen),
- 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual,
- CWBorderPixel | CWColormap | CWEventMask, &swa);
- XFree(vi);
- if (!rk_window) {
- rk_printf("Failed to create window.");
- rk_destroy_context();
- return nullptr;
- }
- XStoreName(rk_display, rk_window, name);
-
- if (!rk_initialize_events()) {
- rk_printf("Failed to initialize events.");
- rk_destroy_context();
- return nullptr;
- }
-
- XMapWindow(rk_display, rk_window);
-
- char const * const glx_exts = glXQueryExtensionsString(rk_display, DefaultScreen(rk_display));
- glXCreateContextAttribsARBProc const glXCreateContextAttribsARB =
- reinterpret_cast(
- glXGetProcAddressARB(reinterpret_cast("glXCreateContextAttribsARB")));
-
- rk_error_occured = false;
- int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&rk_error_handler);
- if (!rk_extension_supported(glx_exts, "GLX_ARB_create_context") || !glXCreateContextAttribsARB) {
- rk_printf("glXCreateContextAttribsARB() extension not found.");
- rk_destroy_context();
- return nullptr;
- } else {
- rk_context = glXCreateContextAttribsARB(rk_display, bestFbc, 0, True, rk_context_attribs);
- XSync(rk_display, False);
- if (rk_error_occured || !rk_context) {
- rk_printf("Failed to create context.");
- rk_destroy_context();
- return nullptr;
- }
- }
- XSetErrorHandler(oldHandler);
-
- if (!glXIsDirect(rk_display, rk_context)) {
- rk_printf("Warning: Rendering context is indirect.");
- }
- glXMakeCurrent(rk_display, rk_window, rk_context);
-
- char const * const gl_exts = reinterpret_cast(glGetString(GL_EXTENSIONS));
- if (rk_extension_supported(gl_exts, "GL_EXT_base_instance")) {
- rk_DrawElementsInstancedBaseInstance =
- reinterpret_cast(
- glXGetProcAddressARB(reinterpret_cast("DrawElementsInstancedBaseInstance")));
- if (rk_DrawElementsInstancedBaseInstance) {
- rk_printf("Using extension GL_EXT_base_instance::DrawElementsInstancedBaseInstance.");
- if (rk_extension_supported(gl_exts, "GL_EXT_multi_draw_indirect")) {
- rk_MultiDrawElementsIndirect =
- reinterpret_cast(
- glXGetProcAddressARB(reinterpret_cast("MultiDrawElementsIndirectEXT")));
- if (rk_MultiDrawElementsIndirect) {
- rk_printf("Using extension GL_EXT_multi_draw_indirect::MultiDrawElementsIndirectEXT.");
- }
- }
- }
- }
-
- return reinterpret_cast(rk_window);
-}
-
-void rk_swap_buffers() {
- if (rk_display && rk_window) {
- glXSwapBuffers(rk_display, rk_window);
- }
-}
-
-void rk_destroy_context() {
- if (rk_display) {
- glXMakeCurrent(rk_display, 0, nullptr);
- if (rk_context) {
- glXDestroyContext(rk_display, rk_context);
- rk_context = nullptr;
- }
- rk_terminate_events();
- if (rk_window) {
- XDestroyWindow(rk_display, rk_window);
- rk_window = 0;
- }
- if (rk_colormap) {
- XFreeColormap(rk_display, rk_colormap);
- rk_colormap = 0;
- }
- XCloseDisplay(rk_display);
- rk_display = nullptr;
- }
-}
diff --git a/cpp/render.hpp b/cpp/render.hpp
index 885f2c8..0d46b6a 100644
--- a/cpp/render.hpp
+++ b/cpp/render.hpp
@@ -19,7 +19,6 @@
#include "types.hpp"
#include "math.hpp"
-typedef rk_handle_t rk_window_t;
typedef rk_handle_t rk_shader_t;
typedef rk_handle_t rk_input_t;
typedef rk_handle_t rk_param_t;
@@ -28,8 +27,6 @@ typedef rk_handle_t rk_triangles_t;
typedef rk_handle_t rk_vertices_t;
typedef rk_handle_t rk_batch_t;
-#define RK_FLAG(bit) (1 << (bit))
-
enum rk_texture_format : rk_uint {
RK_TEXTURE_FORMAT_SRGB8_A8 = 0,
RK_TEXTURE_FORMAT_RGBA8 = 1,
@@ -81,10 +78,9 @@ union rk_mesh {
};
};
-RK_EXPORT rk_window_t rk_initialize(
- char const * name,
- rk_uint width,
- rk_uint height);
+RK_EXPORT void rk_render_initialize();
+
+RK_EXPORT void rk_render_terminate();
RK_EXPORT rk_shader_t rk_load_shader(
rk_uint const vert_nlines,
@@ -194,6 +190,4 @@ RK_EXPORT void rk_destroy_texture(
RK_EXPORT void rk_destroy_shader(
rk_shader_t shader);
-RK_EXPORT void rk_terminate();
-
#endif // _RK_ENGINE_RENDER_H
diff --git a/cpp/opengl/render_opengles.cpp b/cpp/render/render_opengles.cpp
similarity index 94%
rename from cpp/opengl/render_opengles.cpp
rename to cpp/render/render_opengles.cpp
index bb80145..6c28863 100644
--- a/cpp/opengl/render_opengles.cpp
+++ b/cpp/render/render_opengles.cpp
@@ -13,17 +13,19 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
+#include "../render.hpp"
#include "render_opengles.hpp"
+#include "../display/display_glx.hpp"
#include
static rk_shader const * rk_current_shader = nullptr;
static rk_vertices const * rk_current_vertices = nullptr;
-static void rk_printf(char const * messsage) {
- printf("[RK_ENGINE] %s\n", messsage);
+static void rk_printf(char const * message) {
+ printf("[RK] %s\n", message);
}
-#define rk_error(message) { if (glGetError() != GL_NO_ERROR) { rk_printf(message); } }
+#define rk_gl_error(_message) { if (glGetError() != GL_NO_ERROR) { printf("[GL] %s\n", (_message)); } }
static void rk_debug_message_callback(
GLenum source,
@@ -33,36 +35,32 @@ static void rk_debug_message_callback(
GLsizei length,
GLchar const * message,
void const * userParam) {
- printf("[RK_ENGINE][GL] (id=%d) %s\n", id, message);
+ printf("[GL] (id=%d) %s\n", id, message);
}
-rk_window_t rk_initialize(
- char const * name,
- rk_uint width,
- rk_uint height) {
- rk_window_t const window = rk_create_context(name, width, height);
- if (window) {
- GLubyte const * const vendor = glGetString(GL_VENDOR);
- GLubyte const * const renderer = glGetString(GL_RENDERER);
- printf("[RK_ENGINE] vendor: %s, renderer: %s\n", vendor, renderer);
- GLubyte const * const version = glGetString(GL_VERSION);
- GLubyte const * const language = glGetString(GL_SHADING_LANGUAGE_VERSION);
- printf("[RK_ENGINE] version: %s, language: %s\n", version, language);
+void rk_render_initialize() {
+ GLubyte const * const vendor = glGetString(GL_VENDOR);
+ GLubyte const * const renderer = glGetString(GL_RENDERER);
+ printf("[RK] vendor: %s, renderer: %s\n", vendor, renderer);
+ GLubyte const * const version = glGetString(GL_VERSION);
+ GLubyte const * const language = glGetString(GL_SHADING_LANGUAGE_VERSION);
+ printf("[RK] version: %s, language: %s\n", version, language);
- glDebugMessageCallback(rk_debug_message_callback, nullptr);
- glEnable(GL_DEBUG_OUTPUT);
+ glDebugMessageCallback(rk_debug_message_callback, nullptr);
+ glEnable(GL_DEBUG_OUTPUT);
- glDisable(GL_BLEND);
- glEnable(GL_DITHER);
- glEnable(GL_DEPTH_TEST);
- glDisable(GL_SCISSOR_TEST);
- glDisable(GL_STENCIL_TEST);
- glEnable(GL_CULL_FACE);
- glFrontFace(GL_CCW);
- glCullFace(GL_BACK);
- glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
- }
- return window;
+ glDisable(GL_BLEND);
+ glEnable(GL_DITHER);
+ glEnable(GL_DEPTH_TEST);
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_STENCIL_TEST);
+ glEnable(GL_CULL_FACE);
+ glFrontFace(GL_CCW);
+ glCullFace(GL_BACK);
+ glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
+}
+
+void rk_render_terminate() {
}
static void rk_print_shader_infolog(GLuint shader) {
@@ -104,18 +102,18 @@ rk_shader_t rk_load_shader(
rk_printf("Compiling vertex shader...");
glShaderSource(shader->vertex, vert_nlines, vert_lines, nullptr);
glCompileShader(shader->vertex);
- rk_error("glCompileShader() failed.");
+ rk_gl_error("glCompileShader() failed.");
rk_print_shader_infolog(shader->vertex);
rk_printf("Compiling fragment shader...");
glShaderSource(shader->fragment, frag_nlines, frag_lines, nullptr);
glCompileShader(shader->fragment);
- rk_error("glCompileShader() failed.");
+ rk_gl_error("glCompileShader() failed.");
rk_print_shader_infolog(shader->fragment);
rk_printf("Linking program...");
glAttachShader(shader->program, shader->vertex);
glAttachShader(shader->program, shader->fragment);
glLinkProgram(shader->program);
- rk_error("glLinkProgram() failed.");
+ rk_gl_error("glLinkProgram() failed.");
rk_print_program_infolog(shader->program);
rk_printf("Done.");
glReleaseShaderCompiler();
@@ -669,7 +667,6 @@ void rk_unselect_shader(
}
void rk_end_frame() {
- rk_swap_buffers();
}
void rk_destroy_batch(
@@ -730,7 +727,3 @@ void rk_destroy_shader(
delete shader;
}
}
-
-void rk_terminate() {
- rk_destroy_context();
-}
diff --git a/cpp/opengl/render_opengles.hpp b/cpp/render/render_opengles.hpp
similarity index 97%
rename from cpp/opengl/render_opengles.hpp
rename to cpp/render/render_opengles.hpp
index d73d160..d3a1186 100644
--- a/cpp/opengl/render_opengles.hpp
+++ b/cpp/render/render_opengles.hpp
@@ -16,8 +16,7 @@
#ifndef _RK_ENGINE_RENDER_OPENGLES_H
#define _RK_ENGINE_RENDER_OPENGLES_H
-#include "../render.hpp"
-#include "render_context.hpp"
+#include "../types.hpp"
#include
#include
#include
diff --git a/cpp/types.hpp b/cpp/types.hpp
index 72f22ee..edac367 100644
--- a/cpp/types.hpp
+++ b/cpp/types.hpp
@@ -20,6 +20,7 @@
#include
#define RK_EXPORT extern "C"
+#define RK_FLAG(_bit) (1 << (_bit))
typedef bool rk_bool;
typedef char rk_char;