Update C sources and add new functions
This commit is contained in:
parent
9784968948
commit
7874621942
24 changed files with 2149 additions and 1316 deletions
499
raylib/core.c
499
raylib/core.c
|
@ -1,18 +1,16 @@
|
|||
// +build !js
|
||||
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib.core - Basic functions to manage windows, OpenGL context and input on multiple platforms
|
||||
*
|
||||
* PLATFORMS SUPPORTED:
|
||||
* PLATFORM_DESKTOP: Windows (Win32, Win64)
|
||||
* PLATFORM_DESKTOP: Linux (32 and 64 bit)
|
||||
* PLATFORM_DESKTOP: OSX/macOS
|
||||
* PLATFORM_DESKTOP: FreeBSD
|
||||
* PLATFORM_ANDROID: Android (ARM, ARM64)
|
||||
* PLATFORM_RPI: Raspberry Pi (Raspbian)
|
||||
* PLATFORM_WEB: HTML5 (Chrome, Firefox)
|
||||
* PLATFORM_UWP: Universal Windows Platform
|
||||
* PLATFORMS SUPPORTED:
|
||||
* - 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:
|
||||
*
|
||||
|
@ -32,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)
|
||||
|
@ -91,7 +93,7 @@
|
|||
|
||||
#include "raylib.h"
|
||||
|
||||
#if (defined(__linux__) || defined(PLATFORM_WEB)) && _POSIX_S_SOURCE < 199309L
|
||||
#if (defined(__linux__) || defined(PLATFORM_WEB)) && _POSIX_C_SOURCE < 199309L
|
||||
#undef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
|
||||
#endif
|
||||
|
@ -126,7 +128,7 @@
|
|||
#include <string.h> // Required for: strrchr(), strcmp()
|
||||
//#include <errno.h> // Macros for reporting and retrieving error conditions through error codes
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32)
|
||||
#include <direct.h> // Required for: _getch(), _chdir()
|
||||
#define GETCWD _getcwd // NOTE: MSDN recommends not to use getcwd(), chdir()
|
||||
#define CHDIR _chdir
|
||||
|
@ -152,11 +154,11 @@
|
|||
#include <GLFW/glfw3native.h> // which are required for hiding mouse
|
||||
#endif
|
||||
//#include <GL/gl.h> // OpenGL functions (GLFW3 already includes gl.h)
|
||||
//#define GLFW_DLL // Using GLFW DLL on Windows -> No, we use static version!
|
||||
|
||||
|
||||
#if !defined(SUPPORT_BUSY_WAIT_LOOP) && defined(_WIN32)
|
||||
__stdcall unsigned int timeBeginPeriod(unsigned int uPeriod);
|
||||
__stdcall unsigned int timeEndPeriod(unsigned int uPeriod);
|
||||
// NOTE: Those functions require linking with winmm library
|
||||
unsigned int __stdcall timeBeginPeriod(unsigned int uPeriod);
|
||||
unsigned int __stdcall timeEndPeriod(unsigned int uPeriod);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -187,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>
|
||||
|
@ -226,16 +234,17 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
static GLFWwindow *window; // Native window (graphic device)
|
||||
static bool windowMinimized = false;
|
||||
#endif
|
||||
|
||||
static bool windowReady = false; // Check if window has been initialized successfully
|
||||
static bool windowMinimized = false; // Check if window has been minimized
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
static struct android_app *app; // Android activity
|
||||
static struct android_poll_source *source; // Android events polling source
|
||||
static int ident, events; // Android ALooper_pollAll() variables
|
||||
static const char *internalDataPath; // Android internal data path to write data (/data/data/<package>/files)
|
||||
|
||||
static bool windowReady = false; // Used to detect display initialization
|
||||
static bool appEnabled = true; // Used to detec if app is active
|
||||
static bool contextRebindRequired = false; // Used to know context rebind required
|
||||
#endif
|
||||
|
@ -264,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
|
||||
|
@ -273,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)
|
||||
|
@ -281,12 +294,11 @@ static int renderOffsetX = 0; // Offset X from render area (must b
|
|||
static int renderOffsetY = 0; // Offset Y from render area (must be divided by 2)
|
||||
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)
|
||||
|
||||
static bool cursorHidden = false; // Track if cursor is hidden
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
static const char *windowTitle = NULL; // Window text title...
|
||||
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB) || defined(PLATFORM_UWP)
|
||||
static const char *windowTitle = NULL; // Window text title...
|
||||
static int screenshotCounter = 0; // Screenshots counter
|
||||
|
||||
// Register mouse states
|
||||
|
@ -331,7 +343,7 @@ static double updateTime, drawTime; // Time measures for update and draw
|
|||
static double frameTime = 0.0; // Time measure for one frame
|
||||
static double targetTime = 0.0; // Desired time for one frame, if 0 not applied
|
||||
|
||||
static char configFlags = 0; // Configuration flags (bit based)
|
||||
static unsigned char configFlags = 0; // Configuration flags (bit based)
|
||||
static bool showLogo = false; // Track if showing logo at init is enabled
|
||||
|
||||
#if defined(SUPPORT_GIF_RECORDING)
|
||||
|
@ -350,10 +362,9 @@ extern void UnloadDefaultFont(void); // [Module: text] Unloads default fo
|
|||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static void InitGraphicsDevice(int width, int height); // Initialize graphics device
|
||||
static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
|
||||
static void SetupFramebufferSize(int displayWidth, int displayHeight);
|
||||
static void InitTimer(void); // Initialize timer
|
||||
static double GetTime(void); // Returns time since InitTimer() was run
|
||||
static void Wait(float ms); // Wait for some milliseconds (stop program execution)
|
||||
static bool GetKeyStatus(int key); // Returns if a key has been pressed
|
||||
static bool GetMouseButtonStatus(int button); // Returns if a mouse button has been pressed
|
||||
|
@ -403,6 +414,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()
|
||||
|
@ -411,18 +426,28 @@ 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
|
||||
// NOTE: data parameter could be used to pass any kind of required data to the initialization
|
||||
void InitWindow(int width, int height, void *data)
|
||||
{
|
||||
TraceLog(LOG_INFO, "Initializing raylib (v1.9-dev)");
|
||||
TraceLog(LOG_INFO, "Initializing raylib (v1.9.4-dev)");
|
||||
|
||||
// Input data is window title char data
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
windowTitle = (char *)data;
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_UWP)
|
||||
uwpWindow = (EGLNativeWindowType)data;
|
||||
#endif
|
||||
|
||||
// Init hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// Init graphics device (display device and OpenGL context)
|
||||
InitGraphicsDevice(width, height);
|
||||
// NOTE: returns true if window and graphic device has been initialized successfully
|
||||
windowReady = InitGraphicsDevice(width, height);
|
||||
if (!windowReady) return;
|
||||
|
||||
#if defined(SUPPORT_DEFAULT_FONT)
|
||||
// Load default font
|
||||
|
@ -430,9 +455,6 @@ void InitWindow(int width, int height, void *data)
|
|||
LoadDefaultFont();
|
||||
#endif
|
||||
|
||||
// Init hi-res timer
|
||||
InitTimer();
|
||||
|
||||
#if defined(PLATFORM_RPI)
|
||||
// Init raw input system
|
||||
InitMouse(); // Mouse init
|
||||
|
@ -480,7 +502,7 @@ void InitWindow(int width, int height, void *data)
|
|||
// NOTE: data parameter could be used to pass any kind of required data to the initialization
|
||||
void InitWindow(int width, int height, void *data)
|
||||
{
|
||||
TraceLog(LOG_INFO, "Initializing raylib (v1.9-dev)");
|
||||
TraceLog(LOG_INFO, "Initializing raylib (v1.9.4-dev)");
|
||||
|
||||
screenWidth = width;
|
||||
screenHeight = height;
|
||||
|
@ -564,7 +586,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)
|
||||
{
|
||||
|
@ -602,25 +624,36 @@ void CloseWindow(void)
|
|||
TraceLog(LOG_INFO, "Window closed successfully");
|
||||
}
|
||||
|
||||
// Check if window has been initialized successfully
|
||||
bool IsWindowReady(void)
|
||||
{
|
||||
return windowReady;
|
||||
}
|
||||
|
||||
// Check if KEY_ESCAPE pressed or Close icon pressed
|
||||
bool WindowShouldClose(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
// While window minimized, stop loop execution
|
||||
while (windowMinimized) glfwWaitEvents();
|
||||
if (windowReady)
|
||||
{
|
||||
// While window minimized, stop loop execution
|
||||
while (windowMinimized) glfwWaitEvents();
|
||||
|
||||
return (glfwWindowShouldClose(window));
|
||||
return (glfwWindowShouldClose(window));
|
||||
}
|
||||
else return true;
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
return windowShouldClose;
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_UWP)
|
||||
if (windowReady) return windowShouldClose;
|
||||
else return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
@ -687,7 +720,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");
|
||||
|
@ -781,18 +814,17 @@ void DisableCursor()
|
|||
// Set background color (framebuffer clear color)
|
||||
void ClearBackground(Color color)
|
||||
{
|
||||
// Clear full framebuffer (not only render area) to color
|
||||
rlClearColor(color.r, color.g, color.b, color.a);
|
||||
rlClearColor(color.r, color.g, color.b, color.a); // Set clear color
|
||||
rlClearScreenBuffers(); // Clear current framebuffers
|
||||
}
|
||||
|
||||
// Setup canvas (framebuffer) to start drawing
|
||||
void BeginDrawing(void)
|
||||
{
|
||||
currentTime = GetTime(); // Number of elapsed seconds since InitTimer() was called
|
||||
currentTime = GetTime(); // Number of elapsed seconds since InitTimer()
|
||||
updateTime = currentTime - previousTime;
|
||||
previousTime = currentTime;
|
||||
|
||||
rlClearScreenBuffers(); // Clear current framebuffers
|
||||
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
|
||||
rlMultMatrixf(MatrixToFloat(downscaleView)); // If downscale required, apply it here
|
||||
|
||||
|
@ -930,7 +962,7 @@ void BeginTextureMode(RenderTexture2D target)
|
|||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||
|
||||
rlEnableRenderTexture(target.id); // Enable render target
|
||||
|
||||
|
||||
rlClearScreenBuffers(); // Clear render texture buffers
|
||||
|
||||
// Set viewport to framebuffer size
|
||||
|
@ -1062,7 +1094,25 @@ float GetFrameTime(void)
|
|||
return (float)frameTime;
|
||||
}
|
||||
|
||||
// Converts Color to float array and normalizes
|
||||
// Get elapsed time measure in seconds since InitTimer()
|
||||
// NOTE: On PLATFORM_DESKTOP InitTimer() is called on InitWindow()
|
||||
// NOTE: On PLATFORM_DESKTOP, timer is initialized on glfwInit()
|
||||
double GetTime(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
return glfwGetTime(); // Elapsed time since glfwInit()
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
uint64_t time = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec;
|
||||
|
||||
return (double)(time - baseTime)*1e-9; // Elapsed time since InitTimer()
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns normalized float array for a Color
|
||||
float *ColorToFloat(Color color)
|
||||
{
|
||||
static float buffer[4];
|
||||
|
@ -1075,6 +1125,64 @@ float *ColorToFloat(Color color)
|
|||
return buffer;
|
||||
}
|
||||
|
||||
// Returns hexadecimal value for a Color
|
||||
int ColorToInt(Color color)
|
||||
{
|
||||
return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a);
|
||||
}
|
||||
|
||||
// Returns HSV values for a Color
|
||||
// NOTE: Hue is returned as degrees [0..360]
|
||||
Vector3 ColorToHSV(Color color)
|
||||
{
|
||||
Vector3 rgb = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f };
|
||||
Vector3 hsv = { 0.0f, 0.0f, 0.0f };
|
||||
float min, max, delta;
|
||||
|
||||
min = rgb.x < rgb.y ? rgb.x : rgb.y;
|
||||
min = min < rgb.z ? min : rgb.z;
|
||||
|
||||
max = rgb.x > rgb.y ? rgb.x : rgb.y;
|
||||
max = max > rgb.z ? max : rgb.z;
|
||||
|
||||
hsv.z = max; // Value
|
||||
delta = max - min;
|
||||
|
||||
if (delta < 0.00001f)
|
||||
{
|
||||
hsv.y = 0.0f;
|
||||
hsv.x = 0.0f; // Undefined, maybe NAN?
|
||||
return hsv;
|
||||
}
|
||||
|
||||
if (max > 0.0f)
|
||||
{
|
||||
// NOTE: If max is 0, this divide would cause a crash
|
||||
hsv.y = (delta/max); // Saturation
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: If max is 0, then r = g = b = 0, s = 0, h is undefined
|
||||
hsv.y = 0.0f;
|
||||
hsv.x = NAN; // Undefined
|
||||
return hsv;
|
||||
}
|
||||
|
||||
// NOTE: Comparing float values could not work properly
|
||||
if (rgb.x >= max) hsv.x = (rgb.y - rgb.z)/delta; // Between yellow & magenta
|
||||
else
|
||||
{
|
||||
if (rgb.y >= max) hsv.x = 2.0f + (rgb.z - rgb.x)/delta; // Between cyan & yellow
|
||||
else hsv.x = 4.0f + (rgb.x - rgb.y)/delta; // Between magenta & cyan
|
||||
}
|
||||
|
||||
hsv.x *= 60.0f; // Convert to degrees
|
||||
|
||||
if (hsv.x < 0.0f) hsv.x += 360.0f;
|
||||
|
||||
return hsv;
|
||||
}
|
||||
|
||||
// Returns a Color struct from hexadecimal value
|
||||
Color GetColor(int hexValue)
|
||||
{
|
||||
|
@ -1088,11 +1196,7 @@ Color GetColor(int hexValue)
|
|||
return color;
|
||||
}
|
||||
|
||||
// Returns hexadecimal value for a Color
|
||||
int GetHexValue(Color color)
|
||||
{
|
||||
return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a);
|
||||
}
|
||||
|
||||
|
||||
// Returns a random value between min and max (both included)
|
||||
int GetRandomValue(int min, int max)
|
||||
|
@ -1123,7 +1227,7 @@ void ShowLogo(void)
|
|||
}
|
||||
|
||||
// Setup window configuration flags (view FLAGS)
|
||||
void SetConfigFlags(char flags)
|
||||
void SetConfigFlags(unsigned char flags)
|
||||
{
|
||||
configFlags = flags;
|
||||
|
||||
|
@ -1159,7 +1263,7 @@ bool IsFileExtension(const char *fileName, const char *ext)
|
|||
return result;
|
||||
}
|
||||
|
||||
// Get the extension for a filename
|
||||
// Get pointer to extension for a filename string
|
||||
const char *GetExtension(const char *fileName)
|
||||
{
|
||||
const char *dot = strrchr(fileName, '.');
|
||||
|
@ -1169,6 +1273,17 @@ const char *GetExtension(const char *fileName)
|
|||
return (dot + 1);
|
||||
}
|
||||
|
||||
// Get pointer to filename for a path string
|
||||
const char *GetFileName(const char *filePath)
|
||||
{
|
||||
const char *fileName = strrchr(filePath, '\\');
|
||||
|
||||
if (!fileName || fileName == filePath) return filePath;
|
||||
|
||||
return fileName + 1;
|
||||
}
|
||||
|
||||
|
||||
// Get directory for a given fileName (with path)
|
||||
const char *GetDirectoryPath(const char *fileName)
|
||||
{
|
||||
|
@ -1649,7 +1764,8 @@ Vector2 GetTouchPosition(int index)
|
|||
// Initialize display device and framebuffer
|
||||
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
|
||||
// If width or height are 0, default display size will be used for framebuffer size
|
||||
static void InitGraphicsDevice(int width, int height)
|
||||
// NOTE: returns false in case graphic device could not be created
|
||||
static bool InitGraphicsDevice(int width, int height)
|
||||
{
|
||||
screenWidth = width; // User desired width
|
||||
screenHeight = height; // User desired height
|
||||
|
@ -1663,12 +1779,22 @@ static void InitGraphicsDevice(int width, int height)
|
|||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
glfwSetErrorCallback(ErrorCallback);
|
||||
|
||||
if (!glfwInit()) TraceLog(LOG_ERROR, "Failed to initialize GLFW");
|
||||
if (!glfwInit())
|
||||
{
|
||||
TraceLog(LOG_WARNING, "Failed to initialize GLFW");
|
||||
return false;
|
||||
}
|
||||
|
||||
// NOTE: Getting video modes is not implemented in emscripten GLFW3 version
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
// Find monitor resolution
|
||||
const GLFWvidmode *mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
|
||||
if (!monitor)
|
||||
{
|
||||
TraceLog(LOG_WARNING, "Failed to get monitor");
|
||||
return false;
|
||||
}
|
||||
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
|
||||
|
||||
displayWidth = mode->width;
|
||||
displayHeight = mode->height;
|
||||
|
@ -1774,24 +1900,28 @@ static void InitGraphicsDevice(int width, int height)
|
|||
// No-fullscreen window creation
|
||||
window = glfwCreateWindow(screenWidth, screenHeight, windowTitle, NULL, NULL);
|
||||
|
||||
if (window)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
// Center window on screen
|
||||
int windowPosX = displayWidth/2 - screenWidth/2;
|
||||
int windowPosY = displayHeight/2 - screenHeight/2;
|
||||
// Center window on screen
|
||||
int windowPosX = displayWidth/2 - screenWidth/2;
|
||||
int windowPosY = displayHeight/2 - screenHeight/2;
|
||||
|
||||
if (windowPosX < 0) windowPosX = 0;
|
||||
if (windowPosY < 0) windowPosY = 0;
|
||||
if (windowPosX < 0) windowPosX = 0;
|
||||
if (windowPosY < 0) windowPosY = 0;
|
||||
|
||||
glfwSetWindowPos(window, windowPosX, windowPosY);
|
||||
glfwSetWindowPos(window, windowPosX, windowPosY);
|
||||
#endif
|
||||
renderWidth = screenWidth;
|
||||
renderHeight = screenHeight;
|
||||
renderWidth = screenWidth;
|
||||
renderHeight = screenHeight;
|
||||
}
|
||||
}
|
||||
|
||||
if (!window)
|
||||
{
|
||||
glfwTerminate();
|
||||
TraceLog(LOG_ERROR, "GLFW Failed to initialize Window");
|
||||
TraceLog(LOG_WARNING, "GLFW Failed to initialize Window");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1837,7 +1967,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
|
||||
|
@ -1880,19 +2010,194 @@ 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_WARNING, "Failed to get function eglGetPlatformDisplayEXT");
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// 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_WARNING, "Failed to initialize EGL display");
|
||||
return false;
|
||||
}
|
||||
|
||||
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_WARNING, "Failed to initialize EGL display");
|
||||
return false;
|
||||
}
|
||||
|
||||
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_WARNING, "Failed to initialize EGL display");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
|
||||
{
|
||||
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
|
||||
TraceLog(LOG_WARNING, "Failed to initialize EGL");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//SetupFramebufferSize(displayWidth, displayHeight);
|
||||
|
||||
EGLint numConfigs = 0;
|
||||
if ((eglChooseConfig(display, framebufferAttribs, &config, 1, &numConfigs) == EGL_FALSE) || (numConfigs == 0))
|
||||
{
|
||||
TraceLog(LOG_WARNING, "Failed to choose first EGLConfig");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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_WARNING, "Failed to create EGL fullscreen surface");
|
||||
return false;
|
||||
}
|
||||
|
||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
|
||||
if (context == EGL_NO_CONTEXT)
|
||||
{
|
||||
TraceLog(LOG_WARNING, "Failed to create EGL context");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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
|
||||
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (display == EGL_NO_DISPLAY)
|
||||
{
|
||||
TraceLog(LOG_WARNING, "Failed to initialize EGL display");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialize the EGL display connection
|
||||
eglInitialize(display, NULL, NULL);
|
||||
if (eglInitialize(display, NULL, NULL) == EGL_FALSE)
|
||||
{
|
||||
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
|
||||
TraceLog(LOG_WARNING, "Failed to initialize EGL");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get an appropriate EGL framebuffer configuration
|
||||
eglChooseConfig(display, framebufferAttribs, &config, 1, &numConfigs);
|
||||
|
@ -1902,6 +2207,12 @@ static void InitGraphicsDevice(int width, int height)
|
|||
|
||||
// Create an EGL rendering context
|
||||
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
|
||||
if (context == EGL_NO_CONTEXT)
|
||||
{
|
||||
TraceLog(LOG_WARNING, "Failed to create EGL context");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create an EGL window surface
|
||||
//---------------------------------------------------------------------------------
|
||||
|
@ -1969,7 +2280,8 @@ static void InitGraphicsDevice(int width, int height)
|
|||
|
||||
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
|
||||
{
|
||||
TraceLog(LOG_ERROR, "Unable to attach EGL rendering context to EGL surface");
|
||||
TraceLog(LOG_WARNING, "Unable to attach EGL rendering context to EGL surface");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1985,6 +2297,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);
|
||||
|
@ -2005,6 +2320,7 @@ static void InitGraphicsDevice(int width, int height)
|
|||
#if defined(PLATFORM_ANDROID)
|
||||
windowReady = true; // IMPORTANT!
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set viewport parameters
|
||||
|
@ -2120,22 +2436,6 @@ static void InitTimer(void)
|
|||
previousTime = GetTime(); // Get time as double
|
||||
}
|
||||
|
||||
// Get current time measure (in seconds) since InitTimer()
|
||||
static double GetTime(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
return glfwGetTime();
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
uint64_t time = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec;
|
||||
|
||||
return (double)(time - baseTime)*1e-9;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Wait for some milliseconds (stop program execution)
|
||||
// NOTE: Sleep() granularity could be around 10 ms, it means, Sleep() could
|
||||
// take longer than expected... for that reason we use the busy wait loop
|
||||
|
@ -2369,7 +2669,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
|
||||
}
|
||||
|
@ -2433,7 +2733,9 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
|||
else
|
||||
{
|
||||
currentKeyState[key] = action;
|
||||
if (action == GLFW_PRESS) lastKeyPressed = key;
|
||||
|
||||
// NOTE: lastKeyPressed already registered on CharCallback()
|
||||
//if (action == GLFW_PRESS) lastKeyPressed = key;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2499,12 +2801,15 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
|
|||
#endif
|
||||
}
|
||||
|
||||
// GLFW3 Char Key Callback, runs on key pressed (get char value)
|
||||
// GLFW3 Char Key Callback, runs on key down (get unicode char value)
|
||||
static void CharCallback(GLFWwindow *window, unsigned int key)
|
||||
{
|
||||
{
|
||||
// NOTE: Registers any key down considering OS keyboard layout but
|
||||
// do not detects action events, those should be managed by user...
|
||||
// https://github.com/glfw/glfw/issues/668#issuecomment-166794907
|
||||
// http://www.glfw.org/docs/latest/input_guide.html#input_char
|
||||
|
||||
lastKeyPressed = key;
|
||||
|
||||
//TraceLog(LOG_INFO, "Char Callback Key pressed: %i\n", key);
|
||||
}
|
||||
|
||||
// GLFW3 CursorEnter Callback, when cursor enters the window
|
||||
|
@ -2604,6 +2909,9 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
{
|
||||
// Init graphics device (display device and OpenGL context)
|
||||
InitGraphicsDevice(screenWidth, screenHeight);
|
||||
|
||||
// Init hi-res timer
|
||||
InitTimer();
|
||||
|
||||
#if defined(SUPPORT_DEFAULT_FONT)
|
||||
// Load default font
|
||||
|
@ -2626,9 +2934,6 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
}
|
||||
*/
|
||||
|
||||
// Init hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// raylib logo appearing animation (if enabled)
|
||||
if (showLogo)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue