Improve compatability.
Some checks failed
Run ReCI Build Test / Explore-Gitea-Actions (push) Failing after 1m18s

Resolve functions we use for OpenGL at runtime so if your PC doesn't support that renderer you could still use a different one.
This commit is contained in:
2025-01-26 01:37:17 -05:00
parent 1062b471b2
commit a627b22ecb
4 changed files with 66 additions and 18 deletions

View File

@@ -27,12 +27,9 @@ CPMAddPackage(
)
#TODO dlopen these at runtime so if one isn't supported the program still works.
find_package(OpenGL REQUIRED)
find_package(Vulkan REQUIRED)
include_directories(${OPENGL_INCLUDE_DIRS})
include_directories(${Vulkan_INCLUDE_DIR})
include_directories(${J3ML_SOURCE_DIR}/include)
include_directories(${jlog_SOURCE_DIR}/include)
@@ -66,7 +63,7 @@ target_include_directories(ReWindow PUBLIC ${Event_SOURCE_DIR}/include)
set_target_properties(ReWindow PROPERTIES LINKER_LANGUAGE CXX)
if(UNIX AND NOT APPLE)
target_link_libraries(ReWindow PUBLIC X11 Event jlog ${OPENGL_LIBRARIES} Vulkan::Vulkan)
target_link_libraries(ReWindow PUBLIC X11 Event jlog Vulkan::Vulkan)
target_link_libraries(ReWindow PUBLIC)
add_executable(ReWindowDemo main.cpp)

View File

@@ -354,7 +354,7 @@ public:
std::string GetGraphicsDriverVendor() override;
void Open() override;
public:
OpenGLWindow(const std::string& title, int width, int height, uint8_t gl_major, uint8_t gl_minor) : gl_major(gl_major), gl_minor(gl_minor), RWindow(title, width, height) {};
OpenGLWindow(const std::string& title, int width, int height, uint8_t gl_major, uint8_t gl_minor);
};
class ReWindow::VulkanWindow : public RWindow {

View File

@@ -5,7 +5,6 @@
#include <windows.h>
#endif
#include <GL/gl.h>
#include <ReWindow/Logger.h>
using namespace ReWindow;
@@ -22,8 +21,6 @@ class MyWindow : public OpenGLWindow {
void OnKeyDown(const KeyDownEvent& e) override {}
void OnRefresh(float elapsed) override {
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
SwapBuffers();
if (IsMouseButtonDown(MouseButtons::Left))

View File

@@ -1,25 +1,52 @@
#include <ReWindow/types/Window.h>
#include <ReWindow/Logger.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <dlfcn.h>
using namespace ReWindow;
void* glx_lib = nullptr;
void* opengl_lib = nullptr;
typedef const GLubyte* (*glGetString_t)(GLenum name);
glGetString_t func_glGetString = nullptr;
typedef Bool (*glXMakeCurrent_t)(Display *dpy, GLXDrawable drawable, GLXContext ctx);
glXMakeCurrent_t func_glXMakeCurrent = nullptr;
typedef void* (*glXGetProcAddressARB_t)(const GLubyte *procname);
glXGetProcAddressARB_t func_glXGetProcAddressARB = nullptr;
typedef void (*glXSwapBuffers_t)(Display *dpy, GLXDrawable drawable);
glXSwapBuffers_t func_glXSwapBuffers = nullptr;
typedef GLXContext (*glXCreateContext_t)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct);
glXCreateContext_t func_glXCreateContext = nullptr;
typedef GLXFBConfig *(*glXChooseFBConfig_t)(Display *dpy, int screen, const int *attribList, int *nItems);
glXChooseFBConfig_t func_glXChooseFBConfig = nullptr;
typedef XVisualInfo* (*glXGetVisualFromFBConfig_t)(Display *dpy, GLXFBConfig config);
glXGetVisualFromFBConfig_t func_glXGetVisualFromFBConfig = nullptr;
typedef XVisualInfo* (*glXChooseVisual_t)(Display *dpy, int screen, const int *attribList);
glXChooseVisual_t func_glXChooseVisual = nullptr;
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
GLXContext gl_context;
void OpenGLWindow::SwapBuffers() {
glXSwapBuffers(xVars.display,xVars.window);
func_glXSwapBuffers(xVars.display,xVars.window);
}
void OpenGLWindow::SetVsyncEnabled(bool state) {
PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT;
glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) glXGetProcAddressARB((const GLubyte *) "glXSwapIntervalEXT");
glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) func_glXGetProcAddressARB((const GLubyte *) "glXSwapIntervalEXT");
glXSwapIntervalEXT(xVars.display, xVars.window, state);
}
std::string OpenGLWindow::GetGraphicsDriverVendor() {
return std::string(reinterpret_cast<const char*>(glGetString(GL_VENDOR)));
return std::string((const char*) func_glGetString(GL_VENDOR));
}
void OpenGLWindow::Open() {
@@ -31,14 +58,14 @@ void OpenGLWindow::Open() {
xVars.xSetWindowAttributes.override_redirect = True;
xVars.xSetWindowAttributes.event_mask = ExposureMask;
auto glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB");
auto glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)func_glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB");
XVisualInfo* vi = nullptr;
// Fallback to the old way if you somehow don't have this.
if (!glXCreateContextAttribsARB) {
GLint glAttributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None};
xVars.visual = glXChooseVisual(xVars.display, xVars.defaultScreen, glAttributes);
gl_context = glXCreateContext(xVars.display, xVars.visual, nullptr, GL_TRUE);
xVars.visual = func_glXChooseVisual(xVars.display, xVars.defaultScreen, glAttributes);
gl_context = func_glXCreateContext(xVars.display, xVars.visual, nullptr, GL_TRUE);
xVars.window = XCreateWindow(xVars.display, RootWindow(xVars.display, xVars.defaultScreen), 0, 0, width, height, 0, xVars.visual->depth,
InputOutput, xVars.visual->visual, CWBackPixel | CWColormap | CWBorderPixel | NoEventMask, &xVars.xSetWindowAttributes);
ReWindow::Logger::Debug("Created OpenGL Context with glXCreateContext.");
@@ -54,12 +81,12 @@ void OpenGLWindow::Open() {
};
int fb_count;
GLXFBConfig *fb_configurations = glXChooseFBConfig(xVars.display, xVars.defaultScreen, visual_attributes, &fb_count);
GLXFBConfig* fb_configurations = func_glXChooseFBConfig(xVars.display, xVars.defaultScreen, visual_attributes, &fb_count);
if (!fb_configurations || fb_count == 0)
throw std::runtime_error("Couldn't get framebuffer configuration.");
GLXFBConfig best_fbc = fb_configurations[0];
vi = glXGetVisualFromFBConfig(xVars.display, best_fbc);
vi = func_glXGetVisualFromFBConfig(xVars.display, best_fbc);
if (!vi)
throw std::runtime_error("Couldn't visual info from framebuffer configuration.");
@@ -77,7 +104,7 @@ void OpenGLWindow::Open() {
if (!gl_context)
throw std::runtime_error("Couldn't create the OpenGL context.");
if (!glXMakeCurrent(xVars.display, xVars.window, gl_context))
if (!func_glXMakeCurrent(xVars.display, xVars.window, gl_context))
throw std::runtime_error("Couldn't change OpenGL context to current.");
if (vi)
@@ -102,3 +129,30 @@ void OpenGLWindow::Open() {
open = true;
processOnOpen();
}
OpenGLWindow::OpenGLWindow(const std::string& title, int width, int height, uint8_t gl_major, uint8_t gl_minor)
: gl_major(gl_major), gl_minor(gl_minor), RWindow(title, width, height) {
// Try this first so that in the event we have more than one window we don't double-load the library.
glx_lib = dlopen("libGLX.so", RTLD_NOLOAD);
opengl_lib = dlopen("libOpenGL.so", RTLD_NOLOAD);
if (!glx_lib)
glx_lib = dlopen("libGLX.so", RTLD_LAZY);
if (!opengl_lib)
opengl_lib = dlopen("libOpenGL.so", RTLD_LAZY);
if (!opengl_lib)
throw std::runtime_error("libOpenGL.so couldn't be found in your LD_LIBRARY_PATH.");
if (!glx_lib)
throw std::runtime_error("libGLX.so couldn't be found in your LD_LIBRARY_PATH.");
func_glGetString = (glGetString_t) dlsym(opengl_lib, "glGetString");
func_glXMakeCurrent = (glXMakeCurrent_t) dlsym(glx_lib, "glXMakeCurrent");
func_glXGetProcAddressARB = (glXGetProcAddressARB_t) dlsym(glx_lib, "glXGetProcAddressARB");
func_glXSwapBuffers = (glXSwapBuffers_t) dlsym(glx_lib, "glXSwapBuffers");
func_glXCreateContext = (glXCreateContext_t) dlsym(glx_lib, "glXCreateContext");
func_glXChooseFBConfig = (glXChooseFBConfig_t) dlsym(glx_lib, "glXChooseFBConfig");
func_glXGetVisualFromFBConfig = (glXGetVisualFromFBConfig_t) dlsym(glx_lib, "glXGetVisualFromFBConfig");
func_glXChooseVisual = (glXChooseVisual_t) dlsym(glx_lib, "glXChooseVisual");
}