User Contexts API with Win32 implementation.

This commit is contained in:
Doug Binks 2020-06-03 19:46:22 +01:00
parent e0c77f71f9
commit a08bfd9891
7 changed files with 179 additions and 1 deletions

View File

@ -1276,6 +1276,18 @@ typedef struct GLFWmonitor GLFWmonitor;
*/ */
typedef struct GLFWwindow GLFWwindow; typedef struct GLFWwindow GLFWwindow;
/*! @brief Opaque user OpenGL context object.
*
* Opaque user OpenGL context object.
*
* @see @ref user_gl_context
*
* @since Added in version 3.3.
*
* @ingroup window
*/
typedef struct GLFWusercontext GLFWusercontext;
/*! @brief Opaque cursor object. /*! @brief Opaque cursor object.
* *
* Opaque cursor object. * Opaque cursor object.
@ -5772,6 +5784,21 @@ GLFWAPI int glfwExtensionSupported(const char* extension);
*/ */
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname); GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname);
/*! @brief Create a new OpenGL user context for a window
*
*/
GLFWAPI GLFWusercontext* glfwCreateUserContext(GLFWwindow* window);
/*! @brief Delete an OpenGL user context
*
*/
GLFWAPI void glfwDestroyUserContext(GLFWusercontext* context);
/*! @brief Make an OpenGL user context
*
*/
GLFWAPI void glfwMakeUserContextCurrent(GLFWusercontext* context);
/*! @brief Returns whether the Vulkan loader and an ICD have been found. /*! @brief Returns whether the Vulkan loader and an ICD have been found.
* *
* This function returns whether the Vulkan loader and any minimally functional * This function returns whether the Vulkan loader and any minimally functional

View File

@ -758,3 +758,26 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
return window->context.getProcAddress(procname); return window->context.getProcAddress(procname);
} }
GLFWAPI GLFWusercontext* glfwCreateUserContext(GLFWwindow* handle)
{
_GLFWusercontext* context;
_GLFWwindow* window = (_GLFWwindow*)handle;
context = _glfwPlatformCreateUserContext(window);
return (GLFWusercontext*)context;
}
GLFWAPI void glfwDestroyUserContext(GLFWusercontext* handle)
{
_GLFWusercontext* context = (_GLFWusercontext*)handle;
_glfwPlatformDestroyUserContext(context);
}
GLFWAPI void glfwMakeUserContextCurrent(GLFWusercontext* handle)
{
_GLFWusercontext* context = (_GLFWusercontext*)handle;
_glfwPlatformMakeUserContextCurrent(context);
}

View File

@ -75,6 +75,7 @@ typedef struct _GLFWmapping _GLFWmapping;
typedef struct _GLFWjoystick _GLFWjoystick; typedef struct _GLFWjoystick _GLFWjoystick;
typedef struct _GLFWtls _GLFWtls; typedef struct _GLFWtls _GLFWtls;
typedef struct _GLFWmutex _GLFWmutex; typedef struct _GLFWmutex _GLFWmutex;
typedef struct _GLFWusercontext _GLFWusercontext;
typedef void (* _GLFWmakecontextcurrentfun)(_GLFWwindow*); typedef void (* _GLFWmakecontextcurrentfun)(_GLFWwindow*);
typedef void (* _GLFWswapbuffersfun)(_GLFWwindow*); typedef void (* _GLFWswapbuffersfun)(_GLFWwindow*);
@ -681,6 +682,11 @@ void _glfwPlatformWaitEvents(void);
void _glfwPlatformWaitEventsTimeout(double timeout); void _glfwPlatformWaitEventsTimeout(double timeout);
void _glfwPlatformPostEmptyEvent(void); void _glfwPlatformPostEmptyEvent(void);
_GLFWusercontext* _glfwPlatformCreateUserContext(_GLFWwindow* window);
void _glfwPlatformDestroyUserContext(_GLFWusercontext* context);
void _glfwPlatformMakeUserContextCurrent(_GLFWusercontext* context);
void _glfwPlatformGetRequiredInstanceExtensions(char** extensions); void _glfwPlatformGetRequiredInstanceExtensions(char** extensions);
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device, VkPhysicalDevice device,

View File

@ -776,6 +776,62 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
#undef setAttrib #undef setAttrib
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
_GLFWusercontext* _glfwPlatformCreateUserContext(_GLFWwindow* window)
{
_GLFWusercontext* context;
context = calloc(1, sizeof(_GLFWusercontext));
context->handle = wglCreateContext(window->context.wgl.dc);
context->window = window;
if (!context->handle)
{
_glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE,
"WGL: Failed to create user OpenGL context");
free(context);
return GLFW_FALSE;
}
if (!wglShareLists(window->context.wgl.handle,context->handle))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to enable sharing with window OpenGL context and user context");
free(context);
return GLFW_FALSE;
}
return context;
}
void _glfwPlatformDestroyUserContext(_GLFWusercontext* context)
{
wglDeleteContext(context->handle);
free(context);
}
void _glfwPlatformMakeUserContextCurrent(_GLFWusercontext* context)
{
if(context)
{
if(!wglMakeCurrent(context->window->context.wgl.dc,context->handle))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to set current user context");
}
}
else
{
if (!wglMakeCurrent(NULL, NULL))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to clear current context");
}
}
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW native API ////// ////// GLFW native API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View File

@ -151,6 +151,11 @@ typedef struct _GLFWlibraryWGL
} _GLFWlibraryWGL; } _GLFWlibraryWGL;
typedef struct _GLFWusercontext
{
_GLFWwindow* window;
HGLRC handle;
} _GLFWusercontext;
GLFWbool _glfwInitWGL(void); GLFWbool _glfwInitWGL(void);
void _glfwTerminateWGL(void); void _glfwTerminateWGL(void);

View File

@ -28,6 +28,7 @@ add_executable(iconify iconify.c ${GETOPT} ${GLAD_GL})
add_executable(monitors monitors.c ${GETOPT} ${GLAD_GL}) add_executable(monitors monitors.c ${GETOPT} ${GLAD_GL})
add_executable(reopen reopen.c ${GLAD_GL}) add_executable(reopen reopen.c ${GLAD_GL})
add_executable(cursor cursor.c ${GLAD_GL}) add_executable(cursor cursor.c ${GLAD_GL})
add_executable(usercontext usercontext.c ${GLAD_GL})
add_executable(empty WIN32 MACOSX_BUNDLE empty.c ${TINYCTHREAD} ${GLAD_GL}) add_executable(empty WIN32 MACOSX_BUNDLE empty.c ${TINYCTHREAD} ${GLAD_GL})
add_executable(gamma WIN32 MACOSX_BUNDLE gamma.c ${GLAD_GL}) add_executable(gamma WIN32 MACOSX_BUNDLE gamma.c ${GLAD_GL})
@ -52,7 +53,7 @@ endif()
set(GUI_ONLY_BINARIES empty gamma icon inputlag joysticks opacity tearing set(GUI_ONLY_BINARIES empty gamma icon inputlag joysticks opacity tearing
threads timeout title triangle-vulkan windows) threads timeout title triangle-vulkan windows)
set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen
cursor) cursor usercontext)
set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES set_target_properties(${GUI_ONLY_BINARIES} ${CONSOLE_BINARIES} PROPERTIES
C_STANDARD 99 C_STANDARD 99

60
tests/usercontext.c Normal file
View File

@ -0,0 +1,60 @@
#include <glad/gl.h>
#include <GLFW/glfw3.h>
int main(void)
{
GLFWwindow* window;
GLFWusercontext* usercontext;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "User Context", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
gladLoadGL(glfwGetProcAddress);
/* make a new context */
usercontext = glfwCreateUserContext(window);
if (!usercontext)
{
glfwTerminate();
return -1;
}
/* set the user context current */
glfwMakeContextCurrent(NULL);
glfwMakeUserContextCurrent(usercontext);
/* set the window context current */
glfwMakeUserContextCurrent(NULL);
glfwMakeContextCurrent(window);
glClearColor( 0.4f, 0.3f, 0.4f, 0.0f );
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwDestroyUserContext(usercontext);
glfwTerminate();
return 0;
}