|
|
|
@ -32,55 +32,6 @@ |
|
|
|
|
#include <assert.h> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Initialize WGL-specific extensions
|
|
|
|
|
//
|
|
|
|
|
static void loadExtensions(void) |
|
|
|
|
{ |
|
|
|
|
// Functions for WGL_EXT_extension_string
|
|
|
|
|
// NOTE: These are needed by _glfwPlatformExtensionSupported
|
|
|
|
|
_glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) |
|
|
|
|
wglGetProcAddress("wglGetExtensionsStringEXT"); |
|
|
|
|
_glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) |
|
|
|
|
wglGetProcAddress("wglGetExtensionsStringARB"); |
|
|
|
|
|
|
|
|
|
// Functions for WGL_ARB_create_context
|
|
|
|
|
_glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) |
|
|
|
|
wglGetProcAddress("wglCreateContextAttribsARB"); |
|
|
|
|
|
|
|
|
|
// Functions for WGL_EXT_swap_control
|
|
|
|
|
_glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) |
|
|
|
|
wglGetProcAddress("wglSwapIntervalEXT"); |
|
|
|
|
|
|
|
|
|
// Functions for WGL_ARB_pixel_format
|
|
|
|
|
_glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) |
|
|
|
|
wglGetProcAddress("wglGetPixelFormatAttribivARB"); |
|
|
|
|
|
|
|
|
|
// This needs to include every extension used below except for
|
|
|
|
|
// WGL_ARB_extensions_string and WGL_EXT_extensions_string
|
|
|
|
|
_glfw.wgl.ARB_multisample = |
|
|
|
|
_glfwPlatformExtensionSupported("WGL_ARB_multisample"); |
|
|
|
|
_glfw.wgl.ARB_framebuffer_sRGB = |
|
|
|
|
_glfwPlatformExtensionSupported("WGL_ARB_framebuffer_sRGB"); |
|
|
|
|
_glfw.wgl.EXT_framebuffer_sRGB = |
|
|
|
|
_glfwPlatformExtensionSupported("WGL_EXT_framebuffer_sRGB"); |
|
|
|
|
_glfw.wgl.ARB_create_context = |
|
|
|
|
_glfwPlatformExtensionSupported("WGL_ARB_create_context"); |
|
|
|
|
_glfw.wgl.ARB_create_context_profile = |
|
|
|
|
_glfwPlatformExtensionSupported("WGL_ARB_create_context_profile"); |
|
|
|
|
_glfw.wgl.EXT_create_context_es2_profile = |
|
|
|
|
_glfwPlatformExtensionSupported("WGL_EXT_create_context_es2_profile"); |
|
|
|
|
_glfw.wgl.ARB_create_context_robustness = |
|
|
|
|
_glfwPlatformExtensionSupported("WGL_ARB_create_context_robustness"); |
|
|
|
|
_glfw.wgl.EXT_swap_control = |
|
|
|
|
_glfwPlatformExtensionSupported("WGL_EXT_swap_control"); |
|
|
|
|
_glfw.wgl.ARB_pixel_format = |
|
|
|
|
_glfwPlatformExtensionSupported("WGL_ARB_pixel_format"); |
|
|
|
|
_glfw.wgl.ARB_context_flush_control = |
|
|
|
|
_glfwPlatformExtensionSupported("WGL_ARB_context_flush_control"); |
|
|
|
|
|
|
|
|
|
_glfw.wgl.extensionsLoaded = GLFW_TRUE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Returns the specified attribute of the specified pixel format
|
|
|
|
|
//
|
|
|
|
|
static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib) |
|
|
|
@ -280,6 +231,157 @@ static GLFWbool isCompositionEnabled(void) |
|
|
|
|
return enabled; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void makeContextCurrent(_GLFWwindow* window) |
|
|
|
|
{ |
|
|
|
|
if (window) |
|
|
|
|
{ |
|
|
|
|
if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle)) |
|
|
|
|
_glfwPlatformSetCurrentContext(window); |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
_glfwInputError(GLFW_PLATFORM_ERROR, |
|
|
|
|
"WGL: Failed to make context current"); |
|
|
|
|
_glfwPlatformSetCurrentContext(NULL); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
if (!wglMakeCurrent(NULL, NULL)) |
|
|
|
|
{ |
|
|
|
|
_glfwInputError(GLFW_PLATFORM_ERROR, |
|
|
|
|
"WGL: Failed to clear current context"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_glfwPlatformSetCurrentContext(NULL); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void swapBuffers(_GLFWwindow* window) |
|
|
|
|
{ |
|
|
|
|
// HACK: Use DwmFlush when desktop composition is enabled
|
|
|
|
|
if (isCompositionEnabled() && !window->monitor) |
|
|
|
|
{ |
|
|
|
|
int count = abs(window->context.wgl.interval); |
|
|
|
|
while (count--) |
|
|
|
|
_glfw_DwmFlush(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SwapBuffers(window->context.wgl.dc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void swapInterval(int interval) |
|
|
|
|
{ |
|
|
|
|
_GLFWwindow* window = _glfwPlatformGetCurrentContext(); |
|
|
|
|
|
|
|
|
|
window->context.wgl.interval = interval; |
|
|
|
|
|
|
|
|
|
// HACK: Disable WGL swap interval when desktop composition is enabled to
|
|
|
|
|
// avoid interfering with DWM vsync
|
|
|
|
|
if (isCompositionEnabled() && !window->monitor) |
|
|
|
|
interval = 0; |
|
|
|
|
|
|
|
|
|
if (_glfw.wgl.EXT_swap_control) |
|
|
|
|
_glfw.wgl.SwapIntervalEXT(interval); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int extensionSupported(const char* extension) |
|
|
|
|
{ |
|
|
|
|
const char* extensions; |
|
|
|
|
|
|
|
|
|
_GLFWwindow* window = _glfwPlatformGetCurrentContext(); |
|
|
|
|
|
|
|
|
|
if (_glfw.wgl.GetExtensionsStringEXT) |
|
|
|
|
{ |
|
|
|
|
extensions = _glfw.wgl.GetExtensionsStringEXT(); |
|
|
|
|
if (extensions) |
|
|
|
|
{ |
|
|
|
|
if (_glfwStringInExtensionString(extension, extensions)) |
|
|
|
|
return GLFW_TRUE; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (_glfw.wgl.GetExtensionsStringARB) |
|
|
|
|
{ |
|
|
|
|
extensions = _glfw.wgl.GetExtensionsStringARB(window->context.wgl.dc); |
|
|
|
|
if (extensions) |
|
|
|
|
{ |
|
|
|
|
if (_glfwStringInExtensionString(extension, extensions)) |
|
|
|
|
return GLFW_TRUE; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return GLFW_FALSE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static GLFWglproc getProcAddress(const char* procname) |
|
|
|
|
{ |
|
|
|
|
const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname); |
|
|
|
|
if (proc) |
|
|
|
|
return proc; |
|
|
|
|
|
|
|
|
|
return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Destroy the OpenGL context
|
|
|
|
|
//
|
|
|
|
|
static void destroyContext(_GLFWwindow* window) |
|
|
|
|
{ |
|
|
|
|
if (window->context.wgl.handle) |
|
|
|
|
{ |
|
|
|
|
wglDeleteContext(window->context.wgl.handle); |
|
|
|
|
window->context.wgl.handle = NULL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Initialize WGL-specific extensions
|
|
|
|
|
//
|
|
|
|
|
static void loadExtensions(void) |
|
|
|
|
{ |
|
|
|
|
// Functions for WGL_EXT_extension_string
|
|
|
|
|
// NOTE: These are needed by extensionSupported
|
|
|
|
|
_glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) |
|
|
|
|
wglGetProcAddress("wglGetExtensionsStringEXT"); |
|
|
|
|
_glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC) |
|
|
|
|
wglGetProcAddress("wglGetExtensionsStringARB"); |
|
|
|
|
|
|
|
|
|
// Functions for WGL_ARB_create_context
|
|
|
|
|
_glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) |
|
|
|
|
wglGetProcAddress("wglCreateContextAttribsARB"); |
|
|
|
|
|
|
|
|
|
// Functions for WGL_EXT_swap_control
|
|
|
|
|
_glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) |
|
|
|
|
wglGetProcAddress("wglSwapIntervalEXT"); |
|
|
|
|
|
|
|
|
|
// Functions for WGL_ARB_pixel_format
|
|
|
|
|
_glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC) |
|
|
|
|
wglGetProcAddress("wglGetPixelFormatAttribivARB"); |
|
|
|
|
|
|
|
|
|
// This needs to include every extension used below except for
|
|
|
|
|
// WGL_ARB_extensions_string and WGL_EXT_extensions_string
|
|
|
|
|
_glfw.wgl.ARB_multisample = |
|
|
|
|
extensionSupported("WGL_ARB_multisample"); |
|
|
|
|
_glfw.wgl.ARB_framebuffer_sRGB = |
|
|
|
|
extensionSupported("WGL_ARB_framebuffer_sRGB"); |
|
|
|
|
_glfw.wgl.EXT_framebuffer_sRGB = |
|
|
|
|
extensionSupported("WGL_EXT_framebuffer_sRGB"); |
|
|
|
|
_glfw.wgl.ARB_create_context = |
|
|
|
|
extensionSupported("WGL_ARB_create_context"); |
|
|
|
|
_glfw.wgl.ARB_create_context_profile = |
|
|
|
|
extensionSupported("WGL_ARB_create_context_profile"); |
|
|
|
|
_glfw.wgl.EXT_create_context_es2_profile = |
|
|
|
|
extensionSupported("WGL_EXT_create_context_es2_profile"); |
|
|
|
|
_glfw.wgl.ARB_create_context_robustness = |
|
|
|
|
extensionSupported("WGL_ARB_create_context_robustness"); |
|
|
|
|
_glfw.wgl.EXT_swap_control = |
|
|
|
|
extensionSupported("WGL_EXT_swap_control"); |
|
|
|
|
_glfw.wgl.ARB_pixel_format = |
|
|
|
|
extensionSupported("WGL_ARB_pixel_format"); |
|
|
|
|
_glfw.wgl.ARB_context_flush_control = |
|
|
|
|
extensionSupported("WGL_ARB_context_flush_control"); |
|
|
|
|
|
|
|
|
|
_glfw.wgl.extensionsLoaded = GLFW_TRUE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
////// GLFW internal API //////
|
|
|
|
@ -336,7 +438,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, |
|
|
|
|
PIXELFORMATDESCRIPTOR pfd; |
|
|
|
|
HGLRC share = NULL; |
|
|
|
|
|
|
|
|
|
if (ctxconfig->api == GLFW_NO_API) |
|
|
|
|
if (ctxconfig->client == GLFW_NO_API) |
|
|
|
|
return GLFW_TRUE; |
|
|
|
|
|
|
|
|
|
if (ctxconfig->share) |
|
|
|
@ -372,7 +474,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, |
|
|
|
|
{ |
|
|
|
|
int index = 0, mask = 0, flags = 0; |
|
|
|
|
|
|
|
|
|
if (ctxconfig->api == GLFW_OPENGL_API) |
|
|
|
|
if (ctxconfig->client == GLFW_OPENGL_API) |
|
|
|
|
{ |
|
|
|
|
if (ctxconfig->forward) |
|
|
|
|
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; |
|
|
|
@ -474,22 +576,18 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
window->context.makeContextCurrent = makeContextCurrent; |
|
|
|
|
window->context.swapBuffers = swapBuffers; |
|
|
|
|
window->context.swapInterval = swapInterval; |
|
|
|
|
window->context.extensionSupported = extensionSupported; |
|
|
|
|
window->context.getProcAddress = getProcAddress; |
|
|
|
|
window->context.destroyContext = destroyContext; |
|
|
|
|
|
|
|
|
|
return GLFW_TRUE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#undef setWGLattrib |
|
|
|
|
|
|
|
|
|
// Destroy the OpenGL context
|
|
|
|
|
//
|
|
|
|
|
void _glfwDestroyContextWGL(_GLFWwindow* window) |
|
|
|
|
{ |
|
|
|
|
if (window->context.wgl.handle) |
|
|
|
|
{ |
|
|
|
|
wglDeleteContext(window->context.wgl.handle); |
|
|
|
|
window->context.wgl.handle = NULL; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Analyzes the specified context for possible recreation
|
|
|
|
|
//
|
|
|
|
|
int _glfwAnalyzeContextWGL(_GLFWwindow* window, |
|
|
|
@ -501,10 +599,10 @@ int _glfwAnalyzeContextWGL(_GLFWwindow* window, |
|
|
|
|
if (_glfw.wgl.extensionsLoaded) |
|
|
|
|
return _GLFW_RECREATION_NOT_NEEDED; |
|
|
|
|
|
|
|
|
|
_glfwPlatformMakeContextCurrent(window); |
|
|
|
|
makeContextCurrent(window); |
|
|
|
|
loadExtensions(); |
|
|
|
|
|
|
|
|
|
if (ctxconfig->api == GLFW_OPENGL_API) |
|
|
|
|
if (ctxconfig->client == GLFW_OPENGL_API) |
|
|
|
|
{ |
|
|
|
|
if (ctxconfig->forward) |
|
|
|
|
{ |
|
|
|
@ -587,102 +685,6 @@ int _glfwAnalyzeContextWGL(_GLFWwindow* window, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
////// GLFW platform API //////
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) |
|
|
|
|
{ |
|
|
|
|
if (window) |
|
|
|
|
{ |
|
|
|
|
if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle)) |
|
|
|
|
_glfwPlatformSetCurrentContext(window); |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
_glfwInputError(GLFW_PLATFORM_ERROR, |
|
|
|
|
"WGL: Failed to make context current"); |
|
|
|
|
_glfwPlatformSetCurrentContext(NULL); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
if (!wglMakeCurrent(NULL, NULL)) |
|
|
|
|
{ |
|
|
|
|
_glfwInputError(GLFW_PLATFORM_ERROR, |
|
|
|
|
"WGL: Failed to clear current context"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_glfwPlatformSetCurrentContext(NULL); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void _glfwPlatformSwapBuffers(_GLFWwindow* window) |
|
|
|
|
{ |
|
|
|
|
// HACK: Use DwmFlush when desktop composition is enabled
|
|
|
|
|
if (isCompositionEnabled() && !window->monitor) |
|
|
|
|
{ |
|
|
|
|
int count = abs(window->context.wgl.interval); |
|
|
|
|
while (count--) |
|
|
|
|
_glfw_DwmFlush(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SwapBuffers(window->context.wgl.dc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void _glfwPlatformSwapInterval(int interval) |
|
|
|
|
{ |
|
|
|
|
_GLFWwindow* window = _glfwPlatformGetCurrentContext(); |
|
|
|
|
|
|
|
|
|
window->context.wgl.interval = interval; |
|
|
|
|
|
|
|
|
|
// HACK: Disable WGL swap interval when desktop composition is enabled to
|
|
|
|
|
// avoid interfering with DWM vsync
|
|
|
|
|
if (isCompositionEnabled() && !window->monitor) |
|
|
|
|
interval = 0; |
|
|
|
|
|
|
|
|
|
if (_glfw.wgl.EXT_swap_control) |
|
|
|
|
_glfw.wgl.SwapIntervalEXT(interval); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int _glfwPlatformExtensionSupported(const char* extension) |
|
|
|
|
{ |
|
|
|
|
const char* extensions; |
|
|
|
|
|
|
|
|
|
_GLFWwindow* window = _glfwPlatformGetCurrentContext(); |
|
|
|
|
|
|
|
|
|
if (_glfw.wgl.GetExtensionsStringEXT) |
|
|
|
|
{ |
|
|
|
|
extensions = _glfw.wgl.GetExtensionsStringEXT(); |
|
|
|
|
if (extensions) |
|
|
|
|
{ |
|
|
|
|
if (_glfwStringInExtensionString(extension, extensions)) |
|
|
|
|
return GLFW_TRUE; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (_glfw.wgl.GetExtensionsStringARB) |
|
|
|
|
{ |
|
|
|
|
extensions = _glfw.wgl.GetExtensionsStringARB(window->context.wgl.dc); |
|
|
|
|
if (extensions) |
|
|
|
|
{ |
|
|
|
|
if (_glfwStringInExtensionString(extension, extensions)) |
|
|
|
|
return GLFW_TRUE; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return GLFW_FALSE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
GLFWglproc _glfwPlatformGetProcAddress(const char* procname) |
|
|
|
|
{ |
|
|
|
|
const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname); |
|
|
|
|
if (proc) |
|
|
|
|
return proc; |
|
|
|
|
|
|
|
|
|
return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
////// GLFW native API //////
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
@ -692,7 +694,7 @@ GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle) |
|
|
|
|
_GLFWwindow* window = (_GLFWwindow*) handle; |
|
|
|
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL); |
|
|
|
|
|
|
|
|
|
if (window->context.api == GLFW_NO_API) |
|
|
|
|
if (window->context.client == GLFW_NO_API) |
|
|
|
|
{ |
|
|
|
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); |
|
|
|
|
return NULL; |
|
|
|
|