Fix linux compile errors and build the BuilderNative.so library

This commit is contained in:
Magnus Norddahl 2019-08-30 08:45:14 +02:00
parent 51fabae1e7
commit 3cd96fc788
8 changed files with 242 additions and 210 deletions

1
.gitignore vendored
View file

@ -27,3 +27,4 @@ obj
*.ipdb *.ipdb
/Source/Plugins/vpo_dll/Release /Source/Plugins/vpo_dll/Release
/Source/Core/*.user /Source/Core/*.user
/Build/BuilderNative.so

View file

@ -1,3 +1,4 @@
all: all:
msbuild -p:Configuration=Release BuilderMono.sln msbuild -p:Configuration=Release BuilderMono.sln
g++ -O2 --shared -o Build/BuilderNative.so -fPIC -I Source/Native Source/Native/*.cpp Source/Native/gl_load/*.c

View file

@ -32,7 +32,7 @@ namespace CodeImp.DoomBuilder.Rendering
{ {
public RenderDevice(RenderTargetControl rendertarget) public RenderDevice(RenderTargetControl rendertarget)
{ {
Handle = RenderDevice_New(rendertarget.Handle); Handle = RenderDevice_New(IntPtr.Zero, rendertarget.Handle);
if (Handle == IntPtr.Zero) if (Handle == IntPtr.Zero)
throw new Exception("RenderDevice_New failed"); throw new Exception("RenderDevice_New failed");
@ -333,7 +333,7 @@ namespace CodeImp.DoomBuilder.Rendering
IntPtr Handle; IntPtr Handle;
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr RenderDevice_New(IntPtr hwnd); static extern IntPtr RenderDevice_New(IntPtr display, IntPtr window);
[DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)]
static extern void RenderDevice_Delete(IntPtr handle); static extern void RenderDevice_Delete(IntPtr handle);

View file

@ -1,11 +1,12 @@
#include "Precomp.h" #include "Precomp.h"
#include "OpenGLContext.h" #include "OpenGLContext.h"
#include <CommCtrl.h>
#include <stdexcept> #include <stdexcept>
#ifdef WIN32 #ifdef WIN32
#include <CommCtrl.h>
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
@ -64,6 +65,49 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
class OpenGLContext : public IOpenGLContext
{
public:
OpenGLContext(void* window);
~OpenGLContext();
void MakeCurrent() override;
void ClearCurrent() override;
void SwapBuffers() override;
int GetWidth() const override;
int GetHeight() const override;
bool IsValid() const { return context != 0; }
private:
HWND window;
HDC dc;
HGLRC context;
};
class OpenGLCreationHelper
{
public:
OpenGLCreationHelper(HWND window);
~OpenGLCreationHelper();
HGLRC CreateContext(HDC hdc, int major_version, int minor_version, HGLRC share_context = 0);
private:
HWND window;
HDC hdc;
HWND query_window = 0;
HDC query_dc = 0;
HGLRC query_context = 0;
typedef HGLRC(WINAPI* ptr_wglCreateContextAttribsARB)(HDC, HGLRC, const int*);
typedef BOOL(WINAPI* ptr_wglGetPixelFormatAttribivEXT)(HDC, int, int, UINT, int*, int*);
typedef BOOL(WINAPI* ptr_wglGetPixelFormatAttribfvEXT)(HDC, int, int, UINT, int*, FLOAT*);
typedef BOOL(WINAPI* ptr_wglChoosePixelFormatEXT)(HDC, const int*, const FLOAT*, UINT, int*, UINT*);
};
class OpenGLLoadFunctions class OpenGLLoadFunctions
{ {
public: public:
@ -231,8 +275,152 @@ HGLRC OpenGLCreationHelper::CreateContext(HDC hdc, int major_version, int minor_
return opengl3_context; return opengl3_context;
} }
std::unique_ptr<IOpenGLContext> Create(void* disp, void* window)
{
auto ctx = std::make_unique<OpenGLContext>(window);
if (!ctx->IsValid()) return nullptr;
return ctx;
}
#else #else
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/glx.h>
#define GLFUNC
typedef GLXContext(*ptr_glXCreateContextAttribs)(::Display* dpy, GLXFBConfig config, GLXContext share_list, Bool direct, const int* attrib_list);
class GL_GLXFunctions
{
public:
typedef XVisualInfo* (GLFUNC* ptr_glXChooseVisual)(::Display* dpy, int screen, int* attrib_list);
typedef void (GLFUNC* ptr_glXCopyContext)(::Display* dpy, GLXContext src, GLXContext dst, unsigned long mask);
typedef GLXContext(GLFUNC* ptr_glXCreateContext)(::Display* dpy, XVisualInfo* vis, GLXContext share_list, Bool direct);
typedef GLXPixmap(GLFUNC* ptr_glXCreateGLXPixmap)(::Display* dpy, XVisualInfo* vis, Pixmap pixmap);
typedef void (GLFUNC* ptr_glXDestroyContext)(::Display* dpy, GLXContext ctx);
typedef void (GLFUNC* ptr_glXDestroyGLXPixmap)(::Display* dpy, GLXPixmap pix);
typedef int (GLFUNC* ptr_glXGetConfig)(::Display* dpy, XVisualInfo* vis, int attrib, int* value);
typedef GLXContext(GLFUNC* ptr_glXGetCurrentContext)(void);
typedef GLXDrawable(GLFUNC* ptr_glXGetCurrentDrawable)(void);
typedef Bool(GLFUNC* ptr_glXIsDirect)(::Display* dpy, GLXContext ctx);
typedef Bool(GLFUNC* ptr_glXMakeCurrent)(::Display* dpy, GLXDrawable drawable, GLXContext ctx);
typedef Bool(GLFUNC* ptr_glXQueryExtension)(::Display* dpy, int* error_base, int* event_base);
typedef Bool(GLFUNC* ptr_glXQueryVersion)(::Display* dpy, int* major, int* minor);
typedef void (GLFUNC* ptr_glXSwapBuffers)(::Display* dpy, GLXDrawable drawable);
typedef void (GLFUNC* ptr_glXUseXFont)(Font font, int first, int count, int list_base);
typedef void (GLFUNC* ptr_glXWaitGL)(void);
typedef void (GLFUNC* ptr_glXWaitX)(void);
typedef const char* (GLFUNC* ptr_glXGetClientString)(::Display* dpy, int name);
typedef const char* (GLFUNC* ptr_glXQueryServerString)(::Display* dpy, int screen, int name);
typedef const char* (GLFUNC* ptr_glXQueryExtensionsString)(::Display* dpy, int screen);
typedef ::Display* (GLFUNC* ptr_glXGetCurrentDisplay)(void);
typedef GLXFBConfig* (GLFUNC* ptr_glXChooseFBConfig)(::Display* dpy, int screen, const int* attrib_list, int* nelements);
typedef GLXContext(GLFUNC* ptr_glXCreateNewContext)(::Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
typedef GLXPbuffer(GLFUNC* ptr_glXCreatePbuffer)(::Display* dpy, GLXFBConfig config, const int* attrib_list);
typedef GLXPixmap(GLFUNC* ptr_glXCreatePixmap)(::Display* dpy, GLXFBConfig config, Pixmap pixmap, const int* attrib_list);
typedef GLXWindow(GLFUNC* ptr_glXCreateWindow)(::Display* dpy, GLXFBConfig config, Window win, const int* attrib_list);
typedef void (GLFUNC* ptr_glXDestroyPbuffer)(::Display* dpy, GLXPbuffer pbuf);
typedef void (GLFUNC* ptr_glXDestroyPixmap)(::Display* dpy, GLXPixmap pixmap);
typedef void (GLFUNC* ptr_glXDestroyWindow)(::Display* dpy, GLXWindow win);
typedef GLXDrawable(GLFUNC* ptr_glXGetCurrentReadDrawable)(void);
typedef int (GLFUNC* ptr_glXGetFBConfigAttrib)(::Display* dpy, GLXFBConfig config, int attribute, int* value);
typedef GLXFBConfig* (GLFUNC* ptr_glXGetFBConfigs)(::Display* dpy, int screen, int* nelements);
typedef void (GLFUNC* ptr_glXGetSelectedEvent)(::Display* dpy, GLXDrawable draw, unsigned long* event_mask);
typedef XVisualInfo* (GLFUNC* ptr_glXGetVisualFromFBConfig)(::Display* dpy, GLXFBConfig config);
typedef Bool(GLFUNC* ptr_glXMakeContextCurrent)(::Display* display, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
typedef int (GLFUNC* ptr_glXQueryContext)(::Display* dpy, GLXContext ctx, int attribute, int* value);
typedef void (GLFUNC* ptr_glXQueryDrawable)(::Display* dpy, GLXDrawable draw, int attribute, unsigned int* value);
typedef void (GLFUNC* ptr_glXSelectEvent)(::Display* dpy, GLXDrawable draw, unsigned long event_mask);
typedef __GLXextFuncPtr(GLFUNC* ptr_glXGetProcAddress) (const GLubyte*);
typedef void (*(GLFUNC* ptr_glXGetProcAddressARB)(const GLubyte* procName))(void);
public:
ptr_glXChooseVisual glXChooseVisual;
ptr_glXCopyContext glXCopyContext;
ptr_glXCreateContext glXCreateContext;
ptr_glXCreateGLXPixmap glXCreateGLXPixmap;
ptr_glXDestroyContext glXDestroyContext;
ptr_glXDestroyGLXPixmap glXDestroyGLXPixmap;
ptr_glXGetConfig glXGetConfig;
ptr_glXGetCurrentContext glXGetCurrentContext;
ptr_glXGetCurrentDrawable glXGetCurrentDrawable;
ptr_glXIsDirect glXIsDirect;
ptr_glXMakeCurrent glXMakeCurrent;
ptr_glXQueryExtension glXQueryExtension;
ptr_glXQueryVersion glXQueryVersion;
ptr_glXSwapBuffers glXSwapBuffers;
ptr_glXUseXFont glXUseXFont;
ptr_glXWaitGL glXWaitGL;
ptr_glXWaitX glXWaitX;
ptr_glXGetClientString glXGetClientString;
ptr_glXQueryServerString glXQueryServerString;
ptr_glXQueryExtensionsString glXQueryExtensionsString;
ptr_glXGetCurrentDisplay glXGetCurrentDisplay;
ptr_glXChooseFBConfig glXChooseFBConfig;
ptr_glXCreateNewContext glXCreateNewContext;
ptr_glXCreatePbuffer glXCreatePbuffer;
ptr_glXCreatePixmap glXCreatePixmap;
ptr_glXCreateWindow glXCreateWindow;
ptr_glXDestroyPbuffer glXDestroyPbuffer;
ptr_glXDestroyPixmap glXDestroyPixmap;
ptr_glXDestroyWindow glXDestroyWindow;
ptr_glXGetCurrentReadDrawable glXGetCurrentReadDrawable;
ptr_glXGetFBConfigAttrib glXGetFBConfigAttrib;
ptr_glXGetFBConfigs glXGetFBConfigs;
ptr_glXGetSelectedEvent glXGetSelectedEvent;
ptr_glXGetVisualFromFBConfig glXGetVisualFromFBConfig;
ptr_glXMakeContextCurrent glXMakeContextCurrent;
ptr_glXQueryContext glXQueryContext;
ptr_glXQueryDrawable glXQueryDrawable;
ptr_glXSelectEvent glXSelectEvent;
ptr_glXGetProcAddress glXGetProcAddress;
ptr_glXGetProcAddressARB glXGetProcAddressARB;
};
class OpenGLContext : public IOpenGLContext
{
public:
OpenGLContext(void* display, void* window);
~OpenGLContext();
void MakeCurrent() override;
void ClearCurrent() override;
void SwapBuffers() override;
int GetWidth() const override;
int GetHeight() const override;
bool IsValid() const { return opengl_context != 0; }
private:
void CreateContext();
::Display* disp = nullptr;
::Window window = 0;
GLXContext opengl_context = 0;
XVisualInfo* opengl_visual_info = nullptr;
GLXFBConfig fbconfig;
GL_GLXFunctions glx;
typedef void(ProcAddress)();
ProcAddress* get_proc_address(const char *function_name) const;
GLXContext create_context_glx_1_3(GLXContext shared_context);
void create_glx_1_3(::Display* disp);
bool is_glx_extension_supported(const char* ext_name);
int major_version = 3;
int minor_version = 2;
void* opengl_lib_handle = nullptr;
};
#include <cstdio> #include <cstdio>
#define GL_USE_DLOPEN // Using dlopen for linux by default #define GL_USE_DLOPEN // Using dlopen for linux by default
@ -271,7 +459,7 @@ OpenGLContext::~OpenGLContext()
if (opengl_context) if (opengl_context)
{ {
if (glx.glXGetCurrentContext() == opengl_context) if (glx.glXGetCurrentContext() == opengl_context)
OpenGL::set_active(nullptr); ClearCurrent();
if (disp) if (disp)
glx.glXDestroyContext(disp, opengl_context); glx.glXDestroyContext(disp, opengl_context);
@ -299,8 +487,8 @@ int OpenGLContext::GetWidth() const
{ {
::Window root_window; ::Window root_window;
int x, y; int x, y;
unsigned int width, height, border_width, border_height, depth; unsigned int width, height, border_width, depth;
Status result = XGetGeometry(disp, window, &root_window, &x, &y, &width, &height, &border_width, &border_height, &depth); Status result = XGetGeometry(disp, window, &root_window, &x, &y, &width, &height, &border_width, &depth);
return (result != 0) ? width: 0; return (result != 0) ? width: 0;
} }
@ -308,12 +496,12 @@ int OpenGLContext::GetHeight() const
{ {
::Window root_window; ::Window root_window;
int x, y; int x, y;
unsigned int width, height, border_width, border_height, depth; unsigned int width, height, border_width, depth;
Status result = XGetGeometry(disp, window, &root_window, &x, &y, &width, &height, &border_width, &border_height, &depth); Status result = XGetGeometry(disp, window, &root_window, &x, &y, &width, &height, &border_width, &depth);
return (result != 0) ? height : 0; return (result != 0) ? height : 0;
} }
ProcAddress* OpenGLContext::get_proc_address(const char *function_name) const OpenGLContext::ProcAddress* OpenGLContext::get_proc_address(const char *function_name) const
{ {
if (glx.glXGetProcAddressARB) if (glx.glXGetProcAddressARB)
return glx.glXGetProcAddressARB((GLubyte*)function_name); return glx.glXGetProcAddressARB((GLubyte*)function_name);
@ -621,4 +809,11 @@ GLXContext OpenGLContext::create_context_glx_1_3(GLXContext shared_context)
return context; return context;
} }
std::unique_ptr<IOpenGLContext> Create(void* disp, void* window)
{
auto ctx = std::make_unique<OpenGLContext>(disp, window);
if (!ctx->IsValid()) return nullptr;
return ctx;
}
#endif #endif

View file

@ -1,176 +1,18 @@
#pragma once #pragma once
#ifdef WIN32 #include <memory>
class OpenGLContext class IOpenGLContext
{ {
public: public:
OpenGLContext(void* window); virtual ~IOpenGLContext() = default;
~OpenGLContext();
void MakeCurrent(); virtual void MakeCurrent() = 0;
void ClearCurrent(); virtual void ClearCurrent() = 0;
void SwapBuffers(); virtual void SwapBuffers() = 0;
int GetWidth() const; virtual int GetWidth() const = 0;
int GetHeight() const; virtual int GetHeight() const = 0;
explicit operator bool() const { return context != 0; } static std::unique_ptr<IOpenGLContext> Create(void* disp, void* window);
private:
HWND window;
HDC dc;
HGLRC context;
}; };
class OpenGLCreationHelper
{
public:
OpenGLCreationHelper(HWND window);
~OpenGLCreationHelper();
HGLRC CreateContext(HDC hdc, int major_version, int minor_version, HGLRC share_context = 0);
private:
HWND window;
HDC hdc;
HWND query_window = 0;
HDC query_dc = 0;
HGLRC query_context = 0;
typedef HGLRC(WINAPI* ptr_wglCreateContextAttribsARB)(HDC, HGLRC, const int*);
typedef BOOL(WINAPI* ptr_wglGetPixelFormatAttribivEXT)(HDC, int, int, UINT, int*, int*);
typedef BOOL(WINAPI* ptr_wglGetPixelFormatAttribfvEXT)(HDC, int, int, UINT, int*, FLOAT*);
typedef BOOL(WINAPI* ptr_wglChoosePixelFormatEXT)(HDC, const int*, const FLOAT*, UINT, int*, UINT*);
};
#else
#include <X11/Xlib.h>
#include <X11/Xutil.h>
typedef GLXContext(*ptr_glXCreateContextAttribs)(::Display* dpy, GLXFBConfig config, GLXContext share_list, Bool direct, const int* attrib_list);
class GL_GLXFunctions
{
public:
typedef XVisualInfo* (GLFUNC* ptr_glXChooseVisual)(::Display* dpy, int screen, int* attrib_list);
typedef void (GLFUNC* ptr_glXCopyContext)(::Display* dpy, GLXContext src, GLXContext dst, unsigned long mask);
typedef GLXContext(GLFUNC* ptr_glXCreateContext)(::Display* dpy, XVisualInfo* vis, GLXContext share_list, Bool direct);
typedef GLXPixmap(GLFUNC* ptr_glXCreateGLXPixmap)(::Display* dpy, XVisualInfo* vis, Pixmap pixmap);
typedef void (GLFUNC* ptr_glXDestroyContext)(::Display* dpy, GLXContext ctx);
typedef void (GLFUNC* ptr_glXDestroyGLXPixmap)(::Display* dpy, GLXPixmap pix);
typedef int (GLFUNC* ptr_glXGetConfig)(::Display* dpy, XVisualInfo* vis, int attrib, int* value);
typedef GLXContext(GLFUNC* ptr_glXGetCurrentContext)(void);
typedef GLXDrawable(GLFUNC* ptr_glXGetCurrentDrawable)(void);
typedef Bool(GLFUNC* ptr_glXIsDirect)(::Display* dpy, GLXContext ctx);
typedef Bool(GLFUNC* ptr_glXMakeCurrent)(::Display* dpy, GLXDrawable drawable, GLXContext ctx);
typedef Bool(GLFUNC* ptr_glXQueryExtension)(::Display* dpy, int* error_base, int* event_base);
typedef Bool(GLFUNC* ptr_glXQueryVersion)(::Display* dpy, int* major, int* minor);
typedef void (GLFUNC* ptr_glXSwapBuffers)(::Display* dpy, GLXDrawable drawable);
typedef void (GLFUNC* ptr_glXUseXFont)(Font font, int first, int count, int list_base);
typedef void (GLFUNC* ptr_glXWaitGL)(void);
typedef void (GLFUNC* ptr_glXWaitX)(void);
typedef const char* (GLFUNC* ptr_glXGetClientString)(::Display* dpy, int name);
typedef const char* (GLFUNC* ptr_glXQueryServerString)(::Display* dpy, int screen, int name);
typedef const char* (GLFUNC* ptr_glXQueryExtensionsString)(::Display* dpy, int screen);
typedef ::Display* (GLFUNC* ptr_glXGetCurrentDisplay)(void);
typedef GLXFBConfig* (GLFUNC* ptr_glXChooseFBConfig)(::Display* dpy, int screen, const int* attrib_list, int* nelements);
typedef GLXContext(GLFUNC* ptr_glXCreateNewContext)(::Display* dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
typedef GLXPbuffer(GLFUNC* ptr_glXCreatePbuffer)(::Display* dpy, GLXFBConfig config, const int* attrib_list);
typedef GLXPixmap(GLFUNC* ptr_glXCreatePixmap)(::Display* dpy, GLXFBConfig config, Pixmap pixmap, const int* attrib_list);
typedef GLXWindow(GLFUNC* ptr_glXCreateWindow)(::Display* dpy, GLXFBConfig config, Window win, const int* attrib_list);
typedef void (GLFUNC* ptr_glXDestroyPbuffer)(::Display* dpy, GLXPbuffer pbuf);
typedef void (GLFUNC* ptr_glXDestroyPixmap)(::Display* dpy, GLXPixmap pixmap);
typedef void (GLFUNC* ptr_glXDestroyWindow)(::Display* dpy, GLXWindow win);
typedef GLXDrawable(GLFUNC* ptr_glXGetCurrentReadDrawable)(void);
typedef int (GLFUNC* ptr_glXGetFBConfigAttrib)(::Display* dpy, GLXFBConfig config, int attribute, int* value);
typedef GLXFBConfig* (GLFUNC* ptr_glXGetFBConfigs)(::Display* dpy, int screen, int* nelements);
typedef void (GLFUNC* ptr_glXGetSelectedEvent)(::Display* dpy, GLXDrawable draw, unsigned long* event_mask);
typedef XVisualInfo* (GLFUNC* ptr_glXGetVisualFromFBConfig)(::Display* dpy, GLXFBConfig config);
typedef Bool(GLFUNC* ptr_glXMakeContextCurrent)(::Display* display, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
typedef int (GLFUNC* ptr_glXQueryContext)(::Display* dpy, GLXContext ctx, int attribute, int* value);
typedef void (GLFUNC* ptr_glXQueryDrawable)(::Display* dpy, GLXDrawable draw, int attribute, unsigned int* value);
typedef void (GLFUNC* ptr_glXSelectEvent)(::Display* dpy, GLXDrawable draw, unsigned long event_mask);
typedef __GLXextFuncPtr(GLFUNC* ptr_glXGetProcAddress) (const GLubyte*);
typedef void (*(GLFUNC* ptr_glXGetProcAddressARB)(const GLubyte* procName))(void);
public:
ptr_glXChooseVisual glXChooseVisual;
ptr_glXCopyContext glXCopyContext;
ptr_glXCreateContext glXCreateContext;
ptr_glXCreateGLXPixmap glXCreateGLXPixmap;
ptr_glXDestroyContext glXDestroyContext;
ptr_glXDestroyGLXPixmap glXDestroyGLXPixmap;
ptr_glXGetConfig glXGetConfig;
ptr_glXGetCurrentContext glXGetCurrentContext;
ptr_glXGetCurrentDrawable glXGetCurrentDrawable;
ptr_glXIsDirect glXIsDirect;
ptr_glXMakeCurrent glXMakeCurrent;
ptr_glXQueryExtension glXQueryExtension;
ptr_glXQueryVersion glXQueryVersion;
ptr_glXSwapBuffers glXSwapBuffers;
ptr_glXUseXFont glXUseXFont;
ptr_glXWaitGL glXWaitGL;
ptr_glXWaitX glXWaitX;
ptr_glXGetClientString glXGetClientString;
ptr_glXQueryServerString glXQueryServerString;
ptr_glXQueryExtensionsString glXQueryExtensionsString;
ptr_glXGetCurrentDisplay glXGetCurrentDisplay;
ptr_glXChooseFBConfig glXChooseFBConfig;
ptr_glXCreateNewContext glXCreateNewContext;
ptr_glXCreatePbuffer glXCreatePbuffer;
ptr_glXCreatePixmap glXCreatePixmap;
ptr_glXCreateWindow glXCreateWindow;
ptr_glXDestroyPbuffer glXDestroyPbuffer;
ptr_glXDestroyPixmap glXDestroyPixmap;
ptr_glXDestroyWindow glXDestroyWindow;
ptr_glXGetCurrentReadDrawable glXGetCurrentReadDrawable;
ptr_glXGetFBConfigAttrib glXGetFBConfigAttrib;
ptr_glXGetFBConfigs glXGetFBConfigs;
ptr_glXGetSelectedEvent glXGetSelectedEvent;
ptr_glXGetVisualFromFBConfig glXGetVisualFromFBConfig;
ptr_glXMakeContextCurrent glXMakeContextCurrent;
ptr_glXQueryContext glXQueryContext;
ptr_glXQueryDrawable glXQueryDrawable;
ptr_glXSelectEvent glXSelectEvent;
ptr_glXGetProcAddress glXGetProcAddress;
ptr_glXGetProcAddressARB glXGetProcAddressARB;
};
class OpenGLContext
{
public:
OpenGLContext(void* display, void* window);
~OpenGLContext();
void Begin();
void End();
void SwapBuffers();
int GetWidth() const;
int GetHeight() const;
explicit operator bool() const { return opengl_context != 0; }
private:
void CreateContext();
::Display* disp = nullptr;
::Window window = 0;
GLXContext opengl_context = 0;
XVisualInfo* opengl_visual_info = nullptr;
GLXFBConfig fbconfig;
GL_GLXFunctions glx;
ProcAddress* get_proc_address(const char *function_name) const;
GLXContext create_context_glx_1_3(GLXContext shared_context);
void create_glx_1_3(::Display* disp);
};
#endif

View file

@ -7,17 +7,14 @@
#include "ShaderManager.h" #include "ShaderManager.h"
#include <stdexcept> #include <stdexcept>
#ifdef WIN32 RenderDevice::RenderDevice(void* disp, void* window)
RenderDevice::RenderDevice(void* hwnd) : Context(hwnd)
#else
RenderDevice::RenderDevice(void* disp, void* window) : Context(disp, window)
#endif
{ {
memset(mUniforms, 0, sizeof(mUniforms)); memset(mUniforms, 0, sizeof(mUniforms));
Context = IOpenGLContext::Create(disp, window);
if (Context) if (Context)
{ {
Context.MakeCurrent(); Context->MakeCurrent();
glGenVertexArrays(1, &mStreamVAO); glGenVertexArrays(1, &mStreamVAO);
glGenBuffers(1, &mStreamVertexBuffer); glGenBuffers(1, &mStreamVertexBuffer);
@ -29,7 +26,7 @@ RenderDevice::RenderDevice(void* disp, void* window) : Context(disp, window)
mShaderManager = std::make_unique<ShaderManager>(); mShaderManager = std::make_unique<ShaderManager>();
CheckError(); CheckError();
Context.ClearCurrent(); Context->ClearCurrent();
} }
} }
@ -37,11 +34,11 @@ RenderDevice::~RenderDevice()
{ {
if (Context) if (Context)
{ {
Context.MakeCurrent(); Context->MakeCurrent();
glDeleteBuffers(1, &mStreamVertexBuffer); glDeleteBuffers(1, &mStreamVertexBuffer);
glDeleteVertexArrays(1, &mStreamVAO); glDeleteVertexArrays(1, &mStreamVAO);
mShaderManager->ReleaseResources(); mShaderManager->ReleaseResources();
Context.ClearCurrent(); Context->ClearCurrent();
} }
} }
@ -260,7 +257,7 @@ void RenderDevice::DrawData(PrimitiveType type, int startIndex, int primitiveCou
void RenderDevice::StartRendering(bool clear, int backcolor, Texture* target, bool usedepthbuffer) void RenderDevice::StartRendering(bool clear, int backcolor, Texture* target, bool usedepthbuffer)
{ {
Context.MakeCurrent(); Context->MakeCurrent();
mContextIsCurrent = true; mContextIsCurrent = true;
if (target) if (target)
@ -271,7 +268,7 @@ void RenderDevice::StartRendering(bool clear, int backcolor, Texture* target, bo
else else
{ {
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, Context.GetWidth(), Context.GetHeight()); glViewport(0, 0, Context->GetWidth(), Context->GetHeight());
} }
if (clear && usedepthbuffer) if (clear && usedepthbuffer)
@ -302,13 +299,13 @@ void RenderDevice::StartRendering(bool clear, int backcolor, Texture* target, bo
void RenderDevice::FinishRendering() void RenderDevice::FinishRendering()
{ {
CheckError(); CheckError();
Context.ClearCurrent(); Context->ClearCurrent();
mContextIsCurrent = false; mContextIsCurrent = false;
} }
void RenderDevice::Present() void RenderDevice::Present()
{ {
Context.SwapBuffers(); Context->SwapBuffers();
} }
void RenderDevice::ClearTexture(int backcolor, Texture* texture) void RenderDevice::ClearTexture(int backcolor, Texture* texture)
@ -328,7 +325,7 @@ void RenderDevice::CopyTexture(Texture* dst, CubeMapFace face)
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
}; };
if (!mContextIsCurrent) Context.MakeCurrent(); if (!mContextIsCurrent) Context->MakeCurrent();
GLint oldTexture = 0; GLint oldTexture = 0;
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture); glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture);
@ -338,41 +335,41 @@ void RenderDevice::CopyTexture(Texture* dst, CubeMapFace face)
glGenerateMipmap(GL_TEXTURE_CUBE_MAP); glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture); glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture);
if (!mContextIsCurrent) Context.ClearCurrent(); if (!mContextIsCurrent) Context->ClearCurrent();
} }
void RenderDevice::SetVertexBufferData(VertexBuffer* buffer, void* data, int64_t size, VertexFormat format) void RenderDevice::SetVertexBufferData(VertexBuffer* buffer, void* data, int64_t size, VertexFormat format)
{ {
if (!mContextIsCurrent) Context.MakeCurrent(); if (!mContextIsCurrent) Context->MakeCurrent();
buffer->Format = format; buffer->Format = format;
GLint oldbinding = 0; GLint oldbinding = 0;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &oldbinding); glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &oldbinding);
glBindBuffer(GL_ARRAY_BUFFER, buffer->GetBuffer()); glBindBuffer(GL_ARRAY_BUFFER, buffer->GetBuffer());
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, oldbinding); glBindBuffer(GL_ARRAY_BUFFER, oldbinding);
if (!mContextIsCurrent) Context.ClearCurrent(); if (!mContextIsCurrent) Context->ClearCurrent();
} }
void RenderDevice::SetVertexBufferSubdata(VertexBuffer* buffer, int64_t destOffset, void* data, int64_t size) void RenderDevice::SetVertexBufferSubdata(VertexBuffer* buffer, int64_t destOffset, void* data, int64_t size)
{ {
if (!mContextIsCurrent) Context.MakeCurrent(); if (!mContextIsCurrent) Context->MakeCurrent();
GLint oldbinding = 0; GLint oldbinding = 0;
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &oldbinding); glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &oldbinding);
glBindBuffer(GL_ARRAY_BUFFER, buffer->GetBuffer()); glBindBuffer(GL_ARRAY_BUFFER, buffer->GetBuffer());
glBufferSubData(GL_ARRAY_BUFFER, destOffset, size, data); glBufferSubData(GL_ARRAY_BUFFER, destOffset, size, data);
glBindBuffer(GL_ARRAY_BUFFER, oldbinding); glBindBuffer(GL_ARRAY_BUFFER, oldbinding);
if (!mContextIsCurrent) Context.ClearCurrent(); if (!mContextIsCurrent) Context->ClearCurrent();
} }
void RenderDevice::SetIndexBufferData(IndexBuffer* buffer, void* data, int64_t size) void RenderDevice::SetIndexBufferData(IndexBuffer* buffer, void* data, int64_t size)
{ {
if (!mContextIsCurrent) Context.MakeCurrent(); if (!mContextIsCurrent) Context->MakeCurrent();
GLint oldbinding = 0; GLint oldbinding = 0;
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &oldbinding); glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &oldbinding);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->GetBuffer()); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->GetBuffer());
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oldbinding); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oldbinding);
if (!mContextIsCurrent) Context.ClearCurrent(); if (!mContextIsCurrent) Context->ClearCurrent();
} }
void RenderDevice::SetPixels(Texture* texture, const void* data) void RenderDevice::SetPixels(Texture* texture, const void* data)
@ -391,9 +388,9 @@ void RenderDevice::InvalidateTexture(Texture* texture)
{ {
if (texture->IsTextureCreated()) if (texture->IsTextureCreated())
{ {
if (!mContextIsCurrent) Context.MakeCurrent(); if (!mContextIsCurrent) Context->MakeCurrent();
texture->Invalidate(); texture->Invalidate();
if (!mContextIsCurrent) Context.ClearCurrent(); if (!mContextIsCurrent) Context->ClearCurrent();
mNeedApply = true; mNeedApply = true;
mTexturesChanged = true; mTexturesChanged = true;
} }
@ -621,9 +618,9 @@ void RenderDevice::ApplyTextures()
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
RenderDevice* RenderDevice_New(void* hwnd) RenderDevice* RenderDevice_New(void* disp, void* window)
{ {
RenderDevice *device = new RenderDevice(hwnd); RenderDevice *device = new RenderDevice(disp, window);
if (!device->Context) if (!device->Context)
{ {
delete device; delete device;

View file

@ -77,11 +77,7 @@ enum class UniformName : int
class RenderDevice class RenderDevice
{ {
public: public:
#ifdef WIN32
RenderDevice(void* hwnd);
#else
RenderDevice(void* disp, void* window); RenderDevice(void* disp, void* window);
#endif
~RenderDevice(); ~RenderDevice();
void SetShader(ShaderName name); void SetShader(ShaderName name);
@ -135,7 +131,7 @@ public:
GLint GetGLMinFilter(TextureFilter filter, TextureFilter mipfilter); GLint GetGLMinFilter(TextureFilter filter, TextureFilter mipfilter);
OpenGLContext Context; std::unique_ptr<IOpenGLContext> Context;
struct TextureUnit struct TextureUnit
{ {

View file

@ -3293,7 +3293,7 @@ static int Load_Version_4_5(void)
typedef int (*PFN_LOADFUNCPOINTERS)(void); typedef int (*PFN_LOADFUNCPOINTERS)(void);
typedef struct ogl_StrToExtMap_s typedef struct ogl_StrToExtMap_s
{ {
char *extensionName; const char *extensionName;
int *extensionVariable; int *extensionVariable;
PFN_LOADFUNCPOINTERS LoadExtension; PFN_LOADFUNCPOINTERS LoadExtension;
} ogl_StrToExtMap; } ogl_StrToExtMap;