mirror of
https://github.com/glfw/glfw.git
synced 2024-11-10 00:51:47 +00:00
parent
9d50a346f0
commit
ef80beab81
@ -35,13 +35,11 @@ if (APPLE)
|
||||
option(GLFW_USE_CHDIR "Make glfwInit chdir to Contents/Resources" ON)
|
||||
option(GLFW_USE_MENUBAR "Populate the menu bar on first window creation" ON)
|
||||
option(GLFW_USE_RETINA "Use the full resolution of Retina displays" ON)
|
||||
else()
|
||||
option(GLFW_USE_EGL "Use EGL for context creation" OFF)
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
option(GLFW_USE_WAYLAND "Use Wayland for context creation (implies EGL as well)" OFF)
|
||||
option(GLFW_USE_MIR "Use Mir for context creation (implies EGL as well)" OFF)
|
||||
option(GLFW_USE_WAYLAND "Use Wayland for window creation" OFF)
|
||||
option(GLFW_USE_MIR "Use Mir for window creation" OFF)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
@ -59,12 +57,6 @@ else()
|
||||
set(GLFW_LIB_NAME glfw3)
|
||||
endif()
|
||||
|
||||
if (GLFW_USE_WAYLAND)
|
||||
set(GLFW_USE_EGL ON)
|
||||
elseif (GLFW_USE_MIR)
|
||||
set(GLFW_USE_EGL ON)
|
||||
endif()
|
||||
|
||||
set(CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
@ -129,19 +121,9 @@ endif()
|
||||
if (WIN32)
|
||||
set(_GLFW_WIN32 1)
|
||||
message(STATUS "Using Win32 for window creation")
|
||||
|
||||
if (GLFW_USE_EGL)
|
||||
set(_GLFW_EGL 1)
|
||||
message(STATUS "Using EGL for context creation")
|
||||
else()
|
||||
set(_GLFW_WGL 1)
|
||||
message(STATUS "Using WGL for context creation")
|
||||
endif()
|
||||
elseif (APPLE)
|
||||
set(_GLFW_COCOA 1)
|
||||
message(STATUS "Using Cocoa for window creation")
|
||||
set(_GLFW_NSGL 1)
|
||||
message(STATUS "Using NSGL for context creation")
|
||||
elseif (UNIX)
|
||||
if (GLFW_USE_WAYLAND)
|
||||
set(_GLFW_WAYLAND 1)
|
||||
@ -153,14 +135,6 @@ elseif (UNIX)
|
||||
set(_GLFW_X11 1)
|
||||
message(STATUS "Using X11 for window creation")
|
||||
endif()
|
||||
|
||||
if (GLFW_USE_EGL)
|
||||
set(_GLFW_EGL 1)
|
||||
message(STATUS "Using EGL for context creation")
|
||||
else()
|
||||
set(_GLFW_GLX 1)
|
||||
message(STATUS "Using GLX for context creation")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "No supported platform was detected")
|
||||
endif()
|
||||
@ -306,7 +280,7 @@ endif()
|
||||
#--------------------------------------------------------------------
|
||||
# Use Cocoa for window creation and NSOpenGL for context creation
|
||||
#--------------------------------------------------------------------
|
||||
if (_GLFW_COCOA AND _GLFW_NSGL)
|
||||
if (_GLFW_COCOA)
|
||||
|
||||
if (GLFW_USE_MENUBAR)
|
||||
set(_GLFW_USE_MENUBAR 1)
|
||||
|
@ -93,12 +93,14 @@ does not find Doxygen, the documentation will not be generated.
|
||||
- Added `GLFW_NO_API` for creating window without contexts
|
||||
- Added `GLFW_CONTEXT_NO_ERROR` context hint for `GL_KHR_no_error` support
|
||||
- Added `GLFW_INCLUDE_VULKAN` for including the Vulkan header
|
||||
- Added `GLFW_CONTEXT_CREATION_API`, `GLFW_NATIVE_CONTEXT_API` and
|
||||
`GLFW_EGL_CONTEXT_API` for run-time context creation API selection
|
||||
- Added `GLFW_TRUE` and `GLFW_FALSE` as client API independent boolean values
|
||||
- Added icons to examples on Windows and OS X
|
||||
- Relaxed rules for native access header macros
|
||||
- Removed dependency on external OpenGL or OpenGL ES headers
|
||||
- Removed `_GLFW_USE_OPENGL`, `_GLFW_USE_GLESV1` and `_GLFW_USE_GLESV2`
|
||||
configuration macros
|
||||
- Removed `_GLFW_USE_OPENGL`, `_GLFW_USE_GLESV1`, `_GLFW_USE_GLESV2`,
|
||||
`_GLFW_WGL`, `_GLFW_NSGL`, `_GLFW_GLX` and `_GLFW_EGL` configuration macros
|
||||
- [Win32] Added support for Windows 8.1 per-monitor DPI
|
||||
- [Win32] Replaced winmm with XInput and DirectInput for joystick input
|
||||
- [Win32] Bugfix: Window creation would segfault if video mode setting required
|
||||
|
@ -225,19 +225,13 @@ need to be exported by the EXE to be detected by the driver, so the override
|
||||
will not work if GLFW is built as a DLL.
|
||||
|
||||
|
||||
@subsubsection compile_options_egl EGL specific CMake options
|
||||
|
||||
`GLFW_USE_EGL` determines whether to use EGL instead of the platform-specific
|
||||
context creation API. Note that EGL is not yet provided on all supported
|
||||
platforms.
|
||||
|
||||
|
||||
@section compile_manual Compiling GLFW manually
|
||||
|
||||
If you wish to compile GLFW without its CMake build environment then you will
|
||||
have to do at least some of the platform detection yourself. GLFW needs
|
||||
a number of configuration macros to be defined in order to know what it's being
|
||||
compiled for and has many optional, platform-specific ones for various features.
|
||||
a configuration macro to be defined in order to know what window system it's
|
||||
being compiled for and also has optional, platform-specific ones for various
|
||||
features.
|
||||
|
||||
When building with CMake, the `glfw_config.h` configuration header is generated
|
||||
based on the current platform and CMake options. The GLFW CMake environment
|
||||
@ -245,10 +239,6 @@ defines `_GLFW_USE_CONFIG_H`, which causes this header to be included by
|
||||
`internal.h`. Without this macro, GLFW will expect the necessary configuration
|
||||
macros to be defined on the command-line.
|
||||
|
||||
Three macros _must_ be defined when compiling GLFW: one selecting the window
|
||||
creation API and one selecting the context creation API. Exactly one of each
|
||||
kind must be defined for GLFW to compile and link.
|
||||
|
||||
The window creation API is used to create windows, handle input, monitors, gamma
|
||||
ramps and clipboard. The options are:
|
||||
|
||||
@ -258,19 +248,14 @@ ramps and clipboard. The options are:
|
||||
- `_GLFW_WAYLAND` to use the Wayland API (experimental and incomplete)
|
||||
- `_GLFW_MIR` to use the Mir API (experimental and incomplete)
|
||||
|
||||
The context creation API is used to enumerate pixel formats / framebuffer
|
||||
configurations and to create contexts. The options are:
|
||||
|
||||
- `_GLFW_NSGL` to use the Cocoa OpenGL framework
|
||||
- `_GLFW_WGL` to use the Win32 WGL API
|
||||
- `_GLFW_GLX` to use the X11 GLX API
|
||||
- `_GLFW_EGL` to use the EGL API
|
||||
|
||||
Wayland and Mir both require the EGL backend.
|
||||
|
||||
If you are building GLFW as a shared library / dynamic library / DLL then you
|
||||
must also define `_GLFW_BUILD_DLL`. Otherwise, you must not define it.
|
||||
|
||||
For the EGL context creation API, the following options are available:
|
||||
|
||||
- `_GLFW_USE_EGLPLATFORM_H` to use `EGL/eglplatform.h` for native handle
|
||||
definitions (fallback)
|
||||
|
||||
If you are using the X11 window creation API, support for the following X11
|
||||
extensions can be enabled:
|
||||
|
||||
@ -287,12 +272,6 @@ available:
|
||||
- `_GLFW_USE_RETINA` to have windows use the full resolution of Retina displays
|
||||
(recommended)
|
||||
|
||||
If you are using the EGL context creation API, the following options are
|
||||
available:
|
||||
|
||||
- `_GLFW_USE_EGLPLATFORM_H` to use `EGL/eglplatform.h` for native handle
|
||||
definitions (fallback)
|
||||
|
||||
@note None of the @ref build_macros may be defined during the compilation of
|
||||
GLFW. If you define any of these in your build files, make sure they are not
|
||||
applied to the GLFW sources.
|
||||
|
@ -177,9 +177,10 @@ python main.py --generator c --no-loader --out-path output
|
||||
@endcode
|
||||
|
||||
The `--no-loader` option is added because GLFW already provides a function for
|
||||
loading OpenGL and OpenGL ES function pointers and glad can call this instead of
|
||||
having to implement its own. There are several other command-line options as
|
||||
well. See the glad documentation for details.
|
||||
loading OpenGL and OpenGL ES function pointers, one that automatically uses the
|
||||
selected context creation API, and glad can call this instead of having to
|
||||
implement its own. There are several other command-line options as well. See
|
||||
the glad documentation for details.
|
||||
|
||||
Add the generated `output/src/glad.c`, `output/include/glad/glad.h` and
|
||||
`output/include/KHR/khrplatform.h` files to your build. Then you need to
|
||||
|
@ -61,6 +61,12 @@ GLFW now supports waiting for events for a set amount of time with @ref
|
||||
glfwWaitEventsTimeout.
|
||||
|
||||
|
||||
@subsection news_32_contextapi Run-time context creation API selection
|
||||
|
||||
GLFW now supports selecting the context creation API at run-time with
|
||||
[GLFW_CONTEXT_CREATION_API](@ref window_hints_ctx).
|
||||
|
||||
|
||||
@section news_31 New features in 3.1
|
||||
|
||||
These are the release highlights. For a full list of changes see the
|
||||
|
@ -159,6 +159,7 @@ The following hints are always hard constraints:
|
||||
- `GLFW_STEREO`
|
||||
- `GLFW_DOUBLEBUFFER`
|
||||
- `GLFW_CLIENT_API`
|
||||
- `GLFW_CONTEXT_CREATION_API`
|
||||
|
||||
The following additional hints are hard constraints when requesting an OpenGL
|
||||
context, but are ignored when requesting an OpenGL ES context:
|
||||
@ -249,6 +250,24 @@ This hint is ignored for windowed mode windows.
|
||||
Possible values are `GLFW_OPENGL_API`, `GLFW_OPENGL_ES_API` and `GLFW_NO_API`.
|
||||
This is a hard constraint.
|
||||
|
||||
`GLFW_CONTEXT_CREATION_API` specifies which context creation API to use to
|
||||
create the context. Possible values are `GLFW_NATIVE_CONTEXT_API` and
|
||||
`GLFW_EGL_CONTEXT_API`. This is a hard constraint. If no client API is
|
||||
requested, this hint is ignored.
|
||||
|
||||
@par
|
||||
__OS X:__ The EGL API is not available on this platform and requests to use it
|
||||
will fail.
|
||||
|
||||
@par
|
||||
__Wayland, Mir:__ The EGL API _is_ the native context creation API, so this hint
|
||||
will have no effect.
|
||||
|
||||
@note An OpenGL extension loader library that assumes it knows which context
|
||||
creation API is used on a given platform may fail if you change this hint. This
|
||||
can be resolved by having it load via @ref glfwGetProcAddress, which always uses
|
||||
the selected API.
|
||||
|
||||
`GLFW_CONTEXT_VERSION_MAJOR` and `GLFW_CONTEXT_VERSION_MINOR` specify the client
|
||||
API version that the created context must be compatible with. The exact
|
||||
behavior of these hints depend on the requested client API.
|
||||
@ -362,6 +381,7 @@ Window hint | Default value | Supported values
|
||||
`GLFW_SRGB_CAPABLE` | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||
`GLFW_DOUBLEBUFFER` | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE`
|
||||
`GLFW_CLIENT_API` | `GLFW_OPENGL_API` | `GLFW_OPENGL_API`, `GLFW_OPENGL_ES_API` or `GLFW_NO_API`
|
||||
`GLFW_CONTEXT_CREATION_API` | `GLFW_NATIVE_CONTEXT_API` | `GLFW_NATIVE_CONTEXT_API` or `GLFW_EGL_CONTEXT_API`
|
||||
`GLFW_CONTEXT_VERSION_MAJOR` | 1 | Any valid major version number of the chosen client API
|
||||
`GLFW_CONTEXT_VERSION_MINOR` | 0 | Any valid minor version number of the chosen client API
|
||||
`GLFW_CONTEXT_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET`
|
||||
@ -889,6 +909,10 @@ topmost or always-on-top. This is controlled by the
|
||||
`GLFW_CLIENT_API` indicates the client API provided by the window's context;
|
||||
either `GLFW_OPENGL_API`, `GLFW_OPENGL_ES_API` or `GLFW_NO_API`.
|
||||
|
||||
`GLFW_CONTEXT_CREATION_API` indicates the context creation API used to create
|
||||
the window's context; either `GLFW_NATIVE_CONTEXT_API` or
|
||||
`GLFW_EGL_CONTEXT_API`.
|
||||
|
||||
`GLFW_CONTEXT_VERSION_MAJOR`, `GLFW_CONTEXT_VERSION_MINOR` and
|
||||
`GLFW_CONTEXT_REVISION` indicate the client API version of the window's context.
|
||||
|
||||
|
@ -655,6 +655,7 @@ extern "C" {
|
||||
#define GLFW_OPENGL_PROFILE 0x00022008
|
||||
#define GLFW_CONTEXT_RELEASE_BEHAVIOR 0x00022009
|
||||
#define GLFW_CONTEXT_NO_ERROR 0x0002200A
|
||||
#define GLFW_CONTEXT_CREATION_API 0x0002200B
|
||||
|
||||
#define GLFW_NO_API 0
|
||||
#define GLFW_OPENGL_API 0x00030001
|
||||
@ -680,6 +681,9 @@ extern "C" {
|
||||
#define GLFW_RELEASE_BEHAVIOR_FLUSH 0x00035001
|
||||
#define GLFW_RELEASE_BEHAVIOR_NONE 0x00035002
|
||||
|
||||
#define GLFW_NATIVE_CONTEXT_API 0x00036001
|
||||
#define GLFW_EGL_CONTEXT_API 0x00036002
|
||||
|
||||
/*! @defgroup shapes Standard cursor shapes
|
||||
*
|
||||
* See [standard cursor creation](@ref cursor_standard) for how these are used.
|
||||
|
@ -7,23 +7,29 @@ set(common_SOURCES context.c init.c input.c monitor.c vulkan.c window.c)
|
||||
|
||||
if (_GLFW_COCOA)
|
||||
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h cocoa_joystick.h
|
||||
posix_tls.h)
|
||||
posix_tls.h nsgl_context.h)
|
||||
set(glfw_SOURCES ${common_SOURCES} cocoa_init.m cocoa_joystick.m
|
||||
cocoa_monitor.m cocoa_window.m cocoa_time.c posix_tls.c)
|
||||
cocoa_monitor.m cocoa_window.m cocoa_time.c posix_tls.c
|
||||
nsgl_context.m)
|
||||
elseif (_GLFW_WIN32)
|
||||
set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_joystick.h)
|
||||
set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_joystick.h
|
||||
wgl_context.h egl_context.h)
|
||||
set(glfw_SOURCES ${common_SOURCES} win32_init.c win32_joystick.c
|
||||
win32_monitor.c win32_time.c win32_tls.c win32_window.c)
|
||||
win32_monitor.c win32_time.c win32_tls.c win32_window.c
|
||||
wgl_context.c egl_context.c)
|
||||
elseif (_GLFW_X11)
|
||||
set(glfw_HEADERS ${common_HEADERS} x11_platform.h xkb_unicode.h
|
||||
linux_joystick.h posix_time.h posix_tls.h)
|
||||
linux_joystick.h posix_time.h posix_tls.h glx_context.h
|
||||
egl_context.h)
|
||||
set(glfw_SOURCES ${common_SOURCES} x11_init.c x11_monitor.c x11_window.c
|
||||
xkb_unicode.c linux_joystick.c posix_time.c posix_tls.c)
|
||||
xkb_unicode.c linux_joystick.c posix_time.c posix_tls.c
|
||||
glx_context.c egl_context.c)
|
||||
elseif (_GLFW_WAYLAND)
|
||||
set(glfw_HEADERS ${common_HEADERS} wl_platform.h linux_joystick.h
|
||||
posix_time.h posix_tls.h xkb_unicode.h)
|
||||
posix_time.h posix_tls.h xkb_unicode.h egl_context.h)
|
||||
set(glfw_SOURCES ${common_SOURCES} wl_init.c wl_monitor.c wl_window.c
|
||||
linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c)
|
||||
linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c
|
||||
egl_context.c)
|
||||
|
||||
ecm_add_wayland_client_protocol(glfw_SOURCES
|
||||
PROTOCOL
|
||||
@ -35,23 +41,10 @@ elseif (_GLFW_WAYLAND)
|
||||
BASENAME pointer-constraints-unstable-v1)
|
||||
elseif (_GLFW_MIR)
|
||||
set(glfw_HEADERS ${common_HEADERS} mir_platform.h linux_joystick.h
|
||||
posix_time.h posix_tls.h xkb_unicode.h)
|
||||
posix_time.h posix_tls.h xkb_unicode.h egl_context.h)
|
||||
set(glfw_SOURCES ${common_SOURCES} mir_init.c mir_monitor.c mir_window.c
|
||||
linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c)
|
||||
endif()
|
||||
|
||||
if (_GLFW_EGL)
|
||||
list(APPEND glfw_HEADERS ${common_HEADERS} egl_context.h)
|
||||
list(APPEND glfw_SOURCES ${common_SOURCES} egl_context.c)
|
||||
elseif (_GLFW_NSGL)
|
||||
list(APPEND glfw_HEADERS ${common_HEADERS} nsgl_context.h)
|
||||
list(APPEND glfw_SOURCES ${common_SOURCES} nsgl_context.m)
|
||||
elseif (_GLFW_WGL)
|
||||
list(APPEND glfw_HEADERS ${common_HEADERS} wgl_context.h)
|
||||
list(APPEND glfw_SOURCES ${common_SOURCES} wgl_context.c)
|
||||
elseif (_GLFW_X11)
|
||||
list(APPEND glfw_HEADERS ${common_HEADERS} glx_context.h)
|
||||
list(APPEND glfw_SOURCES ${common_SOURCES} glx_context.c)
|
||||
linux_joystick.c posix_time.c posix_tls.c xkb_unicode.c
|
||||
egl_context.c)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
|
@ -280,10 +280,7 @@ void _glfwPlatformTerminate(void)
|
||||
|
||||
const char* _glfwPlatformGetVersionString(void)
|
||||
{
|
||||
return _GLFW_VERSION_NUMBER " Cocoa"
|
||||
#if defined(_GLFW_NSGL)
|
||||
" NSGL"
|
||||
#endif
|
||||
return _GLFW_VERSION_NUMBER " Cocoa NSGL"
|
||||
#if defined(_GLFW_USE_CHDIR)
|
||||
" chdir"
|
||||
#endif
|
||||
|
@ -41,12 +41,7 @@ typedef void* id;
|
||||
|
||||
#include "posix_tls.h"
|
||||
#include "cocoa_joystick.h"
|
||||
|
||||
#if defined(_GLFW_NSGL)
|
||||
#include "nsgl_context.h"
|
||||
#else
|
||||
#error "The Cocoa backend depends on NSGL platform support"
|
||||
#endif
|
||||
|
||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
@ -58,6 +53,9 @@ typedef void* id;
|
||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorNS ns
|
||||
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorNS ns
|
||||
|
||||
#define _GLFW_EGL_CONTEXT_STATE
|
||||
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE
|
||||
|
||||
|
||||
// Cocoa-specific per-window data
|
||||
//
|
||||
|
@ -209,7 +209,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
|
||||
- (void)windowDidResize:(NSNotification *)notification
|
||||
{
|
||||
if (window->context.api != GLFW_NO_API)
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
[window->context.nsgl.object update];
|
||||
|
||||
if (_glfw.cursorWindow == window &&
|
||||
@ -227,7 +227,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 };
|
||||
|
||||
- (void)windowDidMove:(NSNotification *)notification
|
||||
{
|
||||
if (window->context.api != GLFW_NO_API)
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
[window->context.nsgl.object update];
|
||||
|
||||
if (_glfw.cursorWindow == window &&
|
||||
@ -1002,11 +1002,19 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
if (!createWindow(window, wndconfig))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (ctxconfig->api != GLFW_NO_API)
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwCreateContextNSGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Cocoa: EGL not available");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (window->monitor)
|
||||
{
|
||||
@ -1026,8 +1034,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
if (window->monitor)
|
||||
releaseMonitor(window);
|
||||
|
||||
if (window->context.api != GLFW_NO_API)
|
||||
_glfwDestroyContextNSGL(window);
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
window->context.destroyContext(window);
|
||||
|
||||
[window->ns.object setDelegate:nil];
|
||||
[window->ns.delegate release];
|
||||
|
@ -90,17 +90,26 @@ static GLFWbool parseVersionString(int* api, int* major, int* minor, int* rev)
|
||||
|
||||
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
{
|
||||
if (ctxconfig->api != GLFW_NO_API &&
|
||||
ctxconfig->api != GLFW_OPENGL_API &&
|
||||
ctxconfig->api != GLFW_OPENGL_ES_API)
|
||||
if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&
|
||||
ctxconfig->source != GLFW_EGL_CONTEXT_API)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid client API %i",
|
||||
ctxconfig->api);
|
||||
"Invalid context creation API %i",
|
||||
ctxconfig->source);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (ctxconfig->api == GLFW_OPENGL_API)
|
||||
if (ctxconfig->client != GLFW_NO_API &&
|
||||
ctxconfig->client != GLFW_OPENGL_API &&
|
||||
ctxconfig->client != GLFW_OPENGL_ES_API)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid client API %i",
|
||||
ctxconfig->client);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if ((ctxconfig->major < 1 || ctxconfig->minor < 0) ||
|
||||
(ctxconfig->major == 1 && ctxconfig->minor > 5) ||
|
||||
@ -150,7 +159,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
else if (ctxconfig->api == GLFW_OPENGL_ES_API)
|
||||
else if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
{
|
||||
if (ctxconfig->major < 1 || ctxconfig->minor < 0 ||
|
||||
(ctxconfig->major == 1 && ctxconfig->minor > 1) ||
|
||||
@ -366,8 +375,13 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
|
||||
glfwGetProcAddress("glGetIntegerv");
|
||||
window->context.GetString = (PFNGLGETSTRINGPROC)
|
||||
glfwGetProcAddress("glGetString");
|
||||
if (!window->context.GetIntegerv || !window->context.GetString)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!parseVersionString(&window->context.api,
|
||||
if (!parseVersionString(&window->context.client,
|
||||
&window->context.major,
|
||||
&window->context.minor,
|
||||
&window->context.revision))
|
||||
@ -375,6 +389,8 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
window->context.source = ctxconfig->source;
|
||||
|
||||
if (window->context.major < ctxconfig->major ||
|
||||
(window->context.major == ctxconfig->major &&
|
||||
window->context.minor < ctxconfig->minor))
|
||||
@ -409,7 +425,7 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
|
||||
}
|
||||
}
|
||||
|
||||
if (window->context.api == GLFW_OPENGL_API)
|
||||
if (window->context.client == GLFW_OPENGL_API)
|
||||
{
|
||||
// Read back context flags (OpenGL 3.0 and above)
|
||||
if (window->context.major >= 3)
|
||||
@ -507,7 +523,7 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
|
||||
{
|
||||
PFNGLCLEARPROC glClear = (PFNGLCLEARPROC) glfwGetProcAddress("glClear");
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
_glfwPlatformSwapBuffers(window);
|
||||
window->context.swapBuffers(window);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
@ -547,16 +563,24 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
|
||||
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFWwindow* previous = _glfwPlatformGetCurrentContext();
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window && window->context.api == GLFW_NO_API)
|
||||
if (window && window->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwPlatformMakeContextCurrent(window);
|
||||
if (previous)
|
||||
{
|
||||
if (!window || window->context.source != previous->context.source)
|
||||
previous->context.makeContextCurrent(NULL);
|
||||
}
|
||||
|
||||
if (window)
|
||||
window->context.makeContextCurrent(window);
|
||||
}
|
||||
|
||||
GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
|
||||
@ -572,26 +596,29 @@ GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (window->context.api == GLFW_NO_API)
|
||||
if (window->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwPlatformSwapBuffers(window);
|
||||
window->context.swapBuffers(window);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSwapInterval(int interval)
|
||||
{
|
||||
_GLFWwindow* window;
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (!_glfwPlatformGetCurrentContext())
|
||||
window = _glfwPlatformGetCurrentContext();
|
||||
if (!window)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwPlatformSwapInterval(interval);
|
||||
window->context.swapInterval(interval);
|
||||
}
|
||||
|
||||
GLFWAPI int glfwExtensionSupported(const char* extension)
|
||||
@ -657,21 +684,23 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
||||
}
|
||||
|
||||
// Check if extension is in the platform-specific string
|
||||
return _glfwPlatformExtensionSupported(extension);
|
||||
return window->context.extensionSupported(extension);
|
||||
}
|
||||
|
||||
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
|
||||
{
|
||||
_GLFWwindow* window;
|
||||
assert(procname != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (!_glfwPlatformGetCurrentContext())
|
||||
window = _glfwPlatformGetCurrentContext();
|
||||
if (!window)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_CURRENT_CONTEXT, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _glfwPlatformGetProcAddress(procname);
|
||||
return window->context.getProcAddress(procname);
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
|
||||
continue;
|
||||
#endif // _GLFW_X11
|
||||
|
||||
if (ctxconfig->api == GLFW_OPENGL_ES_API)
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
{
|
||||
if (ctxconfig->major == 1)
|
||||
{
|
||||
@ -138,7 +138,7 @@ static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (ctxconfig->api == GLFW_OPENGL_API)
|
||||
else if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if (!(getConfigAttrib(n, EGL_RENDERABLE_TYPE) & EGL_OPENGL_BIT))
|
||||
continue;
|
||||
@ -169,6 +169,110 @@ static GLFWbool chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
|
||||
return closest != NULL;
|
||||
}
|
||||
|
||||
static void makeContextCurrent(_GLFWwindow* window)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
if (!eglMakeCurrent(_glfw.egl.display,
|
||||
window->context.egl.surface,
|
||||
window->context.egl.surface,
|
||||
window->context.egl.handle))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to make context current: %s",
|
||||
getErrorString(eglGetError()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!eglMakeCurrent(_glfw.egl.display,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to clear current context: %s",
|
||||
getErrorString(eglGetError()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_glfwPlatformSetCurrentContext(window);
|
||||
}
|
||||
|
||||
static void swapBuffers(_GLFWwindow* window)
|
||||
{
|
||||
if (window != _glfwPlatformGetCurrentContext())
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: The context must be current on the calling thread when swapping buffers");
|
||||
return;
|
||||
}
|
||||
|
||||
eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
|
||||
}
|
||||
|
||||
static void swapInterval(int interval)
|
||||
{
|
||||
eglSwapInterval(_glfw.egl.display, interval);
|
||||
}
|
||||
|
||||
static int extensionSupported(const char* extension)
|
||||
{
|
||||
const char* extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
|
||||
if (extensions)
|
||||
{
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
static GLFWglproc getProcAddress(const char* procname)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||
|
||||
if (window->context.egl.client)
|
||||
{
|
||||
GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client,
|
||||
procname);
|
||||
if (proc)
|
||||
return proc;
|
||||
}
|
||||
|
||||
return eglGetProcAddress(procname);
|
||||
}
|
||||
|
||||
static void destroyContext(_GLFWwindow* window)
|
||||
{
|
||||
#if defined(_GLFW_X11)
|
||||
// NOTE: Do not unload libGL.so.1 while the X11 display is still open,
|
||||
// as it will make XCloseDisplay segfault
|
||||
if (window->context.client != GLFW_OPENGL_API)
|
||||
#endif // _GLFW_X11
|
||||
{
|
||||
if (window->context.egl.client)
|
||||
{
|
||||
_glfw_dlclose(window->context.egl.client);
|
||||
window->context.egl.client = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (window->context.egl.surface)
|
||||
{
|
||||
eglDestroySurface(_glfw.egl.display, window->context.egl.surface);
|
||||
window->context.egl.surface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
if (window->context.egl.handle)
|
||||
{
|
||||
eglDestroyContext(_glfw.egl.display, window->context.egl.handle);
|
||||
window->context.egl.handle = EGL_NO_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
@ -200,10 +304,7 @@ GLFWbool _glfwInitEGL(void)
|
||||
}
|
||||
|
||||
if (!_glfw.egl.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Failed to load EGL");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.egl.GetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
|
||||
@ -244,6 +345,8 @@ GLFWbool _glfwInitEGL(void)
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"EGL: Failed to get EGL display: %s",
|
||||
getErrorString(eglGetError()));
|
||||
|
||||
_glfwTerminateEGL();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
@ -252,15 +355,17 @@ GLFWbool _glfwInitEGL(void)
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"EGL: Failed to initialize EGL: %s",
|
||||
getErrorString(eglGetError()));
|
||||
|
||||
_glfwTerminateEGL();
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.egl.KHR_create_context =
|
||||
_glfwPlatformExtensionSupported("EGL_KHR_create_context");
|
||||
extensionSupported("EGL_KHR_create_context");
|
||||
_glfw.egl.KHR_create_context_no_error =
|
||||
_glfwPlatformExtensionSupported("EGL_KHR_create_context_no_error");
|
||||
extensionSupported("EGL_KHR_create_context_no_error");
|
||||
_glfw.egl.KHR_gl_colorspace =
|
||||
_glfwPlatformExtensionSupported("EGL_KHR_gl_colorspace");
|
||||
extensionSupported("EGL_KHR_gl_colorspace");
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
@ -299,6 +404,12 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
EGLConfig config;
|
||||
EGLContext share = NULL;
|
||||
|
||||
if (!_glfw.egl.display)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: API not available");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (ctxconfig->share)
|
||||
share = ctxconfig->share->context.egl.handle;
|
||||
|
||||
@ -309,7 +420,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (ctxconfig->api == GLFW_OPENGL_ES_API)
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
{
|
||||
if (!eglBindAPI(EGL_OPENGL_ES_API))
|
||||
{
|
||||
@ -334,7 +445,7 @@ GLFWbool _glfwCreateContextEGL(_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 |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
||||
@ -388,7 +499,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
if (ctxconfig->api == GLFW_OPENGL_ES_API)
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
setEGLattrib(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
|
||||
|
||||
setEGLattrib(EGL_NONE, EGL_NONE);
|
||||
@ -477,7 +588,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
NULL
|
||||
};
|
||||
|
||||
if (ctxconfig->api == GLFW_OPENGL_ES_API)
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
{
|
||||
if (ctxconfig->major == 1)
|
||||
sonames = es1sonames;
|
||||
@ -502,41 +613,18 @@ GLFWbool _glfwCreateContextEGL(_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 setEGLattrib
|
||||
|
||||
// Destroy the OpenGL context
|
||||
//
|
||||
void _glfwDestroyContextEGL(_GLFWwindow* window)
|
||||
{
|
||||
#if defined(_GLFW_X11)
|
||||
// NOTE: Do not unload libGL.so.1 while the X11 display is still open,
|
||||
// as it will make XCloseDisplay segfault
|
||||
if (window->context.api != GLFW_OPENGL_API)
|
||||
#endif // _GLFW_X11
|
||||
{
|
||||
if (window->context.egl.client)
|
||||
{
|
||||
_glfw_dlclose(window->context.egl.client);
|
||||
window->context.egl.client = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (window->context.egl.surface)
|
||||
{
|
||||
eglDestroySurface(_glfw.egl.display, window->context.egl.surface);
|
||||
window->context.egl.surface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
if (window->context.egl.handle)
|
||||
{
|
||||
eglDestroyContext(_glfw.egl.display, window->context.egl.handle);
|
||||
window->context.egl.handle = EGL_NO_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the Visual and depth of the chosen EGLConfig
|
||||
//
|
||||
#if defined(_GLFW_X11)
|
||||
@ -580,87 +668,6 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
|
||||
#endif // _GLFW_X11
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
if (!eglMakeCurrent(_glfw.egl.display,
|
||||
window->context.egl.surface,
|
||||
window->context.egl.surface,
|
||||
window->context.egl.handle))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to make context current: %s",
|
||||
getErrorString(eglGetError()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!eglMakeCurrent(_glfw.egl.display,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to clear current context: %s",
|
||||
getErrorString(eglGetError()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_glfwPlatformSetCurrentContext(window);
|
||||
}
|
||||
|
||||
void _glfwPlatformSwapBuffers(_GLFWwindow* window)
|
||||
{
|
||||
if (window != _glfwPlatformGetCurrentContext())
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: The context must be current on the calling thread when swapping buffers");
|
||||
return;
|
||||
}
|
||||
|
||||
eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
|
||||
}
|
||||
|
||||
void _glfwPlatformSwapInterval(int interval)
|
||||
{
|
||||
eglSwapInterval(_glfw.egl.display, interval);
|
||||
}
|
||||
|
||||
int _glfwPlatformExtensionSupported(const char* extension)
|
||||
{
|
||||
const char* extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
|
||||
if (extensions)
|
||||
{
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
GLFWglproc _glfwPlatformGetProcAddress(const char* procname)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||
|
||||
if (window->context.egl.client)
|
||||
{
|
||||
GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client,
|
||||
procname);
|
||||
if (proc)
|
||||
return proc;
|
||||
}
|
||||
|
||||
return eglGetProcAddress(procname);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -676,7 +683,7 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT);
|
||||
|
||||
if (window->context.api == GLFW_NO_API)
|
||||
if (window->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return EGL_NO_CONTEXT;
|
||||
@ -690,7 +697,7 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE);
|
||||
|
||||
if (window->context.api == GLFW_NO_API)
|
||||
if (window->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return EGL_NO_SURFACE;
|
||||
|
@ -149,8 +149,8 @@ typedef GLFWglproc (EGLAPIENTRY * PFNEGLGETPROCADDRESSPROC)(const char*);
|
||||
#define eglQueryString _glfw.egl.QueryString
|
||||
#define eglGetProcAddress _glfw.egl.GetProcAddress
|
||||
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextEGL egl
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryEGL egl
|
||||
#define _GLFW_EGL_CONTEXT_STATE _GLFWcontextEGL egl
|
||||
#define _GLFW_EGL_LIBRARY_CONTEXT_STATE _GLFWlibraryEGL egl
|
||||
|
||||
|
||||
// EGL-specific per-context data
|
||||
@ -204,7 +204,6 @@ void _glfwTerminateEGL(void);
|
||||
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContextEGL(_GLFWwindow* window);
|
||||
#if defined(_GLFW_X11)
|
||||
GLFWbool _glfwChooseVisualEGL(const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig,
|
||||
|
@ -45,15 +45,6 @@
|
||||
// Define this to 1 if building GLFW for Mir
|
||||
#cmakedefine _GLFW_MIR
|
||||
|
||||
// Define this to 1 if building GLFW for EGL
|
||||
#cmakedefine _GLFW_EGL
|
||||
// Define this to 1 if building GLFW for GLX
|
||||
#cmakedefine _GLFW_GLX
|
||||
// Define this to 1 if building GLFW for WGL
|
||||
#cmakedefine _GLFW_WGL
|
||||
// Define this to 1 if building GLFW for NSGL
|
||||
#cmakedefine _GLFW_NSGL
|
||||
|
||||
// Define this to 1 if building as a shared library / dynamic library / DLL
|
||||
#cmakedefine _GLFW_BUILD_DLL
|
||||
|
||||
|
@ -142,6 +142,96 @@ static GLXContext createLegacyContext(_GLFWwindow* window,
|
||||
True);
|
||||
}
|
||||
|
||||
static void makeContextCurrent(_GLFWwindow* window)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
if (!glXMakeCurrent(_glfw.x11.display,
|
||||
window->context.glx.window,
|
||||
window->context.glx.handle))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"GLX: Failed to make context current");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!glXMakeCurrent(_glfw.x11.display, None, NULL))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"GLX: Failed to clear current context");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_glfwPlatformSetCurrentContext(window);
|
||||
}
|
||||
|
||||
static void swapBuffers(_GLFWwindow* window)
|
||||
{
|
||||
glXSwapBuffers(_glfw.x11.display, window->context.glx.window);
|
||||
}
|
||||
|
||||
static void swapInterval(int interval)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||
|
||||
if (_glfw.glx.EXT_swap_control)
|
||||
{
|
||||
_glfw.glx.SwapIntervalEXT(_glfw.x11.display,
|
||||
window->context.glx.window,
|
||||
interval);
|
||||
}
|
||||
else if (_glfw.glx.MESA_swap_control)
|
||||
_glfw.glx.SwapIntervalMESA(interval);
|
||||
else if (_glfw.glx.SGI_swap_control)
|
||||
{
|
||||
if (interval > 0)
|
||||
_glfw.glx.SwapIntervalSGI(interval);
|
||||
}
|
||||
}
|
||||
|
||||
static int extensionSupported(const char* extension)
|
||||
{
|
||||
const char* extensions =
|
||||
glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen);
|
||||
if (extensions)
|
||||
{
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
static GLFWglproc getProcAddress(const char* procname)
|
||||
{
|
||||
if (_glfw.glx.GetProcAddress)
|
||||
return _glfw.glx.GetProcAddress((const GLubyte*) procname);
|
||||
else if (_glfw.glx.GetProcAddressARB)
|
||||
return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
|
||||
else
|
||||
return dlsym(_glfw.glx.handle, procname);
|
||||
}
|
||||
|
||||
// Destroy the OpenGL context
|
||||
//
|
||||
static void destroyContext(_GLFWwindow* window)
|
||||
{
|
||||
if (window->context.glx.window)
|
||||
{
|
||||
glXDestroyWindow(_glfw.x11.display, window->context.glx.window);
|
||||
window->context.glx.window = None;
|
||||
}
|
||||
|
||||
if (window->context.glx.handle)
|
||||
{
|
||||
glXDestroyContext(_glfw.x11.display, window->context.glx.handle);
|
||||
window->context.glx.handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
@ -229,61 +319,61 @@ GLFWbool _glfwInitGLX(void)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (_glfwPlatformExtensionSupported("GLX_EXT_swap_control"))
|
||||
if (extensionSupported("GLX_EXT_swap_control"))
|
||||
{
|
||||
_glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
|
||||
_glfwPlatformGetProcAddress("glXSwapIntervalEXT");
|
||||
getProcAddress("glXSwapIntervalEXT");
|
||||
|
||||
if (_glfw.glx.SwapIntervalEXT)
|
||||
_glfw.glx.EXT_swap_control = GLFW_TRUE;
|
||||
}
|
||||
|
||||
if (_glfwPlatformExtensionSupported("GLX_SGI_swap_control"))
|
||||
if (extensionSupported("GLX_SGI_swap_control"))
|
||||
{
|
||||
_glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)
|
||||
_glfwPlatformGetProcAddress("glXSwapIntervalSGI");
|
||||
getProcAddress("glXSwapIntervalSGI");
|
||||
|
||||
if (_glfw.glx.SwapIntervalSGI)
|
||||
_glfw.glx.SGI_swap_control = GLFW_TRUE;
|
||||
}
|
||||
|
||||
if (_glfwPlatformExtensionSupported("GLX_MESA_swap_control"))
|
||||
if (extensionSupported("GLX_MESA_swap_control"))
|
||||
{
|
||||
_glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)
|
||||
_glfwPlatformGetProcAddress("glXSwapIntervalMESA");
|
||||
getProcAddress("glXSwapIntervalMESA");
|
||||
|
||||
if (_glfw.glx.SwapIntervalMESA)
|
||||
_glfw.glx.MESA_swap_control = GLFW_TRUE;
|
||||
}
|
||||
|
||||
if (_glfwPlatformExtensionSupported("GLX_ARB_multisample"))
|
||||
if (extensionSupported("GLX_ARB_multisample"))
|
||||
_glfw.glx.ARB_multisample = GLFW_TRUE;
|
||||
|
||||
if (_glfwPlatformExtensionSupported("GLX_ARB_framebuffer_sRGB"))
|
||||
if (extensionSupported("GLX_ARB_framebuffer_sRGB"))
|
||||
_glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE;
|
||||
|
||||
if (_glfwPlatformExtensionSupported("GLX_EXT_framebuffer_sRGB"))
|
||||
if (extensionSupported("GLX_EXT_framebuffer_sRGB"))
|
||||
_glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;
|
||||
|
||||
if (_glfwPlatformExtensionSupported("GLX_ARB_create_context"))
|
||||
if (extensionSupported("GLX_ARB_create_context"))
|
||||
{
|
||||
_glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
|
||||
_glfwPlatformGetProcAddress("glXCreateContextAttribsARB");
|
||||
getProcAddress("glXCreateContextAttribsARB");
|
||||
|
||||
if (_glfw.glx.CreateContextAttribsARB)
|
||||
_glfw.glx.ARB_create_context = GLFW_TRUE;
|
||||
}
|
||||
|
||||
if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_robustness"))
|
||||
if (extensionSupported("GLX_ARB_create_context_robustness"))
|
||||
_glfw.glx.ARB_create_context_robustness = GLFW_TRUE;
|
||||
|
||||
if (_glfwPlatformExtensionSupported("GLX_ARB_create_context_profile"))
|
||||
if (extensionSupported("GLX_ARB_create_context_profile"))
|
||||
_glfw.glx.ARB_create_context_profile = GLFW_TRUE;
|
||||
|
||||
if (_glfwPlatformExtensionSupported("GLX_EXT_create_context_es2_profile"))
|
||||
if (extensionSupported("GLX_EXT_create_context_es2_profile"))
|
||||
_glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE;
|
||||
|
||||
if (_glfwPlatformExtensionSupported("GLX_ARB_context_flush_control"))
|
||||
if (extensionSupported("GLX_ARB_context_flush_control"))
|
||||
_glfw.glx.ARB_context_flush_control = GLFW_TRUE;
|
||||
|
||||
return GLFW_TRUE;
|
||||
@ -330,7 +420,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (ctxconfig->api == GLFW_OPENGL_ES_API)
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
{
|
||||
if (!_glfw.glx.ARB_create_context ||
|
||||
!_glfw.glx.ARB_create_context_profile ||
|
||||
@ -369,7 +459,7 @@ GLFWbool _glfwCreateContextGLX(_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 |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
|
||||
@ -454,7 +544,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
if (!window->context.glx.handle)
|
||||
{
|
||||
if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&
|
||||
ctxconfig->api == GLFW_OPENGL_API &&
|
||||
ctxconfig->client == GLFW_OPENGL_API &&
|
||||
ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&
|
||||
ctxconfig->forward == GLFW_FALSE)
|
||||
{
|
||||
@ -482,28 +572,18 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
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 setGLXattrib
|
||||
|
||||
// Destroy the OpenGL context
|
||||
//
|
||||
void _glfwDestroyContextGLX(_GLFWwindow* window)
|
||||
{
|
||||
if (window->context.glx.window)
|
||||
{
|
||||
glXDestroyWindow(_glfw.x11.display, window->context.glx.window);
|
||||
window->context.glx.window = None;
|
||||
}
|
||||
|
||||
if (window->context.glx.handle)
|
||||
{
|
||||
glXDestroyContext(_glfw.x11.display, window->context.glx.handle);
|
||||
window->context.glx.handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns the Visual and depth of the chosen GLXFBConfig
|
||||
//
|
||||
GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
|
||||
@ -536,84 +616,6 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
if (!glXMakeCurrent(_glfw.x11.display,
|
||||
window->context.glx.window,
|
||||
window->context.glx.handle))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"GLX: Failed to make context current");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!glXMakeCurrent(_glfw.x11.display, None, NULL))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"GLX: Failed to clear current context");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_glfwPlatformSetCurrentContext(window);
|
||||
}
|
||||
|
||||
void _glfwPlatformSwapBuffers(_GLFWwindow* window)
|
||||
{
|
||||
glXSwapBuffers(_glfw.x11.display, window->context.glx.window);
|
||||
}
|
||||
|
||||
void _glfwPlatformSwapInterval(int interval)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||
|
||||
if (_glfw.glx.EXT_swap_control)
|
||||
{
|
||||
_glfw.glx.SwapIntervalEXT(_glfw.x11.display,
|
||||
window->context.glx.window,
|
||||
interval);
|
||||
}
|
||||
else if (_glfw.glx.MESA_swap_control)
|
||||
_glfw.glx.SwapIntervalMESA(interval);
|
||||
else if (_glfw.glx.SGI_swap_control)
|
||||
{
|
||||
if (interval > 0)
|
||||
_glfw.glx.SwapIntervalSGI(interval);
|
||||
}
|
||||
}
|
||||
|
||||
int _glfwPlatformExtensionSupported(const char* extension)
|
||||
{
|
||||
const char* extensions =
|
||||
glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen);
|
||||
if (extensions)
|
||||
{
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
GLFWglproc _glfwPlatformGetProcAddress(const char* procname)
|
||||
{
|
||||
if (_glfw.glx.GetProcAddress)
|
||||
return _glfw.glx.GetProcAddress((const GLubyte*) procname);
|
||||
else if (_glfw.glx.GetProcAddressARB)
|
||||
return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
|
||||
else
|
||||
return dlsym(_glfw.glx.handle, procname);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -623,7 +625,7 @@ GLFWAPI GLXContext glfwGetGLXContext(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;
|
||||
@ -637,7 +639,7 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(None);
|
||||
|
||||
if (window->context.api == GLFW_NO_API)
|
||||
if (window->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return None;
|
||||
|
@ -58,6 +58,13 @@ typedef struct _GLFWlibrary _GLFWlibrary;
|
||||
typedef struct _GLFWmonitor _GLFWmonitor;
|
||||
typedef struct _GLFWcursor _GLFWcursor;
|
||||
|
||||
typedef void (* _GLFWmakecontextcurrentfun)(_GLFWwindow*);
|
||||
typedef void (* _GLFWswapbuffersfun)(_GLFWwindow*);
|
||||
typedef void (* _GLFWswapintervalfun)(int);
|
||||
typedef int (* _GLFWextensionsupportedfun)(const char*);
|
||||
typedef GLFWglproc (* _GLFWgetprocaddressfun)(const char*);
|
||||
typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*);
|
||||
|
||||
#define GL_VERSION 0x1f02
|
||||
#define GL_NONE 0
|
||||
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||
@ -258,7 +265,8 @@ struct _GLFWwndconfig
|
||||
*/
|
||||
struct _GLFWctxconfig
|
||||
{
|
||||
int api;
|
||||
int client;
|
||||
int source;
|
||||
int major;
|
||||
int minor;
|
||||
GLFWbool forward;
|
||||
@ -304,7 +312,8 @@ struct _GLFWfbconfig
|
||||
*/
|
||||
struct _GLFWcontext
|
||||
{
|
||||
int api;
|
||||
int client;
|
||||
int source;
|
||||
int major, minor, revision;
|
||||
GLFWbool forward, debug, noerror;
|
||||
int profile;
|
||||
@ -315,8 +324,17 @@ struct _GLFWcontext
|
||||
PFNGLGETINTEGERVPROC GetIntegerv;
|
||||
PFNGLGETSTRINGPROC GetString;
|
||||
|
||||
_GLFWmakecontextcurrentfun makeContextCurrent;
|
||||
_GLFWswapbuffersfun swapBuffers;
|
||||
_GLFWswapintervalfun swapInterval;
|
||||
_GLFWextensionsupportedfun extensionSupported;
|
||||
_GLFWgetprocaddressfun getProcAddress;
|
||||
_GLFWdestroycontextfun destroyContext;
|
||||
|
||||
// This is defined in the context API's context.h
|
||||
_GLFW_PLATFORM_CONTEXT_STATE;
|
||||
// This is defined in egl_context.h
|
||||
_GLFW_EGL_CONTEXT_STATE;
|
||||
};
|
||||
|
||||
|
||||
@ -461,6 +479,8 @@ struct _GLFWlibrary
|
||||
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
|
||||
// This is defined in the platform's tls.h
|
||||
_GLFW_PLATFORM_LIBRARY_TLS_STATE;
|
||||
// This is defined in egl_context.h
|
||||
_GLFW_EGL_LIBRARY_CONTEXT_STATE;
|
||||
};
|
||||
|
||||
|
||||
@ -742,11 +762,6 @@ void _glfwPlatformWaitEventsTimeout(double timeout);
|
||||
*/
|
||||
void _glfwPlatformPostEmptyEvent(void);
|
||||
|
||||
/*! @copydoc glfwMakeContextCurrent
|
||||
* @ingroup platform
|
||||
*/
|
||||
void _glfwPlatformMakeContextCurrent(_GLFWwindow* window);
|
||||
|
||||
/*! @ingroup platform
|
||||
*/
|
||||
void _glfwPlatformSetCurrentContext(_GLFWwindow* context);
|
||||
@ -756,26 +771,6 @@ void _glfwPlatformSetCurrentContext(_GLFWwindow* context);
|
||||
*/
|
||||
_GLFWwindow* _glfwPlatformGetCurrentContext(void);
|
||||
|
||||
/*! @copydoc glfwSwapBuffers
|
||||
* @ingroup platform
|
||||
*/
|
||||
void _glfwPlatformSwapBuffers(_GLFWwindow* window);
|
||||
|
||||
/*! @copydoc glfwSwapInterval
|
||||
* @ingroup platform
|
||||
*/
|
||||
void _glfwPlatformSwapInterval(int interval);
|
||||
|
||||
/*! @copydoc glfwExtensionSupported
|
||||
* @ingroup platform
|
||||
*/
|
||||
int _glfwPlatformExtensionSupported(const char* extension);
|
||||
|
||||
/*! @copydoc glfwGetProcAddress
|
||||
* @ingroup platform
|
||||
*/
|
||||
GLFWglproc _glfwPlatformGetProcAddress(const char* procname);
|
||||
|
||||
/*! @copydoc glfwCreateCursor
|
||||
* @ingroup platform
|
||||
*/
|
||||
|
@ -51,12 +51,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(Vk
|
||||
#include "posix_time.h"
|
||||
#include "linux_joystick.h"
|
||||
#include "xkb_unicode.h"
|
||||
|
||||
#if defined(_GLFW_EGL)
|
||||
#include "egl_context.h"
|
||||
#else
|
||||
#error "The Mir backend depends on EGL platform support"
|
||||
#endif
|
||||
|
||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
@ -70,6 +65,9 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceMirPresentationSupportKHR)(Vk
|
||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryMir mir
|
||||
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorMir mir
|
||||
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
||||
|
||||
|
||||
// Mir-specific Event Queue
|
||||
//
|
||||
|
@ -378,7 +378,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
window->mir.window = mir_buffer_stream_get_egl_native_window(
|
||||
mir_surface_get_buffer_stream(window->mir.surface));
|
||||
|
||||
if (ctxconfig->api != GLFW_NO_API)
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
@ -395,7 +395,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
window->mir.surface = NULL;
|
||||
}
|
||||
|
||||
_glfwDestroyContextEGL(window);
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
window->context.destroyContext(window);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title)
|
||||
|
@ -27,6 +27,63 @@
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
static void makeContextCurrent(_GLFWwindow* window)
|
||||
{
|
||||
if (window)
|
||||
[window->context.nsgl.object makeCurrentContext];
|
||||
else
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
|
||||
_glfwPlatformSetCurrentContext(window);
|
||||
}
|
||||
|
||||
static void swapBuffers(_GLFWwindow* window)
|
||||
{
|
||||
// ARP appears to be unnecessary, but this is future-proof
|
||||
[window->context.nsgl.object flushBuffer];
|
||||
}
|
||||
|
||||
static void swapInterval(int interval)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||
|
||||
GLint sync = interval;
|
||||
[window->context.nsgl.object setValues:&sync
|
||||
forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
|
||||
static int extensionSupported(const char* extension)
|
||||
{
|
||||
// There are no NSGL extensions
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
static GLFWglproc getProcAddress(const char* procname)
|
||||
{
|
||||
CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault,
|
||||
procname,
|
||||
kCFStringEncodingASCII);
|
||||
|
||||
GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,
|
||||
symbolName);
|
||||
|
||||
CFRelease(symbolName);
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
// Destroy the OpenGL context
|
||||
//
|
||||
static void destroyContext(_GLFWwindow* window)
|
||||
{
|
||||
[window->context.nsgl.pixelFormat release];
|
||||
window->context.nsgl.pixelFormat = nil;
|
||||
|
||||
[window->context.nsgl.object release];
|
||||
window->context.nsgl.object = nil;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -61,7 +118,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
{
|
||||
unsigned int attributeCount = 0;
|
||||
|
||||
if (ctxconfig->api == GLFW_OPENGL_ES_API)
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"NSGL: OpenGL ES is not available on OS X");
|
||||
@ -216,70 +273,17 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
[window->context.nsgl.object setView:window->ns.view];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Destroy the OpenGL context
|
||||
//
|
||||
void _glfwDestroyContextNSGL(_GLFWwindow* window)
|
||||
{
|
||||
[window->context.nsgl.pixelFormat release];
|
||||
window->context.nsgl.pixelFormat = nil;
|
||||
|
||||
[window->context.nsgl.object release];
|
||||
window->context.nsgl.object = nil;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
|
||||
{
|
||||
if (window)
|
||||
[window->context.nsgl.object makeCurrentContext];
|
||||
else
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
|
||||
_glfwPlatformSetCurrentContext(window);
|
||||
}
|
||||
|
||||
void _glfwPlatformSwapBuffers(_GLFWwindow* window)
|
||||
{
|
||||
// ARP appears to be unnecessary, but this is future-proof
|
||||
[window->context.nsgl.object flushBuffer];
|
||||
}
|
||||
|
||||
void _glfwPlatformSwapInterval(int interval)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetCurrentContext();
|
||||
|
||||
GLint sync = interval;
|
||||
[window->context.nsgl.object setValues:&sync
|
||||
forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
|
||||
int _glfwPlatformExtensionSupported(const char* extension)
|
||||
{
|
||||
// There are no NSGL extensions
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
GLFWglproc _glfwPlatformGetProcAddress(const char* procname)
|
||||
{
|
||||
CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault,
|
||||
procname,
|
||||
kCFStringEncodingASCII);
|
||||
|
||||
GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,
|
||||
symbolName);
|
||||
|
||||
CFRelease(symbolName);
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
@ -290,7 +294,7 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(nil);
|
||||
|
||||
if (window->context.api == GLFW_NO_API)
|
||||
if (window->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return NULL;
|
||||
|
@ -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;
|
||||
|
@ -148,7 +148,6 @@ void _glfwTerminateWGL(void);
|
||||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContextWGL(_GLFWwindow* window);
|
||||
int _glfwAnalyzeContextWGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
|
@ -421,14 +421,10 @@ int _glfwPlatformInit(void)
|
||||
|
||||
_glfwPlatformPollEvents();
|
||||
|
||||
#if defined(_GLFW_WGL)
|
||||
if (!_glfwInitWGL())
|
||||
return GLFW_FALSE;
|
||||
#elif defined(_GLFW_EGL)
|
||||
if (!_glfwInitEGL())
|
||||
return GLFW_FALSE;
|
||||
#endif
|
||||
|
||||
_glfwInitEGL();
|
||||
_glfwInitTimerWin32();
|
||||
_glfwInitJoysticksWin32();
|
||||
|
||||
@ -449,11 +445,8 @@ void _glfwPlatformTerminate(void)
|
||||
|
||||
free(_glfw.win32.clipboardString);
|
||||
|
||||
#if defined(_GLFW_WGL)
|
||||
_glfwTerminateWGL();
|
||||
#elif defined(_GLFW_EGL)
|
||||
_glfwTerminateEGL();
|
||||
#endif
|
||||
|
||||
_glfwTerminateJoysticksWin32();
|
||||
_glfwTerminateThreadLocalStorageWin32();
|
||||
@ -463,12 +456,7 @@ void _glfwPlatformTerminate(void)
|
||||
|
||||
const char* _glfwPlatformGetVersionString(void)
|
||||
{
|
||||
return _GLFW_VERSION_NUMBER " Win32"
|
||||
#if defined(_GLFW_WGL)
|
||||
" WGL"
|
||||
#elif defined(_GLFW_EGL)
|
||||
" EGL"
|
||||
#endif
|
||||
return _GLFW_VERSION_NUMBER " Win32 WGL EGL"
|
||||
#if defined(__MINGW32__)
|
||||
" MinGW"
|
||||
#elif defined(_MSC_VER)
|
||||
|
@ -205,16 +205,8 @@ typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin3
|
||||
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t);
|
||||
|
||||
#include "win32_joystick.h"
|
||||
|
||||
#if defined(_GLFW_WGL)
|
||||
#include "wgl_context.h"
|
||||
#elif defined(_GLFW_EGL)
|
||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->win32.handle)
|
||||
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
|
||||
#include "egl_context.h"
|
||||
#else
|
||||
#error "No supported context creation API selected"
|
||||
#endif
|
||||
|
||||
#define _GLFW_WNDCLASSNAME L"GLFW30"
|
||||
|
||||
@ -222,6 +214,9 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(
|
||||
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
|
||||
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
|
||||
|
||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->win32.handle)
|
||||
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
|
||||
|
||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
|
||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
|
||||
#define _GLFW_PLATFORM_LIBRARY_TIME_STATE _GLFWtimeWin32 win32_time
|
||||
|
@ -940,9 +940,10 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
if (!createWindow(window, wndconfig))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (ctxconfig->api != GLFW_NO_API)
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
#if defined(_GLFW_WGL)
|
||||
if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
|
||||
@ -972,11 +973,11 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
// First we clear the current context (the one we just created)
|
||||
// This is usually done by glfwDestroyWindow, but as we're not doing
|
||||
// full GLFW window destruction, it's duplicated here
|
||||
_glfwPlatformMakeContextCurrent(NULL);
|
||||
window->context.makeContextCurrent(NULL);
|
||||
|
||||
// Next destroy the Win32 window and WGL context (without resetting
|
||||
// or destroying the GLFW window object)
|
||||
_glfwDestroyContextWGL(window);
|
||||
window->context.destroyContext(window);
|
||||
destroyWindow(window);
|
||||
|
||||
// ...and then create them again, this time with better APIs
|
||||
@ -985,10 +986,12 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
if (!_glfwCreateContextWGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
#elif defined(_GLFW_EGL)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (window->monitor)
|
||||
@ -1007,14 +1010,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
if (window->monitor)
|
||||
releaseMonitor(window);
|
||||
|
||||
if (window->context.api != GLFW_NO_API)
|
||||
{
|
||||
#if defined(_GLFW_WGL)
|
||||
_glfwDestroyContextWGL(window);
|
||||
#elif defined(_GLFW_EGL)
|
||||
_glfwDestroyContextEGL(window);
|
||||
#endif
|
||||
}
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
window->context.destroyContext(window);
|
||||
|
||||
destroyWindow(window);
|
||||
|
||||
|
28
src/window.c
28
src/window.c
@ -155,7 +155,7 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
|
||||
if (ctxconfig.share)
|
||||
{
|
||||
if (ctxconfig.share->context.api == GLFW_NO_API)
|
||||
if (ctxconfig.share->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return NULL;
|
||||
@ -192,29 +192,31 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
|
||||
// Save the currently current context so it can be restored later
|
||||
previous = _glfwPlatformGetCurrentContext();
|
||||
if (ctxconfig.client != GLFW_NO_API)
|
||||
glfwMakeContextCurrent(NULL);
|
||||
|
||||
// Open the actual window and create its context
|
||||
if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig))
|
||||
{
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
glfwDestroyWindow((GLFWwindow*) window);
|
||||
_glfwPlatformMakeContextCurrent(previous);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ctxconfig.api != GLFW_NO_API)
|
||||
if (ctxconfig.client != GLFW_NO_API)
|
||||
{
|
||||
_glfwPlatformMakeContextCurrent(window);
|
||||
window->context.makeContextCurrent(window);
|
||||
|
||||
// Retrieve the actual (as opposed to requested) context attributes
|
||||
if (!_glfwRefreshContextAttribs(&ctxconfig))
|
||||
{
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
glfwDestroyWindow((GLFWwindow*) window);
|
||||
_glfwPlatformMakeContextCurrent(previous);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Restore the previously current context (or NULL)
|
||||
_glfwPlatformMakeContextCurrent(previous);
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
}
|
||||
|
||||
if (window->monitor)
|
||||
@ -247,7 +249,8 @@ void glfwDefaultWindowHints(void)
|
||||
memset(&_glfw.hints, 0, sizeof(_glfw.hints));
|
||||
|
||||
// The default is OpenGL with minimum version 1.0
|
||||
_glfw.hints.context.api = GLFW_OPENGL_API;
|
||||
_glfw.hints.context.client = GLFW_OPENGL_API;
|
||||
_glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API;
|
||||
_glfw.hints.context.major = 1;
|
||||
_glfw.hints.context.minor = 0;
|
||||
|
||||
@ -345,7 +348,10 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
||||
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
break;
|
||||
case GLFW_CLIENT_API:
|
||||
_glfw.hints.context.api = value;
|
||||
_glfw.hints.context.client = value;
|
||||
break;
|
||||
case GLFW_CONTEXT_CREATION_API:
|
||||
_glfw.hints.context.source = value;
|
||||
break;
|
||||
case GLFW_CONTEXT_VERSION_MAJOR:
|
||||
_glfw.hints.context.major = value;
|
||||
@ -396,7 +402,7 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow* handle)
|
||||
// The window's context must not be current on another thread when the
|
||||
// window is destroyed
|
||||
if (window == _glfwPlatformGetCurrentContext())
|
||||
_glfwPlatformMakeContextCurrent(NULL);
|
||||
glfwMakeContextCurrent(NULL);
|
||||
|
||||
// Clear the focused window pointer if this is the focused window
|
||||
if (_glfw.cursorWindow == window)
|
||||
@ -683,7 +689,9 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
||||
case GLFW_FLOATING:
|
||||
return window->floating;
|
||||
case GLFW_CLIENT_API:
|
||||
return window->context.api;
|
||||
return window->context.client;
|
||||
case GLFW_CONTEXT_CREATION_API:
|
||||
return window->context.source;
|
||||
case GLFW_CONTEXT_VERSION_MAJOR:
|
||||
return window->context.major;
|
||||
case GLFW_CONTEXT_VERSION_MINOR:
|
||||
|
@ -49,12 +49,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
||||
#include "posix_time.h"
|
||||
#include "linux_joystick.h"
|
||||
#include "xkb_unicode.h"
|
||||
|
||||
#if defined(_GLFW_EGL)
|
||||
#include "egl_context.h"
|
||||
#else
|
||||
#error "The Wayland backend depends on EGL platform support"
|
||||
#endif
|
||||
|
||||
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
|
||||
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
||||
@ -71,6 +66,9 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWayland wl
|
||||
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWayland wl
|
||||
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
||||
|
||||
|
||||
// Wayland-specific video mode data
|
||||
//
|
||||
|
@ -373,7 +373,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
if (!createSurface(window, wndconfig))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (ctxconfig->api != GLFW_NO_API)
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
@ -417,7 +417,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||
}
|
||||
|
||||
_glfwDestroyContextEGL(window);
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
window->context.destroyContext(window);
|
||||
|
||||
if (window->wl.native)
|
||||
wl_egl_window_destroy(window->wl.native);
|
||||
|
@ -766,17 +766,13 @@ int _glfwPlatformInit(void)
|
||||
if (!_glfwInitThreadLocalStoragePOSIX())
|
||||
return GLFW_FALSE;
|
||||
|
||||
#if defined(_GLFW_GLX)
|
||||
if (!_glfwInitGLX())
|
||||
return GLFW_FALSE;
|
||||
#elif defined(_GLFW_EGL)
|
||||
if (!_glfwInitEGL())
|
||||
return GLFW_FALSE;
|
||||
#endif
|
||||
|
||||
if (!_glfwInitJoysticksLinux())
|
||||
return GLFW_FALSE;
|
||||
|
||||
_glfwInitEGL();
|
||||
_glfwInitTimerPOSIX();
|
||||
|
||||
return GLFW_TRUE;
|
||||
@ -804,9 +800,7 @@ void _glfwPlatformTerminate(void)
|
||||
_glfw.x11.im = NULL;
|
||||
}
|
||||
|
||||
#if defined(_GLFW_EGL)
|
||||
_glfwTerminateEGL();
|
||||
#endif
|
||||
|
||||
if (_glfw.x11.display)
|
||||
{
|
||||
@ -816,9 +810,7 @@ void _glfwPlatformTerminate(void)
|
||||
|
||||
// NOTE: This needs to be done after XCloseDisplay, as libGL registers
|
||||
// cleanup callbacks that get called by it
|
||||
#if defined(_GLFW_GLX)
|
||||
_glfwTerminateGLX();
|
||||
#endif
|
||||
|
||||
_glfwTerminateJoysticksLinux();
|
||||
_glfwTerminateThreadLocalStoragePOSIX();
|
||||
@ -826,12 +818,7 @@ void _glfwPlatformTerminate(void)
|
||||
|
||||
const char* _glfwPlatformGetVersionString(void)
|
||||
{
|
||||
return _GLFW_VERSION_NUMBER " X11"
|
||||
#if defined(_GLFW_GLX)
|
||||
" GLX"
|
||||
#elif defined(_GLFW_EGL)
|
||||
" EGL"
|
||||
#endif
|
||||
return _GLFW_VERSION_NUMBER " X11 GLX EGL"
|
||||
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
|
||||
" clock_gettime"
|
||||
#else
|
||||
|
@ -87,21 +87,16 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(Vk
|
||||
#include "posix_time.h"
|
||||
#include "linux_joystick.h"
|
||||
#include "xkb_unicode.h"
|
||||
|
||||
#if defined(_GLFW_GLX)
|
||||
#include "glx_context.h"
|
||||
#elif defined(_GLFW_EGL)
|
||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->x11.handle)
|
||||
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.x11.display)
|
||||
#include "egl_context.h"
|
||||
#else
|
||||
#error "No supported context creation API selected"
|
||||
#endif
|
||||
|
||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
#define _glfw_dlsym(handle, name) dlsym(handle, name)
|
||||
|
||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->x11.handle)
|
||||
#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.x11.display)
|
||||
|
||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11
|
||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11
|
||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 x11
|
||||
|
@ -1478,34 +1478,40 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
Visual* visual;
|
||||
int depth;
|
||||
|
||||
if (ctxconfig->api == GLFW_NO_API)
|
||||
if (ctxconfig->client == GLFW_NO_API)
|
||||
{
|
||||
visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen);
|
||||
depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(_GLFW_GLX)
|
||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwChooseVisualGLX(ctxconfig, fbconfig, &visual, &depth))
|
||||
return GLFW_FALSE;
|
||||
#elif defined(_GLFW_EGL)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_glfwChooseVisualEGL(ctxconfig, fbconfig, &visual, &depth))
|
||||
return GLFW_FALSE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!createWindow(window, wndconfig, visual, depth))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (ctxconfig->api != GLFW_NO_API)
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
|
||||
{
|
||||
#if defined(_GLFW_GLX)
|
||||
if (!_glfwCreateContextGLX(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
#elif defined(_GLFW_EGL)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (window->monitor)
|
||||
@ -1530,14 +1536,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
window->x11.ic = NULL;
|
||||
}
|
||||
|
||||
if (window->context.api != GLFW_NO_API)
|
||||
{
|
||||
#if defined(_GLFW_GLX)
|
||||
_glfwDestroyContextGLX(window);
|
||||
#elif defined(_GLFW_EGL)
|
||||
_glfwDestroyContextEGL(window);
|
||||
#endif
|
||||
}
|
||||
if (window->context.client != GLFW_NO_API)
|
||||
window->context.destroyContext(window);
|
||||
|
||||
if (window->x11.handle)
|
||||
{
|
||||
|
@ -41,6 +41,9 @@
|
||||
#define API_NAME_OPENGL "gl"
|
||||
#define API_NAME_OPENGL_ES "es"
|
||||
|
||||
#define API_NAME_NATIVE "native"
|
||||
#define API_NAME_EGL "egl"
|
||||
|
||||
#define PROFILE_NAME_CORE "core"
|
||||
#define PROFILE_NAME_COMPAT "compat"
|
||||
|
||||
@ -60,6 +63,9 @@ static void usage(void)
|
||||
printf(" -b, --behavior=BEHAVIOR the release behavior to use ("
|
||||
BEHAVIOR_NAME_NONE " or "
|
||||
BEHAVIOR_NAME_FLUSH ")\n");
|
||||
printf(" -c, --context-api=API the context creation API to use ("
|
||||
API_NAME_NATIVE " or "
|
||||
API_NAME_EGL ")\n");
|
||||
printf(" -d, --debug request a debug context\n");
|
||||
printf(" -f, --forward require a forward-compatible context\n");
|
||||
printf(" -h, --help show this help\n");
|
||||
@ -165,15 +171,15 @@ static const char* get_strategy_name_glfw(int strategy)
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static void list_context_extensions(int api, int major, int minor)
|
||||
static void list_context_extensions(int client, int major, int minor)
|
||||
{
|
||||
int i;
|
||||
GLint count;
|
||||
const GLubyte* extensions;
|
||||
|
||||
printf("%s context extensions:\n", get_api_name(api));
|
||||
printf("%s context extensions:\n", get_api_name(client));
|
||||
|
||||
if (api == GLFW_OPENGL_API && major > 2)
|
||||
if (client == GLFW_OPENGL_API && major > 2)
|
||||
{
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
|
||||
|
||||
@ -351,13 +357,13 @@ static void print_version(void)
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int ch, api, major, minor, revision, profile;
|
||||
int ch, client, context, major, minor, revision, profile;
|
||||
GLint redbits, greenbits, bluebits, alphabits, depthbits, stencilbits;
|
||||
int list_extensions = GLFW_FALSE, list_layers = GLFW_FALSE;
|
||||
GLenum error;
|
||||
GLFWwindow* window;
|
||||
|
||||
enum { API, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS, LAYERS,
|
||||
enum { CLIENT, CONTEXT, BEHAVIOR, DEBUG, FORWARD, HELP, EXTENSIONS, LAYERS,
|
||||
MAJOR, MINOR, PROFILE, ROBUSTNESS, VERSION,
|
||||
REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS,
|
||||
ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS,
|
||||
@ -365,7 +371,8 @@ int main(int argc, char** argv)
|
||||
const struct option options[] =
|
||||
{
|
||||
{ "behavior", 1, NULL, BEHAVIOR },
|
||||
{ "client-api", 1, NULL, API },
|
||||
{ "client-api", 1, NULL, CLIENT },
|
||||
{ "context-api", 1, NULL, CONTEXT },
|
||||
{ "debug", 0, NULL, DEBUG },
|
||||
{ "forward", 0, NULL, FORWARD },
|
||||
{ "help", 0, NULL, HELP },
|
||||
@ -410,7 +417,7 @@ int main(int argc, char** argv)
|
||||
switch (ch)
|
||||
{
|
||||
case 'a':
|
||||
case API:
|
||||
case CLIENT:
|
||||
if (strcasecmp(optarg, API_NAME_OPENGL) == 0)
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
|
||||
else if (strcasecmp(optarg, API_NAME_OPENGL_ES) == 0)
|
||||
@ -439,6 +446,18 @@ int main(int argc, char** argv)
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
case CONTEXT:
|
||||
if (strcasecmp(optarg, API_NAME_NATIVE) == 0)
|
||||
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API);
|
||||
else if (strcasecmp(optarg, API_NAME_EGL) == 0)
|
||||
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
|
||||
else
|
||||
{
|
||||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
case DEBUG:
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
||||
@ -616,30 +635,31 @@ int main(int argc, char** argv)
|
||||
|
||||
// Report client API version
|
||||
|
||||
api = glfwGetWindowAttrib(window, GLFW_CLIENT_API);
|
||||
client = glfwGetWindowAttrib(window, GLFW_CLIENT_API);
|
||||
context = glfwGetWindowAttrib(window, GLFW_CONTEXT_CREATION_API);
|
||||
major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
|
||||
minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
|
||||
revision = glfwGetWindowAttrib(window, GLFW_CONTEXT_REVISION);
|
||||
profile = glfwGetWindowAttrib(window, GLFW_OPENGL_PROFILE);
|
||||
|
||||
printf("%s context version string: \"%s\"\n",
|
||||
get_api_name(api),
|
||||
get_api_name(client),
|
||||
glGetString(GL_VERSION));
|
||||
|
||||
printf("%s context version parsed by GLFW: %u.%u.%u\n",
|
||||
get_api_name(api),
|
||||
get_api_name(client),
|
||||
major, minor, revision);
|
||||
|
||||
// Report client API context properties
|
||||
|
||||
if (api == GLFW_OPENGL_API)
|
||||
if (client == GLFW_OPENGL_API)
|
||||
{
|
||||
if (major >= 3)
|
||||
{
|
||||
GLint flags;
|
||||
|
||||
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
|
||||
printf("%s context flags (0x%08x):", get_api_name(api), flags);
|
||||
printf("%s context flags (0x%08x):", get_api_name(client), flags);
|
||||
|
||||
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
|
||||
printf(" forward-compatible");
|
||||
@ -651,7 +671,7 @@ int main(int argc, char** argv)
|
||||
printf(" no-error");
|
||||
putchar('\n');
|
||||
|
||||
printf("%s context flags parsed by GLFW:", get_api_name(api));
|
||||
printf("%s context flags parsed by GLFW:", get_api_name(client));
|
||||
|
||||
if (glfwGetWindowAttrib(window, GLFW_OPENGL_FORWARD_COMPAT))
|
||||
printf(" forward-compatible");
|
||||
@ -670,12 +690,12 @@ int main(int argc, char** argv)
|
||||
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
|
||||
|
||||
printf("%s profile mask (0x%08x): %s\n",
|
||||
get_api_name(api),
|
||||
get_api_name(client),
|
||||
mask,
|
||||
get_profile_name_gl(mask));
|
||||
|
||||
printf("%s profile mask parsed by GLFW: %s\n",
|
||||
get_api_name(api),
|
||||
get_api_name(client),
|
||||
get_profile_name_glfw(profile));
|
||||
}
|
||||
|
||||
@ -686,33 +706,33 @@ int main(int argc, char** argv)
|
||||
glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB, &strategy);
|
||||
|
||||
printf("%s robustness strategy (0x%08x): %s\n",
|
||||
get_api_name(api),
|
||||
get_api_name(client),
|
||||
strategy,
|
||||
get_strategy_name_gl(strategy));
|
||||
|
||||
printf("%s robustness strategy parsed by GLFW: %s\n",
|
||||
get_api_name(api),
|
||||
get_api_name(client),
|
||||
get_strategy_name_glfw(robustness));
|
||||
}
|
||||
}
|
||||
|
||||
printf("%s context renderer string: \"%s\"\n",
|
||||
get_api_name(api),
|
||||
get_api_name(client),
|
||||
glGetString(GL_RENDERER));
|
||||
printf("%s context vendor string: \"%s\"\n",
|
||||
get_api_name(api),
|
||||
get_api_name(client),
|
||||
glGetString(GL_VENDOR));
|
||||
|
||||
if (major >= 2)
|
||||
{
|
||||
printf("%s context shading language version: \"%s\"\n",
|
||||
get_api_name(api),
|
||||
get_api_name(client),
|
||||
glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
}
|
||||
|
||||
printf("%s framebuffer:\n", get_api_name(api));
|
||||
printf("%s framebuffer:\n", get_api_name(client));
|
||||
|
||||
if (api == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE)
|
||||
if (client == GLFW_OPENGL_API && profile == GLFW_OPENGL_CORE_PROFILE)
|
||||
{
|
||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER,
|
||||
GL_BACK_LEFT,
|
||||
@ -752,7 +772,7 @@ int main(int argc, char** argv)
|
||||
printf(" red: %u green: %u blue: %u alpha: %u depth: %u stencil: %u\n",
|
||||
redbits, greenbits, bluebits, alphabits, depthbits, stencilbits);
|
||||
|
||||
if (api == GLFW_OPENGL_ES_API ||
|
||||
if (client == GLFW_OPENGL_ES_API ||
|
||||
glfwExtensionSupported("GL_ARB_multisample") ||
|
||||
major > 1 || minor >= 3)
|
||||
{
|
||||
@ -763,7 +783,7 @@ int main(int argc, char** argv)
|
||||
printf(" samples: %u sample buffers: %u\n", samples, samplebuffers);
|
||||
}
|
||||
|
||||
if (api == GLFW_OPENGL_API && profile != GLFW_OPENGL_CORE_PROFILE)
|
||||
if (client == GLFW_OPENGL_API && profile != GLFW_OPENGL_CORE_PROFILE)
|
||||
{
|
||||
GLint accumredbits, accumgreenbits, accumbluebits, accumalphabits;
|
||||
GLint auxbuffers;
|
||||
@ -779,7 +799,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
if (list_extensions)
|
||||
list_context_extensions(api, major, minor);
|
||||
list_context_extensions(client, major, minor);
|
||||
|
||||
printf("Vulkan loader: %s\n",
|
||||
glfwVulkanSupported() ? "available" : "missing");
|
||||
|
Loading…
Reference in New Issue
Block a user