Compare commits
2 Commits
33abfd834a
...
ed6c852102
Author | SHA1 | Date | |
---|---|---|---|
ed6c852102 | |||
919ba9291f |
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "../display.hpp"
|
#include "../display.hpp"
|
||||||
#include "display_glx.hpp"
|
#include "display_glx.hpp"
|
||||||
|
#include "../events/events_x11.hpp"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
@ -26,10 +27,8 @@ static bool rk_error_occured = false;
|
|||||||
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
|
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||||
typedef GLXContext (*rk_CreateContextAttribsFunc)(Display *, GLXFBConfig, GLXContext, Bool, int const *);
|
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[] = {
|
static int const rk_visual_attribs[] = {
|
||||||
|
GLX_CONFIG_CAVEAT, GLX_NONE,
|
||||||
GLX_X_RENDERABLE, True,
|
GLX_X_RENDERABLE, True,
|
||||||
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
||||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||||
@ -51,19 +50,24 @@ static int const rk_context_attribs[] = {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void rk_x11_printf(
|
||||||
|
char const * messsage) {
|
||||||
|
printf("[X11] %s\n", messsage);
|
||||||
|
}
|
||||||
|
|
||||||
static void rk_glx_printf(
|
static void rk_glx_printf(
|
||||||
char const * messsage) {
|
char const * messsage) {
|
||||||
printf("[GLX] %s\n", messsage);
|
printf("[GLX] %s\n", messsage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rk_extension_supported(
|
static bool rk_extension_supported(
|
||||||
char const * extlist,
|
char const * extensions,
|
||||||
char const * extension) {
|
char const * extension) {
|
||||||
char const * where = strchr(extension, ' ');
|
char const * where = strchr(extension, ' ');
|
||||||
if (where || *extension == '\0') {
|
if (where || *extension == '\0') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (char const * start = extlist;;) {
|
for (char const * start = extensions;;) {
|
||||||
where = strstr(start, extension);
|
where = strstr(start, extension);
|
||||||
if (!where) {
|
if (!where) {
|
||||||
break;
|
break;
|
||||||
@ -77,6 +81,24 @@ static bool rk_extension_supported(
|
|||||||
return false;
|
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<GLubyte const *>(fn));
|
||||||
|
if (!ptr) {
|
||||||
|
printf("[GLX] Function %s::%s not found\n", extension, fn);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
static int rk_error_handler(
|
static int rk_error_handler(
|
||||||
Display * display,
|
Display * display,
|
||||||
XErrorEvent * event) {
|
XErrorEvent * event) {
|
||||||
@ -97,7 +119,7 @@ rk_display_t rk_create_display(
|
|||||||
display->colormap = 0;
|
display->colormap = 0;
|
||||||
display->context = nullptr;
|
display->context = nullptr;
|
||||||
if (!display->display) {
|
if (!display->display) {
|
||||||
rk_glx_printf("Failed to open X display.");
|
rk_x11_printf("Failed to open X display.");
|
||||||
rk_destroy_display(reinterpret_cast<rk_display_t>(display));
|
rk_destroy_display(reinterpret_cast<rk_display_t>(display));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -109,45 +131,43 @@ rk_display_t rk_create_display(
|
|||||||
rk_destroy_display(reinterpret_cast<rk_display_t>(display));
|
rk_destroy_display(reinterpret_cast<rk_display_t>(display));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
char const * const glx_exts = glXQueryExtensionsString(display->display, DefaultScreen(display->display));
|
char const * const glx_exts = glXQueryExtensionsString(display->display, DefaultScreen(display->display));
|
||||||
// rk_glx_printf(glx_exts);
|
// rk_glx_printf(glx_exts);
|
||||||
|
rk_CreateContextAttribsFunc const glXCreateContextAttribs = reinterpret_cast<rk_CreateContextAttribsFunc>(
|
||||||
|
rk_resolve_extension(glx_exts, "GLX_ARB_create_context", "glXCreateContextAttribsARB"));
|
||||||
|
if (!glXCreateContextAttribs) {
|
||||||
|
rk_destroy_display(reinterpret_cast<rk_display_t>(display));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
int fbcount;
|
int fb_count = 0;
|
||||||
GLXFBConfig * const fbc = glXChooseFBConfig(
|
GLXFBConfig * const fb_configs = glXChooseFBConfig(
|
||||||
display->display, DefaultScreen(display->display), rk_visual_attribs, &fbcount);
|
display->display, DefaultScreen(display->display), rk_visual_attribs, &fb_count);
|
||||||
if (!fbc) {
|
printf("[GLX] Found %d framebuffer configs.\n", fb_count);
|
||||||
|
if (!fb_configs || !fb_count) {
|
||||||
rk_glx_printf("Failed to retrieve framebuffer configs.");
|
rk_glx_printf("Failed to retrieve framebuffer configs.");
|
||||||
rk_destroy_display(reinterpret_cast<rk_display_t>(display));
|
rk_destroy_display(reinterpret_cast<rk_display_t>(display));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
printf("[GLX] Found %d framebuffer configs.\n", fbcount);
|
GLXFBConfig const fb_config = fb_configs[0];
|
||||||
|
XFree(fb_configs);
|
||||||
|
int red_size = 0;
|
||||||
|
glXGetFBConfigAttrib(display->display, fb_config, GLX_RED_SIZE, &red_size);
|
||||||
|
int green_size = 0;
|
||||||
|
glXGetFBConfigAttrib(display->display, fb_config, GLX_GREEN_SIZE, &green_size);
|
||||||
|
int blue_size = 0;
|
||||||
|
glXGetFBConfigAttrib(display->display, fb_config, GLX_BLUE_SIZE, &blue_size);
|
||||||
|
int alpha_size = 0;
|
||||||
|
glXGetFBConfigAttrib(display->display, fb_config, GLX_ALPHA_SIZE, &alpha_size);
|
||||||
|
int depth_size = 0;
|
||||||
|
glXGetFBConfigAttrib(display->display, fb_config, GLX_DEPTH_SIZE, &depth_size);
|
||||||
|
int stencil_size = 0;
|
||||||
|
glXGetFBConfigAttrib(display->display, fb_config, GLX_STENCIL_SIZE, &stencil_size);
|
||||||
|
printf("[GLX] Select framebuffer config R%dG%dB%dA%d D%dS%d.\n",
|
||||||
|
red_size, green_size, blue_size, alpha_size, depth_size, stencil_size);
|
||||||
|
|
||||||
int best_fbc = -1;
|
XVisualInfo * const vi = glXGetVisualFromFBConfig(display->display, fb_config);
|
||||||
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<rk_display_t>(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->colormap = XCreateColormap(
|
||||||
display->display, RootWindow(display->display, vi->screen), vi->visual, AllocNone);
|
display->display, RootWindow(display->display, vi->screen), vi->visual, AllocNone);
|
||||||
XSetWindowAttributes swa;
|
XSetWindowAttributes swa;
|
||||||
@ -157,25 +177,16 @@ rk_display_t rk_create_display(
|
|||||||
0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa);
|
0, 0, width, height, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa);
|
||||||
XFree(vi);
|
XFree(vi);
|
||||||
if (!display->window) {
|
if (!display->window) {
|
||||||
rk_glx_printf("Failed to create window.");
|
rk_x11_printf("Failed to create window.");
|
||||||
rk_destroy_display(reinterpret_cast<rk_display_t>(display));
|
rk_destroy_display(reinterpret_cast<rk_display_t>(display));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
XStoreName(display->display, display->window, name);
|
XStoreName(display->display, display->window, name);
|
||||||
XMapWindow(display->display, display->window);
|
XMapWindow(display->display, display->window);
|
||||||
|
|
||||||
rk_CreateContextAttribsFunc const glXCreateContextAttribs =
|
|
||||||
reinterpret_cast<rk_CreateContextAttribsFunc>(
|
|
||||||
glXGetProcAddressARB(reinterpret_cast<GLubyte const *>("glXCreateContextAttribsARB")));
|
|
||||||
|
|
||||||
if (!rk_extension_supported(glx_exts, "GLX_ARB_create_context") || !glXCreateContextAttribs) {
|
|
||||||
rk_glx_printf("glXCreateContextAttribsARB extension not found.");
|
|
||||||
rk_destroy_display(reinterpret_cast<rk_display_t>(display));
|
|
||||||
return nullptr;
|
|
||||||
} else {
|
|
||||||
rk_error_occured = false;
|
rk_error_occured = false;
|
||||||
int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&rk_error_handler);
|
int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&rk_error_handler);
|
||||||
display->context = glXCreateContextAttribs(display->display, bestFbc, 0, True, rk_context_attribs);
|
display->context = glXCreateContextAttribs(display->display, fb_config, 0, True, rk_context_attribs);
|
||||||
XSync(display->display, False);
|
XSync(display->display, False);
|
||||||
XSetErrorHandler(oldHandler);
|
XSetErrorHandler(oldHandler);
|
||||||
if (rk_error_occured || !display->context) {
|
if (rk_error_occured || !display->context) {
|
||||||
@ -183,32 +194,12 @@ rk_display_t rk_create_display(
|
|||||||
rk_destroy_display(reinterpret_cast<rk_display_t>(display));
|
rk_destroy_display(reinterpret_cast<rk_display_t>(display));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!glXIsDirect(display->display, display->context)) {
|
if (!glXIsDirect(display->display, display->context)) {
|
||||||
rk_glx_printf("Warning: Rendering context is indirect.");
|
rk_glx_printf("Warning: Rendering context is indirect.");
|
||||||
}
|
}
|
||||||
glXMakeCurrent(display->display, display->window, display->context);
|
glXMakeCurrent(display->display, display->window, display->context);
|
||||||
|
|
||||||
char const * const gl_exts = reinterpret_cast<char const *>(glGetString(GL_EXTENSIONS));
|
|
||||||
// printf("[GL] %s\n", gl_exts);
|
|
||||||
if (rk_extension_supported(gl_exts, "GL_EXT_base_instance")) {
|
|
||||||
rk_DrawElementsInstancedBaseInstance =
|
|
||||||
reinterpret_cast<rk_DrawElementsInstancedBaseInstanceFunc>(
|
|
||||||
glXGetProcAddressARB(reinterpret_cast<GLubyte const *>("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<rk_MultiDrawElementsIndirectFunc>(
|
|
||||||
glXGetProcAddressARB(reinterpret_cast<GLubyte const *>("MultiDrawElementsIndirectEXT")));
|
|
||||||
if (rk_MultiDrawElementsIndirect) {
|
|
||||||
rk_glx_printf("Using extension GL_EXT_multi_draw_indirect::MultiDrawElementsIndirectEXT.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return reinterpret_cast<rk_display_t>(display);
|
return reinterpret_cast<rk_display_t>(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,17 +18,17 @@
|
|||||||
|
|
||||||
#include "../types.hpp"
|
#include "../types.hpp"
|
||||||
#include "display_x11.hpp"
|
#include "display_x11.hpp"
|
||||||
#include "../events/events_x11.hpp"
|
|
||||||
#include <GL/glx.h>
|
#include <GL/glx.h>
|
||||||
|
|
||||||
struct rk_display_glx : public rk_display_x11 {
|
struct rk_display_glx : public rk_display_x11 {
|
||||||
GLXContext context;
|
GLXContext context;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*rk_DrawElementsInstancedBaseInstanceFunc)(rk_uint, rk_uint, rk_uint, const void *, rk_uint, rk_uint);
|
typedef void (*rk_func_ptr)();
|
||||||
typedef void (*rk_MultiDrawElementsIndirectFunc)(rk_uint, rk_uint, const void *, rk_uint, rk_uint);
|
|
||||||
|
|
||||||
extern rk_DrawElementsInstancedBaseInstanceFunc rk_DrawElementsInstancedBaseInstance;
|
extern rk_func_ptr rk_resolve_extension(
|
||||||
extern rk_MultiDrawElementsIndirectFunc rk_MultiDrawElementsIndirect;
|
char const * extensions,
|
||||||
|
char const * extension,
|
||||||
|
char const * fn);
|
||||||
|
|
||||||
#endif // _RK_ENGINE_DISPLAY_GLX_H
|
#endif // _RK_ENGINE_DISPLAY_GLX_H
|
||||||
|
@ -19,9 +19,19 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
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_shader const * rk_current_shader = nullptr;
|
||||||
static rk_vertices const * rk_current_vertices = 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) {
|
static void rk_printf(char const * message) {
|
||||||
printf("[RK] %s\n", message);
|
printf("[RK] %s\n", message);
|
||||||
}
|
}
|
||||||
@ -42,14 +52,27 @@ static void rk_debug_message_callback(
|
|||||||
void rk_render_initialize() {
|
void rk_render_initialize() {
|
||||||
GLubyte const * const vendor = glGetString(GL_VENDOR);
|
GLubyte const * const vendor = glGetString(GL_VENDOR);
|
||||||
GLubyte const * const renderer = glGetString(GL_RENDERER);
|
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 version = glGetString(GL_VERSION);
|
||||||
GLubyte const * const language = glGetString(GL_SHADING_LANGUAGE_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);
|
glDebugMessageCallback(rk_debug_message_callback, nullptr);
|
||||||
glEnable(GL_DEBUG_OUTPUT);
|
glEnable(GL_DEBUG_OUTPUT);
|
||||||
|
|
||||||
|
char const * const gl_exts = reinterpret_cast<char const *>(glGetString(GL_EXTENSIONS));
|
||||||
|
// printf("[GL] %s\n", gl_exts);
|
||||||
|
rk_DrawElementsInstancedBaseInstance = reinterpret_cast<rk_DrawElementsInstancedBaseInstanceFunc>(
|
||||||
|
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_MultiDrawElementsIndirectFunc>(
|
||||||
|
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);
|
glDisable(GL_BLEND);
|
||||||
glEnable(GL_DITHER);
|
glEnable(GL_DITHER);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
Loading…
Reference in New Issue
Block a user