From 749117acd927076bbfd3237d0a4ed26a5965b56a Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Mon, 4 Nov 2013 19:54:29 -0500 Subject: [PATCH] WinRT: added experimental OpenGL ES 2.0 support A port of the ANGLE library (OpenGL ES 2.0 for Direct3D) to WinRT, via https://github.com/stammen/angleproject, is used as a base. To enable, clone 'angleproject' into the directory one above where SDL/WinRT is, open the file SDL/include/SDL_config_winrt.h, and uncomment the #defines that begin with 'SDL_VIDEO_OPENGL'. From there, apps can create an OpenGL capable SDL_Window via the flag, SDL_WINDOW_OPENGL, and an OpenGL ES 2 context via SDL_GL_CreateContext. The Direct3D 11.1 renderer cannot be used alongside SDL_WINDOW_OPENGL. Only Windows 8/8.1 is supported for now. Shaders may need to be precompiled, in some (all?) cases. --- VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj | 25 ++- .../SDL/SDL-WinRT_VS2012.vcxproj.filters | 18 ++ include/SDL_config_winrt.h | 9 + include/SDL_opengles2.h | 2 + src/video/SDL_egl.c | 16 ++ src/video/SDL_egl.h | 70 +++++--- src/video/SDL_video.c | 2 +- src/video/winrt/SDL_winrtegl.h | 166 ++++++++++++++++++ src/video/winrt/SDL_winrtopengles.cpp | 55 ++++++ src/video/winrt/SDL_winrtopengles.h | 48 +++++ src/video/winrt/SDL_winrtvideo.cpp | 34 ++++ src/video/winrt/SDL_winrtvideo_cpp.h | 9 + 12 files changed, 419 insertions(+), 35 deletions(-) create mode 100644 src/video/winrt/SDL_winrtegl.h create mode 100644 src/video/winrt/SDL_winrtopengles.cpp create mode 100644 src/video/winrt/SDL_winrtopengles.h diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj index e50293e2468c4..a7ffb4d5fd61c 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj @@ -145,6 +145,7 @@ + @@ -177,6 +178,14 @@ true true + + true + true + true + true + true + true + true true @@ -224,6 +233,7 @@ + @@ -299,13 +309,16 @@ + + + @@ -448,7 +461,7 @@ NotUsing false - ..\..\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -462,7 +475,7 @@ NotUsing false - ..\..\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -476,7 +489,7 @@ NotUsing false - ..\..\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -490,7 +503,7 @@ NotUsing false - ..\..\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -504,7 +517,7 @@ NotUsing false - ..\..\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) @@ -518,7 +531,7 @@ NotUsing false - ..\..\include;%(AdditionalIncludeDirectories) + ..\..\include;..\..\..\angleproject\include;%(AdditionalIncludeDirectories) _WINDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) diff --git a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters index 8a7f94d5363ce..82cbcb34463bd 100644 --- a/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters +++ b/VisualC-WinRT/SDL/SDL-WinRT_VS2012.vcxproj.filters @@ -279,6 +279,12 @@ Source Files + + Source Files + + + Source Files + @@ -617,6 +623,18 @@ Header Files + + Source Files + + + Source Files + + + Source Files + + + Header Files + diff --git a/include/SDL_config_winrt.h b/include/SDL_config_winrt.h index 712a9149fa611..210d1e6607831 100644 --- a/include/SDL_config_winrt.h +++ b/include/SDL_config_winrt.h @@ -166,6 +166,15 @@ typedef unsigned int uintptr_t; #define SDL_VIDEO_DRIVER_WINRT 1 #define SDL_VIDEO_DRIVER_DUMMY 1 +/* Enable OpenGL ES 2.0 (via a modified ANGLE library) */ +#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP /* TODO, WinRT: try adding OpenGL ES 2 support for Windows Phone 8 */ +/* Uncomment the following two #defines to enable experimental OpenGL ES 2 support + (via a WinRT port of the ANGLE library). +*/ +//#define SDL_VIDEO_OPENGL_ES2 1 +//#define SDL_VIDEO_OPENGL_EGL 1 +#endif + // TODO, WinRT: Get a Direct3D 11 based renderer working in SDL. /* Enable appropriate renderer(s) */ #define SDL_VIDEO_RENDER_D3D11 1 diff --git a/include/SDL_opengles2.h b/include/SDL_opengles2.h index 7697626f4a95a..d090c8db7facc 100644 --- a/include/SDL_opengles2.h +++ b/include/SDL_opengles2.h @@ -33,6 +33,8 @@ #include #endif +#ifndef __WINRT__ #ifndef APIENTRY #define APIENTRY #endif +#endif diff --git a/src/video/SDL_egl.c b/src/video/SDL_egl.c index ccfb92e180dba..6d4130bd456dd 100644 --- a/src/video/SDL_egl.c +++ b/src/video/SDL_egl.c @@ -40,6 +40,13 @@ #define DEFAULT_OGL_ES_PVR "libGLES_CM.so" #define DEFAULT_OGL_ES "libGLESv1_CM.so" +#elif SDL_VIDEO_DRIVER_WINRT +/* WinRT (via a modified version of Google's ANGLE library) */ +#define DEFAULT_EGL "libEGL.dll" +#define DEFAULT_OGL_ES2 "libGLESv2.dll" +#define DEFAULT_OGL_ES_PVR NULL +#define DEFAULT_OGL_ES NULL + #else /* Desktop Linux */ #define DEFAULT_EGL "libEGL.so.1" @@ -134,8 +141,13 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa #endif /* A funny thing, loading EGL.so first does not work on the Raspberry, so we load libGL* first */ +#ifdef __WINRT__ + path = NULL; + egl_dll_handle = NULL; +#else path = getenv("SDL_VIDEO_GL_DRIVER"); egl_dll_handle = dlopen(path, dlopen_flags); +#endif if ((path == NULL) | (egl_dll_handle == NULL)) { if (_this->gl_config.major_version > 1) { path = DEFAULT_OGL_ES2; @@ -160,7 +172,11 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa /* Catch the case where the application isn't linked with EGL */ if ((dlsym(dll_handle, "eglChooseConfig") == NULL) && (egl_path == NULL)) { dlclose(dll_handle); +#ifdef __WINRT__ + path = NULL; +#else path = getenv("SDL_VIDEO_EGL_DRIVER"); +#endif if (path == NULL) { path = DEFAULT_EGL; } diff --git a/src/video/SDL_egl.h b/src/video/SDL_egl.h index d6139058d6940..00bb26f5a8ea6 100644 --- a/src/video/SDL_egl.h +++ b/src/video/SDL_egl.h @@ -25,6 +25,18 @@ #if SDL_VIDEO_OPENGL_EGL +#if defined(__WINRT__) + +// DavidL: including this here leads to a compiler error: +// C2016: C requires that a struct or union has at least one member +// The error originates from a WinRT header file itself, roapi.h. +// +// Instead of including that file (EGL/egl.h), a subset of its contents is +// made available as part of winrt/SDL_winrtegl.h +//#include +#include "winrt/SDL_winrtegl.h" + +#else #include #include @@ -32,6 +44,8 @@ #define dlsym(x,y) dlsym(x, "_" y) #endif +#endif /* ! defined(__WINRT__) */ + #include "SDL_sysvideo.h" typedef struct SDL_EGL_VideoData @@ -41,46 +55,46 @@ typedef struct SDL_EGL_VideoData EGLConfig egl_config; int egl_swapinterval; - EGLDisplay(*eglGetDisplay) (NativeDisplayType display); - EGLBoolean(*eglInitialize) (EGLDisplay dpy, EGLint * major, - EGLint * minor); - EGLBoolean(*eglTerminate) (EGLDisplay dpy); + EGLDisplay(EGLAPIENTRY *eglGetDisplay) (NativeDisplayType display); + EGLBoolean(EGLAPIENTRY *eglInitialize) (EGLDisplay dpy, EGLint * major, + EGLint * minor); + EGLBoolean(EGLAPIENTRY *eglTerminate) (EGLDisplay dpy); - void *(*eglGetProcAddress) (const char * procName); + void *(EGLAPIENTRY *eglGetProcAddress) (const char * procName); - EGLBoolean(*eglChooseConfig) (EGLDisplay dpy, - const EGLint * attrib_list, - EGLConfig * configs, - EGLint config_size, EGLint * num_config); + EGLBoolean(EGLAPIENTRY *eglChooseConfig) (EGLDisplay dpy, + const EGLint * attrib_list, + EGLConfig * configs, + EGLint config_size, EGLint * num_config); - EGLContext(*eglCreateContext) (EGLDisplay dpy, - EGLConfig config, - EGLContext share_list, - const EGLint * attrib_list); + EGLContext(EGLAPIENTRY *eglCreateContext) (EGLDisplay dpy, + EGLConfig config, + EGLContext share_list, + const EGLint * attrib_list); - EGLBoolean(*eglDestroyContext) (EGLDisplay dpy, EGLContext ctx); + EGLBoolean(EGLAPIENTRY *eglDestroyContext) (EGLDisplay dpy, EGLContext ctx); - EGLSurface(*eglCreateWindowSurface) (EGLDisplay dpy, - EGLConfig config, - NativeWindowType window, - const EGLint * attrib_list); - EGLBoolean(*eglDestroySurface) (EGLDisplay dpy, EGLSurface surface); + EGLSurface(EGLAPIENTRY *eglCreateWindowSurface) (EGLDisplay dpy, + EGLConfig config, + NativeWindowType window, + const EGLint * attrib_list); + EGLBoolean(EGLAPIENTRY *eglDestroySurface) (EGLDisplay dpy, EGLSurface surface); - EGLBoolean(*eglMakeCurrent) (EGLDisplay dpy, EGLSurface draw, - EGLSurface read, EGLContext ctx); + EGLBoolean(EGLAPIENTRY *eglMakeCurrent) (EGLDisplay dpy, EGLSurface draw, + EGLSurface read, EGLContext ctx); - EGLBoolean(*eglSwapBuffers) (EGLDisplay dpy, EGLSurface draw); + EGLBoolean(EGLAPIENTRY *eglSwapBuffers) (EGLDisplay dpy, EGLSurface draw); - EGLBoolean(*eglSwapInterval) (EGLDisplay dpy, EGLint interval); + EGLBoolean(EGLAPIENTRY *eglSwapInterval) (EGLDisplay dpy, EGLint interval); - const char *(*eglQueryString) (EGLDisplay dpy, EGLint name); + const char *(EGLAPIENTRY *eglQueryString) (EGLDisplay dpy, EGLint name); - EGLBoolean(*eglGetConfigAttrib) (EGLDisplay dpy, EGLConfig config, - EGLint attribute, EGLint * value); + EGLBoolean(EGLAPIENTRY *eglGetConfigAttrib) (EGLDisplay dpy, EGLConfig config, + EGLint attribute, EGLint * value); - EGLBoolean(*eglWaitNative) (EGLint engine); + EGLBoolean(EGLAPIENTRY *eglWaitNative) (EGLint engine); - EGLBoolean(*eglWaitGL)(void); + EGLBoolean(EGLAPIENTRY *eglWaitGL)(void); } SDL_EGL_VideoData; /* OpenGLES functions */ diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 5c1c6d3f7c73b..e255f4bbf4aa3 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -41,7 +41,7 @@ /* GL and GLES2 headers conflict on Linux 32 bits */ #if SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL -#include "SDL_opengles2.h" +#include "SDL_opengles2.h" #endif /* SDL_VIDEO_OPENGL_ES2 && !SDL_VIDEO_OPENGL */ #include "SDL_syswm.h" diff --git a/src/video/winrt/SDL_winrtegl.h b/src/video/winrt/SDL_winrtegl.h new file mode 100644 index 0000000000000..4ce55be962b59 --- /dev/null +++ b/src/video/winrt/SDL_winrtegl.h @@ -0,0 +1,166 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + +#include "SDL_config.h" + +#ifndef _SDL_winrtegl_h +#define _SDL_winrtegl_h + +#include "SDL_hints.h" +#include "SDL_loadso.h" + +#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL + +/* Emulate various *nix functions that SDL_egl.c will call. + */ +#define dlsym SDL_LoadFunction +#define dlclose SDL_UnloadObject +#define dlopen(path, mode) ((path == NULL) ? NULL : SDL_LoadObject(path)) /* TODO, WinRT: create a separate function here, that sets dlerror on empty params */ +#define dlerror SDL_GetError +#define getenv SDL_GetHint +#define RTLD_LAZY 0 + + +/* +** Copyright (c) 2007-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* EGL Types */ +/* EGLint is defined in eglplatform.h */ +typedef unsigned int EGLBoolean; +typedef unsigned int EGLenum; +typedef void *EGLConfig; +typedef void *EGLContext; +typedef void *EGLDisplay; +typedef void *EGLSurface; +typedef void *EGLClientBuffer; + +/* Platform-specific types */ +//typedef int EGLNativeDisplayType; +typedef int NativeDisplayType; +typedef void * NativeWindowType; + +#ifndef EGLAPIENTRY +#define EGLAPIENTRY __stdcall +#endif + + +/* Define EGLint. This must be a signed integral type large enough to contain + * all legal attribute names and values passed into and out of EGL, whether + * their type is boolean, bitmask, enumerant (symbolic constant), integer, + * handle, or other. While in general a 32-bit integer will suffice, if + * handles are 64 bit types, then EGLint should be defined as a signed 64-bit + * integer type. + */ +typedef int EGLint; + +/* EGL Enumerants. Bitmasks and other exceptional cases aside, most + * enums are assigned unique values starting at 0x3000. + */ + +/* EGL aliases */ +#define EGL_FALSE 0 +#define EGL_TRUE 1 + +/* Out-of-band handle values */ +#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) +#define EGL_NO_CONTEXT ((EGLContext)0) +#define EGL_NO_DISPLAY ((EGLDisplay)0) +#define EGL_NO_SURFACE ((EGLSurface)0) + +/* Config attributes */ +#define EGL_BUFFER_SIZE 0x3020 +#define EGL_ALPHA_SIZE 0x3021 +#define EGL_BLUE_SIZE 0x3022 +#define EGL_GREEN_SIZE 0x3023 +#define EGL_RED_SIZE 0x3024 +#define EGL_DEPTH_SIZE 0x3025 +#define EGL_STENCIL_SIZE 0x3026 +#define EGL_CONFIG_CAVEAT 0x3027 +#define EGL_CONFIG_ID 0x3028 +#define EGL_LEVEL 0x3029 +#define EGL_MAX_PBUFFER_HEIGHT 0x302A +#define EGL_MAX_PBUFFER_PIXELS 0x302B +#define EGL_MAX_PBUFFER_WIDTH 0x302C +#define EGL_NATIVE_RENDERABLE 0x302D +#define EGL_NATIVE_VISUAL_ID 0x302E +#define EGL_NATIVE_VISUAL_TYPE 0x302F +#define EGL_SAMPLES 0x3031 +#define EGL_SAMPLE_BUFFERS 0x3032 +#define EGL_SURFACE_TYPE 0x3033 +#define EGL_TRANSPARENT_TYPE 0x3034 +#define EGL_TRANSPARENT_BLUE_VALUE 0x3035 +#define EGL_TRANSPARENT_GREEN_VALUE 0x3036 +#define EGL_TRANSPARENT_RED_VALUE 0x3037 +#define EGL_NONE 0x3038 /* Attrib list terminator */ +#define EGL_BIND_TO_TEXTURE_RGB 0x3039 +#define EGL_BIND_TO_TEXTURE_RGBA 0x303A +#define EGL_MIN_SWAP_INTERVAL 0x303B +#define EGL_MAX_SWAP_INTERVAL 0x303C +#define EGL_LUMINANCE_SIZE 0x303D +#define EGL_ALPHA_MASK_SIZE 0x303E +#define EGL_COLOR_BUFFER_TYPE 0x303F +#define EGL_RENDERABLE_TYPE 0x3040 +#define EGL_MATCH_NATIVE_PIXMAP 0x3041 /* Pseudo-attribute (not queryable) */ +#define EGL_CONFORMANT 0x3042 + +/* Config attribute mask bits */ +#define EGL_PBUFFER_BIT 0x0001 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_PIXMAP_BIT 0x0002 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_WINDOW_BIT 0x0004 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200 /* EGL_SURFACE_TYPE mask bits */ +#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400 /* EGL_SURFACE_TYPE mask bits */ + +#define EGL_OPENGL_ES_BIT 0x0001 /* EGL_RENDERABLE_TYPE mask bits */ +#define EGL_OPENVG_BIT 0x0002 /* EGL_RENDERABLE_TYPE mask bits */ +#define EGL_OPENGL_ES2_BIT 0x0004 /* EGL_RENDERABLE_TYPE mask bits */ +#define EGL_OPENGL_BIT 0x0008 /* EGL_RENDERABLE_TYPE mask bits */ + +/* CreateContext attributes */ +#define EGL_CONTEXT_CLIENT_VERSION 0x3098 + + +#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ + +#endif /* _SDL_winrtegl_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/winrt/SDL_winrtopengles.cpp b/src/video/winrt/SDL_winrtopengles.cpp new file mode 100644 index 0000000000000..bbb73d7e03ca5 --- /dev/null +++ b/src/video/winrt/SDL_winrtopengles.cpp @@ -0,0 +1,55 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_config.h" + +// TODO: WinRT, make this file compile via C code + +#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL + +/* EGL implementation of SDL OpenGL support */ + +// TODO, WinRT: Try to include these here, or via something else (rather than redefining key parts of them) +//#include +//#include +//#include + +#include "SDL_winrtvideo_cpp.h" +extern "C" { +#include "SDL_winrtopengles.h" +} + +#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((NativeDisplayType) -3) + +extern "C" int +WINRT_GLES_LoadLibrary(_THIS, const char *path) { + return SDL_EGL_LoadLibrary(_this, path, EGL_D3D11_ONLY_DISPLAY_ANGLE); +} + +extern "C" { +SDL_EGL_CreateContext_impl(WINRT) +SDL_EGL_SwapWindow_impl(WINRT) +SDL_EGL_MakeCurrent_impl(WINRT) +} + +#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ + +/* vi: set ts=4 sw=4 expandtab: */ + diff --git a/src/video/winrt/SDL_winrtopengles.h b/src/video/winrt/SDL_winrtopengles.h new file mode 100644 index 0000000000000..5c52e0cb44325 --- /dev/null +++ b/src/video/winrt/SDL_winrtopengles.h @@ -0,0 +1,48 @@ +/* + Simple DirectMedia Layer + Copyright (C) 1997-2013 Sam Lantinga + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "SDL_config.h" + +#ifndef _SDL_winrtopengles_h +#define _SDL_winrtopengles_h + +#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL + +#include "../SDL_sysvideo.h" +#include "../SDL_egl.h" + +/* OpenGLES functions */ +#define WINRT_GLES_GetAttribute SDL_EGL_GetAttribute +#define WINRT_GLES_GetProcAddress SDL_EGL_GetProcAddress +#define WINRT_GLES_UnloadLibrary SDL_EGL_UnloadLibrary +#define WINRT_GLES_SetSwapInterval SDL_EGL_SetSwapInterval +#define WINRT_GLES_GetSwapInterval SDL_EGL_GetSwapInterval +#define WINRT_GLES_DeleteContext SDL_EGL_DeleteContext + +extern int WINRT_GLES_LoadLibrary(_THIS, const char *path); +extern SDL_GLContext WINRT_GLES_CreateContext(_THIS, SDL_Window * window); +extern void WINRT_GLES_SwapWindow(_THIS, SDL_Window * window); +extern int WINRT_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context); + +#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */ + +#endif /* _SDL_winrtopengles_h */ + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index c0b75c0ebbd48..97358a966b978 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -42,6 +42,7 @@ extern "C" { #include "../../events/SDL_events_c.h" #include "../../render/SDL_sysrender.h" #include "SDL_syswm.h" +#include "SDL_winrtopengles.h" } #include "../../core/winrt/SDL_winrtapp_direct3d.h" @@ -111,6 +112,17 @@ WINRT_CreateDevice(int devindex) device->SetDisplayMode = WINRT_SetDisplayMode; device->PumpEvents = WINRT_PumpEvents; device->GetWindowWMInfo = WINRT_GetWindowWMInfo; +#ifdef SDL_VIDEO_OPENGL_EGL + device->GL_LoadLibrary = WINRT_GLES_LoadLibrary; + device->GL_GetProcAddress = WINRT_GLES_GetProcAddress; + device->GL_UnloadLibrary = WINRT_GLES_UnloadLibrary; + device->GL_CreateContext = WINRT_GLES_CreateContext; + device->GL_MakeCurrent = WINRT_GLES_MakeCurrent; + device->GL_SetSwapInterval = WINRT_GLES_SetSwapInterval; + device->GL_GetSwapInterval = WINRT_GLES_GetSwapInterval; + device->GL_SwapWindow = WINRT_GLES_SwapWindow; + device->GL_DeleteContext = WINRT_GLES_DeleteContext; +#endif device->free = WINRT_DeleteDevice; WINRT_GlobalSDLVideoDevice = device; @@ -247,6 +259,22 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) data->coreWindow = CoreWindow::GetForCurrentThread(); } +#if SDL_VIDEO_OPENGL_EGL + /* Setup the EGL surface, but only if OpenGL ES 2 was requested. */ + if (!(window->flags & SDL_WINDOW_OPENGL)) { + /* OpenGL ES 2 wasn't requested. Don't set up an EGL surface. */ + data->egl_surface = EGL_NO_SURFACE; + } else { + /* OpenGL ES 2 was reuqested. Set up an EGL surface. */ + IUnknown * nativeWindow = reinterpret_cast(data->coreWindow.Get()); + data->egl_surface = SDL_EGL_CreateSurface(_this, nativeWindow); + if (data->egl_surface == NULL) { + // TODO, WinRT: see if SDL_EGL_CreateSurface, or its callee(s), sets an error message. If so, attach it to the SDL error. + return SDL_SetError("SDL_EGL_CreateSurface failed"); + } + } +#endif + /* Make sure the window is considered to be positioned at {0,0}, and is considered fullscreen, shown, and the like. */ @@ -259,6 +287,12 @@ WINRT_CreateWindow(_THIS, SDL_Window * window) SDL_WINDOW_MAXIMIZED | SDL_WINDOW_INPUT_GRABBED; +#if SDL_VIDEO_OPENGL_EGL + if (data->egl_surface) { + window->flags |= SDL_WINDOW_OPENGL; + } +#endif + /* WinRT does not, as of this writing, appear to support app-adjustable window sizes. Set the window size to whatever the native WinRT CoreWindow is set at. diff --git a/src/video/winrt/SDL_winrtvideo_cpp.h b/src/video/winrt/SDL_winrtvideo_cpp.h index a36cc308d1aa2..f3900acfd55f5 100644 --- a/src/video/winrt/SDL_winrtvideo_cpp.h +++ b/src/video/winrt/SDL_winrtvideo_cpp.h @@ -26,8 +26,14 @@ #endif /* SDL includes: */ +#include "SDL_video.h" #include "SDL_events.h" +extern "C" { +#include "../SDL_sysvideo.h" +#include "SDL_winrtegl.h" +} + /* The global, WinRT, SDL Window. For now, SDL/WinRT only supports one window (due to platform limitations of @@ -49,6 +55,9 @@ struct SDL_WindowData { SDL_Window *sdlWindow; Platform::Agile coreWindow; +#ifdef SDL_VIDEO_OPENGL_EGL + EGLSurface egl_surface; +#endif }; #endif // ifdef __cplusplus_winrt