diff --git a/cpp/display/display_glx.cpp b/cpp/display/display_glx.cpp index 8f2dae1..2a79cc9 100644 --- a/cpp/display/display_glx.cpp +++ b/cpp/display/display_glx.cpp @@ -17,6 +17,7 @@ #include "../display.hpp" #include "display_glx.hpp" +#include "../events/events_x11.hpp" #include #include @@ -26,9 +27,6 @@ static bool rk_error_occured = false; #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, @@ -51,19 +49,24 @@ static int const rk_context_attribs[] = { None }; +static void rk_x11_printf( + char const * messsage) { + printf("[X11] %s\n", messsage); +} + static void rk_glx_printf( char const * messsage) { printf("[GLX] %s\n", messsage); } static bool rk_extension_supported( - char const * extlist, + char const * extensions, char const * extension) { char const * where = strchr(extension, ' '); if (where || *extension == '\0') { return false; } - for (char const * start = extlist;;) { + for (char const * start = extensions;;) { where = strstr(start, extension); if (!where) { break; @@ -77,6 +80,24 @@ static bool rk_extension_supported( return false; } +rk_func_ptr rk_resolve_extension( + char const * extensions, + char const * extension, + char const * fn) { + if (!extensions || !extension || !fn) { + return nullptr; + } + if (!rk_extension_supported(extensions, extension)) { + printf("[GLX] Extension %s not supported\n", extension); + return nullptr; + } + rk_func_ptr const ptr = glXGetProcAddressARB(reinterpret_cast(fn)); + if (!ptr) { + printf("[GLX] Function %s::%s not found\n", extension, fn); + } + return ptr; +} + static int rk_error_handler( Display * display, XErrorEvent * event) { @@ -97,7 +118,7 @@ rk_display_t rk_create_display( display->colormap = 0; display->context = nullptr; if (!display->display) { - rk_glx_printf("Failed to open X display."); + rk_x11_printf("Failed to open X display."); rk_destroy_display(reinterpret_cast(display)); return nullptr; } @@ -109,8 +130,15 @@ rk_display_t rk_create_display( rk_destroy_display(reinterpret_cast(display)); return nullptr; } + char const * const glx_exts = glXQueryExtensionsString(display->display, DefaultScreen(display->display)); // rk_glx_printf(glx_exts); + rk_CreateContextAttribsFunc const glXCreateContextAttribs = reinterpret_cast( + rk_resolve_extension(glx_exts, "GLX_ARB_create_context", "glXCreateContextAttribsARB")); + if (!glXCreateContextAttribs) { + rk_destroy_display(reinterpret_cast(display)); + return nullptr; + } int fbcount; GLXFBConfig * const fbc = glXChooseFBConfig( @@ -157,32 +185,22 @@ rk_display_t rk_create_display( 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa); XFree(vi); if (!display->window) { - rk_glx_printf("Failed to create window."); + rk_x11_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_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; - } 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)) { @@ -190,25 +208,6 @@ rk_display_t rk_create_display( } glXMakeCurrent(display->display, display->window, display->context); - char const * const gl_exts = reinterpret_cast(glGetString(GL_EXTENSIONS)); - // printf("[GL] %s\n", gl_exts); - 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); } diff --git a/cpp/display/display_glx.hpp b/cpp/display/display_glx.hpp index 33bcbc4..80252a8 100644 --- a/cpp/display/display_glx.hpp +++ b/cpp/display/display_glx.hpp @@ -18,17 +18,17 @@ #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); +typedef void (*rk_func_ptr)(); -extern rk_DrawElementsInstancedBaseInstanceFunc rk_DrawElementsInstancedBaseInstance; -extern rk_MultiDrawElementsIndirectFunc rk_MultiDrawElementsIndirect; +extern rk_func_ptr rk_resolve_extension( + char const * extensions, + char const * extension, + char const * fn); #endif // _RK_ENGINE_DISPLAY_GLX_H diff --git a/cpp/render/render_opengles.cpp b/cpp/render/render_opengles.cpp index cf1075c..73c51a1 100644 --- a/cpp/render/render_opengles.cpp +++ b/cpp/render/render_opengles.cpp @@ -19,9 +19,19 @@ #include #include +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); + +static rk_DrawElementsInstancedBaseInstanceFunc rk_DrawElementsInstancedBaseInstance = nullptr; +static rk_MultiDrawElementsIndirectFunc rk_MultiDrawElementsIndirect = nullptr; + static rk_shader const * rk_current_shader = nullptr; static rk_vertices const * rk_current_vertices = nullptr; +static void rk_gl_printf(char const * message) { + printf("[GL] %s\n", message); +} + static void rk_printf(char const * message) { printf("[RK] %s\n", message); } @@ -42,14 +52,27 @@ static void rk_debug_message_callback( 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); + printf("[GL] 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); + printf("[GL] version: %s, language: %s\n", version, language); glDebugMessageCallback(rk_debug_message_callback, nullptr); glEnable(GL_DEBUG_OUTPUT); + char const * const gl_exts = reinterpret_cast(glGetString(GL_EXTENSIONS)); + // printf("[GL] %s\n", gl_exts); + rk_DrawElementsInstancedBaseInstance = reinterpret_cast( + rk_resolve_extension(gl_exts, "GL_EXT_base_instance", "DrawElementsInstancedBaseInstance")); + if (rk_DrawElementsInstancedBaseInstance) { + rk_gl_printf("Using extension GL_EXT_base_instance::DrawElementsInstancedBaseInstance."); + rk_MultiDrawElementsIndirect = reinterpret_cast( + rk_resolve_extension(gl_exts, "GL_EXT_multi_draw_indirect", "MultiDrawElementsIndirectEXT")); + if (rk_MultiDrawElementsIndirect) { + rk_gl_printf("Using extension GL_EXT_multi_draw_indirect::MultiDrawElementsIndirectEXT."); + } + } + glDisable(GL_BLEND); glEnable(GL_DITHER); glEnable(GL_DEPTH_TEST);