Working on UWP support
Support Universal Windows Platform (UWP): - Windows 10 App - Windows Phone - Xbox One
This commit is contained in:
parent
e12182f59b
commit
b6b58991e6
31 changed files with 6202 additions and 97 deletions
210
src/core.c
210
src/core.c
|
@ -3,13 +3,14 @@
|
|||
* raylib.core - Basic functions to manage windows, OpenGL context and input on multiple platforms
|
||||
*
|
||||
* PLATFORMS SUPPORTED:
|
||||
* - Windows (Win32, Win64)
|
||||
* - Linux (tested on Ubuntu)
|
||||
* - FreeBSD
|
||||
* - OSX/macOS
|
||||
* - Android (ARM, ARM64)
|
||||
* - Raspberry Pi (Raspbian)
|
||||
* - HTML5 (Chrome, Firefox)
|
||||
* - PLATFORM_DESKTOP: Windows (Win32, Win64)
|
||||
* - PLATFORM_DESKTOP: Linux (X11 desktop mode)
|
||||
* - PLATFORM_DESKTOP: FreeBSD (X11 desktop)
|
||||
* - PLATFORM_DESKTOP: OSX/macOS
|
||||
* - PLATFORM_ANDROID: Android 4.0 (ARM, ARM64)
|
||||
* - PLATFORM_RPI: Raspberry Pi 0,1,2,3 (Raspbian)
|
||||
* - PLATFORM_WEB: HTML5 with asm.js (Chrome, Firefox)
|
||||
* - PLATFORM_UWP: Windows 10 App, Windows Phone, Xbox One
|
||||
*
|
||||
* CONFIGURATION:
|
||||
*
|
||||
|
@ -29,6 +30,10 @@
|
|||
* Windowing and input system configured for HTML5 (run on browser), code converted from C to asm.js
|
||||
* using emscripten compiler. OpenGL ES 2.0 required for direct translation to WebGL equivalent code.
|
||||
*
|
||||
* #define PLATFORM_UWP
|
||||
* Universal Windows Platform support, using OpenGL ES 2.0 through ANGLE on multiple Windows platforms,
|
||||
* including Windows 10 App, Windows Phone and Xbox One platforms.
|
||||
*
|
||||
* #define SUPPORT_DEFAULT_FONT (default)
|
||||
* Default font is loaded on window initialization to be available for the user to render simple text.
|
||||
* NOTE: If enabled, uses external module functions to load default raylib font (module: text)
|
||||
|
@ -184,6 +189,12 @@
|
|||
#include "GLES2/gl2.h" // Khronos OpenGL ES 2.0 library
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_UWP)
|
||||
#include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions
|
||||
#include "EGL/eglext.h" // Khronos EGL library - Extensions
|
||||
#include "GLES2/gl2.h" // Khronos OpenGL ES 2.0 library
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
|
@ -223,9 +234,10 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
static GLFWwindow *window; // Native window (graphic device)
|
||||
static bool windowMinimized = false;
|
||||
#endif
|
||||
|
||||
static bool windowMinimized = false;
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
static struct android_app *app; // Android activity
|
||||
static struct android_poll_source *source; // Android events polling source
|
||||
|
@ -261,7 +273,7 @@ static pthread_t gamepadThreadId; // Gamepad reading thread id
|
|||
static char gamepadName[64]; // Gamepad name holder
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
|
||||
static EGLDisplay display; // Native display device (physical screen connection)
|
||||
static EGLSurface surface; // Surface to draw on, framebuffers (connected to context)
|
||||
static EGLContext context; // Graphic context, mode in which drawing can be done
|
||||
|
@ -270,6 +282,10 @@ static uint64_t baseTime; // Base time measure for hi-res timer
|
|||
static bool windowShouldClose = false; // Flag to set window for closing
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_UWP)
|
||||
static EGLNativeWindowType uwpWindow;
|
||||
#endif
|
||||
|
||||
// Display size-related data
|
||||
static unsigned int displayWidth, displayHeight; // Display width and height (monitor, device-screen, LCD, ...)
|
||||
static int screenWidth, screenHeight; // Screen width and height (used render area)
|
||||
|
@ -279,7 +295,7 @@ static int renderOffsetY = 0; // Offset Y from render area (must b
|
|||
static bool fullscreen = false; // Fullscreen mode (useful only for PLATFORM_DESKTOP)
|
||||
static Matrix downscaleView; // Matrix to downscale view (in case screen size bigger than display size)
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) || defined(PLATFORM_UWP)
|
||||
static const char *windowTitle; // Window text title...
|
||||
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
|
||||
static bool cursorHidden = false; // Track if cursor is hidden
|
||||
|
@ -399,6 +415,10 @@ static void InitGamepad(void); // Init raw gamepad inpu
|
|||
static void *GamepadThread(void *arg); // Mouse reading thread
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_UWP)
|
||||
// Define functions required to manage inputs
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
// NOTE: We include Sleep() function signature here to avoid windows.h inclusion
|
||||
void __stdcall Sleep(unsigned long msTimeout); // Required for Wait()
|
||||
|
@ -407,14 +427,19 @@ static void *GamepadThread(void *arg); // Mouse reading thread
|
|||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition - Window and OpenGL Context Functions
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) || defined(PLATFORM_UWP)
|
||||
// Initialize window and OpenGL context
|
||||
void InitWindow(int width, int height, const char *title)
|
||||
void InitWindow(int width, int height, void *data)
|
||||
{
|
||||
TraceLog(LOG_INFO, "Initializing raylib (v1.8.0)");
|
||||
|
||||
// Store window title (could be useful...)
|
||||
windowTitle = title;
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
windowTitle = (char *)data;
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_UWP)
|
||||
uwpWindow = (EGLNativeWindowType)data;
|
||||
#endif
|
||||
|
||||
// Init graphics device (display device and OpenGL context)
|
||||
InitGraphicsDevice(width, height);
|
||||
|
@ -558,7 +583,7 @@ void CloseWindow(void)
|
|||
timeEndPeriod(1); // Restore time period
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
|
||||
// Close surface, context and display
|
||||
if (display != EGL_NO_DISPLAY)
|
||||
{
|
||||
|
@ -606,7 +631,7 @@ bool WindowShouldClose(void)
|
|||
return (glfwWindowShouldClose(window));
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
|
||||
return windowShouldClose;
|
||||
#endif
|
||||
}
|
||||
|
@ -614,7 +639,7 @@ bool WindowShouldClose(void)
|
|||
// Check if window has been minimized (or lost focus)
|
||||
bool IsWindowMinimized(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) || defined(PLATFORM_UWP)
|
||||
return windowMinimized;
|
||||
#else
|
||||
return false;
|
||||
|
@ -681,7 +706,7 @@ void SetWindowMonitor(int monitor)
|
|||
|
||||
if ((monitor >= 0) && (monitor < monitorCount))
|
||||
{
|
||||
glfwSetWindowMonitor(window, monitors[monitor], 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE);
|
||||
//glfwSetWindowMonitor(window, monitors[monitor], 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE);
|
||||
TraceLog(LOG_INFO, "Selected fullscreen monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor]));
|
||||
}
|
||||
else TraceLog(LOG_WARNING, "Selected monitor not found");
|
||||
|
@ -1833,7 +1858,7 @@ static void InitGraphicsDevice(int width, int height)
|
|||
}
|
||||
#endif // defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
|
||||
fullscreen = true;
|
||||
|
||||
// Screen size security check
|
||||
|
@ -1876,12 +1901,151 @@ static void InitGraphicsDevice(int width, int height)
|
|||
EGL_NONE
|
||||
};
|
||||
|
||||
EGLint contextAttribs[] =
|
||||
const EGLint contextAttribs[] =
|
||||
{
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
#if defined(PLATFORM_UWP)
|
||||
const EGLint surfaceAttributes[] =
|
||||
{
|
||||
// EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER is part of the same optimization as EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER (see above).
|
||||
// If you have compilation issues with it then please update your Visual Studio templates.
|
||||
EGL_ANGLE_SURFACE_RENDER_TO_BACK_BUFFER, EGL_TRUE,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
const EGLint defaultDisplayAttributes[] =
|
||||
{
|
||||
// These are the default display attributes, used to request ANGLE's D3D11 renderer.
|
||||
// eglInitialize will only succeed with these attributes if the hardware supports D3D11 Feature Level 10_0+.
|
||||
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
|
||||
|
||||
// EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices.
|
||||
// Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it.
|
||||
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
|
||||
|
||||
// EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call
|
||||
// the IDXGIDevice3::Trim method on behalf of the application when it gets suspended.
|
||||
// Calling IDXGIDevice3::Trim when an application is suspended is a Windows Store application certification requirement.
|
||||
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
|
||||
EGL_NONE,
|
||||
};
|
||||
|
||||
const EGLint fl9_3DisplayAttributes[] =
|
||||
{
|
||||
// These can be used to request ANGLE's D3D11 renderer, with D3D11 Feature Level 9_3.
|
||||
// These attributes are used if the call to eglInitialize fails with the default display attributes.
|
||||
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
|
||||
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9,
|
||||
EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, 3,
|
||||
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
|
||||
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
|
||||
EGL_NONE,
|
||||
};
|
||||
|
||||
const EGLint warpDisplayAttributes[] =
|
||||
{
|
||||
// These attributes can be used to request D3D11 WARP.
|
||||
// They are used if eglInitialize fails with both the default display attributes and the 9_3 display attributes.
|
||||
EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
|
||||
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE,
|
||||
EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
|
||||
EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, EGL_TRUE,
|
||||
EGL_NONE,
|
||||
};
|
||||
|
||||
EGLConfig config = NULL;
|
||||
|
||||
// eglGetPlatformDisplayEXT is an alternative to eglGetDisplay. It allows us to pass in display attributes, used to configure D3D11.
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)(eglGetProcAddress("eglGetPlatformDisplayEXT"));
|
||||
if (!eglGetPlatformDisplayEXT) TraceLog(LOG_ERROR, "Failed to get function eglGetPlatformDisplayEXT");
|
||||
|
||||
//
|
||||
// To initialize the display, we make three sets of calls to eglGetPlatformDisplayEXT and eglInitialize, with varying
|
||||
// parameters passed to eglGetPlatformDisplayEXT:
|
||||
// 1) The first calls uses "defaultDisplayAttributes" as a parameter. This corresponds to D3D11 Feature Level 10_0+.
|
||||
// 2) If eglInitialize fails for step 1 (e.g. because 10_0+ isn't supported by the default GPU), then we try again
|
||||
// using "fl9_3DisplayAttributes". This corresponds to D3D11 Feature Level 9_3.
|
||||
// 3) If eglInitialize fails for step 2 (e.g. because 9_3+ isn't supported by the default GPU), then we try again
|
||||
// using "warpDisplayAttributes". This corresponds to D3D11 Feature Level 11_0 on WARP, a D3D11 software rasterizer.
|
||||
//
|
||||
|
||||
// This tries to initialize EGL to D3D11 Feature Level 10_0+. See above comment for details.
|
||||
display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, defaultDisplayAttributes);
|
||||
if (display == EGL_NO_DISPLAY) TraceLog(LOG_ERROR, "Failed to get EGL display");
|
||||
|
||||
if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
|
||||
{
|
||||
// This tries to initialize EGL to D3D11 Feature Level 9_3, if 10_0+ is unavailable (e.g. on some mobile devices).
|
||||
display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, fl9_3DisplayAttributes);
|
||||
if (display == EGL_NO_DISPLAY) TraceLog(LOG_ERROR, "Failed to get EGL display");
|
||||
|
||||
if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
|
||||
{
|
||||
// This initializes EGL to D3D11 Feature Level 11_0 on WARP, if 9_3+ is unavailable on the default GPU.
|
||||
display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, warpDisplayAttributes);
|
||||
if (display == EGL_NO_DISPLAY) TraceLog(LOG_ERROR, "Failed to get EGL display");
|
||||
|
||||
if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
|
||||
{
|
||||
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
|
||||
TraceLog(LOG_ERROR, "Failed to initialize EGL");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//SetupFramebufferSize(displayWidth, displayHeight);
|
||||
|
||||
EGLint numConfigs = 0;
|
||||
if ((eglChooseConfig(display, framebufferAttribs, &config, 1, &numConfigs) == EGL_FALSE) || (numConfigs == 0))
|
||||
{
|
||||
TraceLog(LOG_ERROR, "Failed to choose first EGLConfig");
|
||||
}
|
||||
|
||||
// Create a PropertySet and initialize with the EGLNativeWindowType.
|
||||
//PropertySet^ surfaceCreationProperties = ref new PropertySet();
|
||||
//surfaceCreationProperties->Insert(ref new String(EGLNativeWindowTypeProperty), window); // CoreWindow^ window
|
||||
|
||||
// You can configure the surface to render at a lower resolution and be scaled up to
|
||||
// the full window size. The scaling is often free on mobile hardware.
|
||||
//
|
||||
// One way to configure the SwapChainPanel is to specify precisely which resolution it should render at.
|
||||
// Size customRenderSurfaceSize = Size(800, 600);
|
||||
// surfaceCreationProperties->Insert(ref new String(EGLRenderSurfaceSizeProperty), PropertyValue::CreateSize(customRenderSurfaceSize));
|
||||
//
|
||||
// Another way is to tell the SwapChainPanel to render at a certain scale factor compared to its size.
|
||||
// e.g. if the SwapChainPanel is 1920x1280 then setting a factor of 0.5f will make the app render at 960x640
|
||||
// float customResolutionScale = 0.5f;
|
||||
// surfaceCreationProperties->Insert(ref new String(EGLRenderResolutionScaleProperty), PropertyValue::CreateSingle(customResolutionScale));
|
||||
|
||||
|
||||
// eglCreateWindowSurface() requires a EGLNativeWindowType parameter,
|
||||
// In Windows platform: typedef HWND EGLNativeWindowType;
|
||||
|
||||
|
||||
// Property: EGLNativeWindowTypeProperty
|
||||
// Type: IInspectable
|
||||
// Description: Set this property to specify the window type to use for creating a surface.
|
||||
// If this property is missing, surface creation will fail.
|
||||
//
|
||||
//const wchar_t EGLNativeWindowTypeProperty[] = L"EGLNativeWindowTypeProperty";
|
||||
|
||||
//https://stackoverflow.com/questions/46550182/how-to-create-eglsurface-using-c-winrt-and-angle
|
||||
|
||||
//surface = eglCreateWindowSurface(display, config, reinterpret_cast<IInspectable*>(surfaceCreationProperties), surfaceAttributes);
|
||||
surface = eglCreateWindowSurface(display, config, uwpWindow, surfaceAttributes);
|
||||
if (surface == EGL_NO_SURFACE) TraceLog(LOG_ERROR, "Failed to create EGL fullscreen surface");
|
||||
|
||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
|
||||
if (context == EGL_NO_CONTEXT) TraceLog(LOG_ERROR, "Failed to create EGL context");
|
||||
|
||||
// Get EGL display window size
|
||||
eglQuerySurface(display, surface, EGL_WIDTH, &screenWidth);
|
||||
eglQuerySurface(display, surface, EGL_HEIGHT, &screenHeight);
|
||||
|
||||
#else // PLATFORM_ANDROID, PLATFORM_RPI
|
||||
EGLint numConfigs;
|
||||
|
||||
// Get an EGL display connection
|
||||
|
@ -1898,6 +2062,7 @@ static void InitGraphicsDevice(int width, int height)
|
|||
|
||||
// Create an EGL rendering context
|
||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
|
||||
#endif
|
||||
|
||||
// Create an EGL window surface
|
||||
//---------------------------------------------------------------------------------
|
||||
|
@ -1981,6 +2146,9 @@ static void InitGraphicsDevice(int width, int height)
|
|||
}
|
||||
#endif // defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
|
||||
renderWidth = screenWidth;
|
||||
renderHeight = screenHeight;
|
||||
|
||||
// Initialize OpenGL context (states and resources)
|
||||
// NOTE: screenWidth and screenHeight not used, just stored as globals
|
||||
rlglInit(screenWidth, screenHeight);
|
||||
|
@ -2365,7 +2533,7 @@ static void SwapBuffers(void)
|
|||
glfwSwapBuffers(window);
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
|
||||
eglSwapBuffers(display, surface);
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue