diff --git a/__init__.py b/__init__.py index 8ef28dd..a52f73b 100644 --- a/__init__.py +++ b/__init__.py @@ -185,7 +185,9 @@ def mat4_mul_mat4(ret, a, b): initialize = _lib.rk_initialize initialize.restype = ctypes.c_void_p initialize.argtypes = ( - ctypes.c_char_p,) # name + ctypes.c_char_p, # name + ctypes.c_uint, # width + ctypes.c_uint) # height _load_shader = _lib.rk_load_shader _load_shader.restype = ctypes.c_void_p diff --git a/cpp/opengl/render_context.hpp b/cpp/opengl/render_context.hpp index 1d632a0..5d44619 100644 --- a/cpp/opengl/render_context.hpp +++ b/cpp/opengl/render_context.hpp @@ -13,16 +13,19 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -#ifndef _RK_ENGINE_RENDER_OPENGL_CONTEXT_H -#define _RK_ENGINE_RENDER_OPENGL_CONTEXT_H +#ifndef _RK_ENGINE_RENDER_CONTEXT_H +#define _RK_ENGINE_RENDER_CONTEXT_H #include "../render.hpp" +#include + +extern PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC rk_DrawElementsInstancedBaseInstance; +extern PFNGLMULTIDRAWELEMENTSINDIRECTPROC rk_MultiDrawElementsIndirect; RK_EXPORT rk_window_t rk_create_context( char const * name, - int profile, - int major, - int minor); + rk_uint width, + rk_uint height); RK_EXPORT char ** rk_load_shader_source( char const * filename, @@ -35,4 +38,4 @@ RK_EXPORT void rk_free_shader_source( RK_EXPORT void rk_swap_buffers(); RK_EXPORT void rk_destroy_context(); -#endif // _RK_ENGINE_RENDER_OPENGL_CONTEXT_H +#endif // _RK_ENGINE_RENDER_CONTEXT_H diff --git a/cpp/opengl/render_context_glx.cpp b/cpp/opengl/render_context_glx.cpp index 884ecd1..93ddba0 100644 --- a/cpp/opengl/render_context_glx.cpp +++ b/cpp/opengl/render_context_glx.cpp @@ -18,7 +18,7 @@ #include "render_context.hpp" #include #include -#include +#include #include static Display * rk_display = nullptr; @@ -31,6 +31,31 @@ static bool rk_error_occured = false; #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 typedef GLXContext (*glXCreateContextAttribsARBProc)(Display *, GLXFBConfig, GLXContext, Bool, int const *); +PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC rk_DrawElementsInstancedBaseInstance = nullptr; +PFNGLMULTIDRAWELEMENTSINDIRECTPROC 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); @@ -66,30 +91,14 @@ static int rk_error_handler( rk_window_t rk_create_context( char const * name, - int profile, - int major, - int minor) { + rk_uint width, + rk_uint height) { rk_display = XOpenDisplay(nullptr); if (!rk_display) { rk_printf("Failed to open X display."); return nullptr; } - static int const 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 - }; - 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."); @@ -98,7 +107,7 @@ rk_window_t rk_create_context( } int fbcount; - GLXFBConfig * const fbc = glXChooseFBConfig(rk_display, DefaultScreen(rk_display), visual_attribs, &fbcount); + GLXFBConfig * const fbc = glXChooseFBConfig(rk_display, DefaultScreen(rk_display), rk_visual_attribs, &fbcount); if (!fbc) { rk_printf("Failed to retrieve a framebuffer config."); rk_destroy_context(); @@ -141,7 +150,7 @@ rk_window_t rk_create_context( swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; rk_window = XCreateWindow(rk_display, RootWindow(rk_display, vi->screen), - 0, 0, 1600, 900, 0, vi->depth, InputOutput, vi->visual, + 0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel | CWColormap | CWEventMask, &swa); if (!rk_window) { rk_printf("Failed to create window."); @@ -150,27 +159,21 @@ rk_window_t rk_create_context( } XFree(vi); XStoreName(rk_display, rk_window, name); - XMapWindow( rk_display, rk_window ); + XMapWindow(rk_display, rk_window); char const * const glxExts = glXQueryExtensionsString(rk_display, DefaultScreen(rk_display)); - glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; - glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) - glXGetProcAddressARB((const GLubyte *)("glXCreateContextAttribsARB")); + 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(glxExts, "GLX_ARB_create_context") || !glXCreateContextAttribsARB) { - rk_printf("glXCreateContextAttribsARB() not found."); + rk_printf("glXCreateContextAttribsARB() extension not found."); rk_destroy_context(); return nullptr; } else { - const int context_attribs[] = { - GLX_CONTEXT_MAJOR_VERSION_ARB, major, - GLX_CONTEXT_MINOR_VERSION_ARB, minor, - GLX_CONTEXT_PROFILE_MASK_ARB, profile, - None - }; - rk_context = glXCreateContextAttribsARB(rk_display, bestFbc, 0, True, context_attribs); + 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."); @@ -184,6 +187,24 @@ rk_window_t rk_create_context( rk_printf("Warning: Rendering context is indirect."); } glXMakeCurrent(rk_display, rk_window, rk_context); + + if (rk_extension_supported(glxExts, "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(glxExts, "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); } diff --git a/cpp/opengl/render_opengles.cpp b/cpp/opengl/render_opengles.cpp index 23e0830..b5ea8f7 100644 --- a/cpp/opengl/render_opengles.cpp +++ b/cpp/opengl/render_opengles.cpp @@ -15,18 +15,11 @@ #include "render_opengles.hpp" #include -#include - -//TODO: move the GLX stuff to render_context_glx.cpp -#include static rk_shader const * rk_current_shader = nullptr; static rk_vertices const * rk_current_vertices = nullptr; static bool rk_frame = false; -static PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC rk_DrawElementsInstancedBaseInstance = nullptr; -static PFNGLMULTIDRAWELEMENTSINDIRECTPROC rk_MultiDrawElementsIndirect = nullptr; - static void rk_printf(char const * messsage) { printf("[RK_ENGINE] %s\n", messsage); } @@ -47,26 +40,11 @@ static void rk_debug_message_callback( printf("[RK_ENGINE][GL] (id=%d) %s\n", id, message); } -static __GLXextFuncPtr rk_extension( - char const * const name, - char const * const func) { - __GLXextFuncPtr ext_ptr = nullptr; - GLint num_exts = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts); - for (int ext_index = 0; ext_index < num_exts; ++ext_index) { - char const * const ext_name = reinterpret_cast(glGetStringi(GL_EXTENSIONS, ext_index)); - if (strcmp(name, ext_name) == 0) { - ext_ptr = glXGetProcAddressARB(reinterpret_cast(func)); - printf("[RK_ENGINE] Using extension %s::%s\n", name, func); - break; - } - } - return ext_ptr; -} - rk_window_t rk_initialize( - char const * name) { - rk_window_t const window = rk_create_context(name, GLX_CONTEXT_ES_PROFILE_BIT_EXT, 3, 2); + 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); @@ -75,15 +53,6 @@ rk_window_t rk_initialize( GLubyte const * const language = glGetString(GL_SHADING_LANGUAGE_VERSION); printf("[RK_ENGINE] version: %s, language: %s\n", version, language); - rk_DrawElementsInstancedBaseInstance = - reinterpret_cast( - rk_extension("GL_EXT_base_instance", "DrawElementsInstancedBaseInstance")); - if (rk_DrawElementsInstancedBaseInstance) { - rk_MultiDrawElementsIndirect = - reinterpret_cast( - rk_extension("GL_EXT_multi_draw_indirect", "MultiDrawElementsIndirectEXT")); - } - GLint context_flags = 0; glGetIntegerv(GL_CONTEXT_FLAGS, &context_flags); if (context_flags & GL_CONTEXT_FLAG_DEBUG_BIT) { diff --git a/cpp/render.hpp b/cpp/render.hpp index 6f22d48..4dbeb1d 100644 --- a/cpp/render.hpp +++ b/cpp/render.hpp @@ -99,7 +99,9 @@ union rk_mesh { }; RK_EXPORT rk_window_t rk_initialize( - char const * name); + char const * name, + rk_uint width, + rk_uint height); RK_EXPORT rk_shader_t rk_load_shader( char const * name);