8 Commits

Author SHA1 Message Date
f0a043bb75 [Platform/RGFW] add support for software rendering (#5773)
* add support for software rendering

* null check on freeing

* add back line

* rename framebuffer to surface

* add guard on free

* update makefile to prevent software on web

* update for mac
2026-04-17 18:09:57 +02:00
dde8c8e07e [build-windows.bat] Update build-windows script (#5769)
* Update build-windows script

* Use vswhere in build-windows script
2026-04-17 18:04:08 +02:00
Ray
1cbe438f93 Update rcore_desktop_rgfw.c 2026-04-17 18:03:29 +02:00
Ray
7c96c24cf9 Update rcore.c 2026-04-17 17:57:05 +02:00
Ray
d116c92f13 Merge branch 'master' of https://github.com/raysan5/raylib 2026-04-17 17:57:01 +02:00
Ray
14fe0cbfd8 Update rlgl.h 2026-04-17 17:56:49 +02:00
Ray
94f3c094e7 Update raudio.c 2026-04-17 17:56:47 +02:00
be768e27f9 fix issue with gettime (#5772) 2026-04-17 17:55:04 +02:00
6 changed files with 228 additions and 48 deletions

View File

@ -26,13 +26,13 @@ REM Checks if cl is available and skips to the argument loop if it is
REM (Prevents calling vcvarsall every time you run this script) REM (Prevents calling vcvarsall every time you run this script)
WHERE cl >nul 2>nul WHERE cl >nul 2>nul
IF %ERRORLEVEL% == 0 goto READ_ARGS IF %ERRORLEVEL% == 0 goto READ_ARGS
REM Activate the msvc build environment if cl isn't available yet REM Activate the msvc build environment if cl isn't available yet
IF EXIST "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" ( for /f "tokens=*" %%i in (
set VC_INIT="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" '"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath 2^>nul'
) ELSE IF EXIST "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" ( ) do set VS_PATH=%%i
set VC_INIT="C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" IF defined VS_PATH (
) ELSE IF EXIST "C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat" ( set VC_INIT="%VS_PATH%\VC\Auxiliary\Build\vcvarsall.bat"
set VC_INIT="C:\Program Files (x86)\Microsoft Visual C++ Build Tools\vcbuildtools.bat"
) ELSE ( ) ELSE (
REM Initialize your vc environment here if the defaults don't work REM Initialize your vc environment here if the defaults don't work
REM set VC_INIT="C:\your\path\here\vcvarsall.bat" REM set VC_INIT="C:\your\path\here\vcvarsall.bat"
@ -167,7 +167,7 @@ IF NOT EXIST !TEMP_DIR!\ (
cd !TEMP_DIR! cd !TEMP_DIR!
REM raylib source folder REM raylib source folder
set "RAYLIB_DEFINES=/D_DEFAULT_SOURCE /DPLATFORM_DESKTOP /DGRAPHICS_API_OPENGL_33" set "RAYLIB_DEFINES=/D_DEFAULT_SOURCE /DPLATFORM_DESKTOP /DGRAPHICS_API_OPENGL_33"
set RAYLIB_C_FILES="!RAYLIB_SRC!\rcore.c" "!RAYLIB_SRC!\rshapes.c" "!RAYLIB_SRC!\rtextures.c" "!RAYLIB_SRC!\rtext.c" "!RAYLIB_SRC!\rmodels.c" "!RAYLIB_SRC!\utils.c" "!RAYLIB_SRC!\raudio.c" "!RAYLIB_SRC!\rglfw.c" set RAYLIB_C_FILES="!RAYLIB_SRC!\rcore.c" "!RAYLIB_SRC!\rshapes.c" "!RAYLIB_SRC!\rtextures.c" "!RAYLIB_SRC!\rtext.c" "!RAYLIB_SRC!\rmodels.c" "!RAYLIB_SRC!\raudio.c" "!RAYLIB_SRC!\rglfw.c"
set RAYLIB_INCLUDE_FLAGS=/I"!RAYLIB_SRC!" /I"!RAYLIB_SRC!\external\glfw\include" set RAYLIB_INCLUDE_FLAGS=/I"!RAYLIB_SRC!" /I"!RAYLIB_SRC!\external\glfw\include"
IF DEFINED REALLY_QUIET ( IF DEFINED REALLY_QUIET (

View File

@ -275,11 +275,20 @@ ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
GRAPHICS ?= GRAPHICS_API_OPENGL_ES2 GRAPHICS ?= GRAPHICS_API_OPENGL_ES2
#GRAPHICS = GRAPHICS_API_OPENGL_SOFTWARE # Uncomment to use software rendering #GRAPHICS = GRAPHICS_API_OPENGL_SOFTWARE # Uncomment to use software rendering
endif endif
ifeq ($(TARGET_PLATFORM),$(filter $(TARGET_PLATFORM),PLATFORM_WEB PLATFORM_WEB_RGFW)) ifeq ($(TARGET_PLATFORM),PLATFORM_WEB)
# On HTML5 OpenGL ES 2.0 is used, emscripten translates it to WebGL 1.0 # On HTML5 OpenGL ES 2.0 is used, emscripten translates it to WebGL 1.0
GRAPHICS ?= GRAPHICS_API_OPENGL_ES2 GRAPHICS ?= GRAPHICS_API_OPENGL_ES2
#GRAPHICS = GRAPHICS_API_OPENGL_ES3 #GRAPHICS = GRAPHICS_API_OPENGL_ES3
endif endif
ifeq ($(TARGET_PLATFORM),PLATFORM_WEB_RGFW)
# On HTML5 OpenGL ES 2.0 is used, emscripten translates it to WebGL 1.0
GRAPHICS ?= GRAPHICS_API_OPENGL_ES2
#GRAPHICS = GRAPHICS_API_OPENGL_ES3
ifeq ($(GRAPHICS),GRAPHICS_API_OPENGL_SOFTWARE)
$(error WEB_RGFW: Software rendering not supported!)
endif
endif
ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID) ifeq ($(TARGET_PLATFORM),PLATFORM_ANDROID)
# By default use OpenGL ES 2.0 on Android # By default use OpenGL ES 2.0 on Android
GRAPHICS ?= GRAPHICS_API_OPENGL_ES2 GRAPHICS ?= GRAPHICS_API_OPENGL_ES2

View File

@ -177,6 +177,13 @@ typedef struct {
RGFW_window *window; // Native display device (physical screen connection) RGFW_window *window; // Native display device (physical screen connection)
RGFW_monitor *monitor; RGFW_monitor *monitor;
mg_gamepads minigamepad; mg_gamepads minigamepad;
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
RGFW_surface *surface;
u8 *surfacePixels;
i32 surfaceWidth;
i32 surfaceHeight;
#endif
} PlatformData; } PlatformData;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -1121,7 +1128,35 @@ void DisableCursor(void)
// Swap back buffer with front buffer (screen drawing) // Swap back buffer with front buffer (screen drawing)
void SwapScreenBuffer(void) void SwapScreenBuffer(void)
{ {
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
{
if (platform.surface)
{
// copy rlsw pixel data to the surface framebuffer
swReadPixels(0, 0, platform.surfaceWidth, platform.surfaceHeight, SW_RGBA, SW_UNSIGNED_BYTE, platform.surfacePixels);
// Mac wants a different pixel order. I cant seem to get this to work any other way
#if defined(__APPLE__)
unsigned char temp = 0;
unsigned char *p = NULL;
for (int i = 0; i < (platform.surfaceWidth * platform.surfaceHeight); i += 1)
{
p = platform.surfacePixels + (i * 4);
temp = p[0];
p[0] = p[2];
p[2] = temp;
}
#endif
// blit surface to the window
RGFW_window_blitSurface(platform.window, platform.surface);
}
}
#else
{
RGFW_window_swapBuffers_OpenGL(platform.window); RGFW_window_swapBuffers_OpenGL(platform.window);
}
#endif
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -1131,7 +1166,9 @@ void SwapScreenBuffer(void)
// Get elapsed time measure in seconds since InitTimer() // Get elapsed time measure in seconds since InitTimer()
double GetTime(void) double GetTime(void)
{ {
double time = get_time_seconds() - CORE.Time.base; // CORE.Time.base is nanoseconds as integer
double baseTime = (double)CORE.Time.base*1e-9;
double time = get_time_seconds() - baseTime;
return time; return time;
} }
@ -1313,6 +1350,9 @@ void PollInputEvents(void)
// Window events are also polled (Minimized, maximized, close...) // Window events are also polled (Minimized, maximized, close...)
case RGFW_windowResized: case RGFW_windowResized:
{ {
// set flag that the window was resized
CORE.Window.resizedLastFrame = true;
#if defined(__APPLE__) #if defined(__APPLE__)
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{ {
@ -1361,7 +1401,42 @@ void PollInputEvents(void)
CORE.Window.currentFbo.width = CORE.Window.screen.width; CORE.Window.currentFbo.width = CORE.Window.screen.width;
CORE.Window.currentFbo.height = CORE.Window.screen.height; CORE.Window.currentFbo.height = CORE.Window.screen.height;
#endif #endif
CORE.Window.resizedLastFrame = true;
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
#if defined(__APPLE__)
RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window);
CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f);
SetupViewport(platform.window->w * currentMonitor->pixelRatio, platform.window->h * currentMonitor->pixelRatio);
CORE.Window.render.width = CORE.Window.screen.width * currentMonitor->pixelRatio;
CORE.Window.render.height = CORE.Window.screen.height * currentMonitor->pixelRatio;
CORE.Window.currentFbo.width = CORE.Window.render.width;
CORE.Window.currentFbo.height = CORE.Window.render.height;
#endif
platform.surfaceWidth = CORE.Window.currentFbo.width;
platform.surfaceHeight = CORE.Window.currentFbo.height;
// in software mode we dont have the viewport so we need to reverse the highdpi changes
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI))
{
Vector2 scaleDpi = GetWindowScaleDPI();
platform.surfaceWidth *= scaleDpi.x;
platform.surfaceHeight *= scaleDpi.y;
}
if (platform.surfacePixels != NULL)
{
RL_FREE(platform.surfacePixels);
platform.surfacePixels = RL_MALLOC(platform.surfaceWidth * platform.surfaceHeight * 4);
}
if (platform.surface != NULL)
{
RGFW_surface_free(platform.surface);
platform.surface = RGFW_window_createSurface(platform.window, platform.surfacePixels, platform.surfaceWidth, platform.surfaceHeight, RGFW_formatBGRA8);
swResize(platform.surfaceWidth, platform.surfaceHeight);
}
#endif
} break; } break;
case RGFW_windowMaximized: case RGFW_windowMaximized:
{ {
@ -1639,6 +1714,12 @@ int InitPlatform(void)
hints->major = 4; hints->major = 4;
hints->minor = 3; hints->minor = 3;
} }
else if (rlGetVersion() == RL_OPENGL_SOFTWARE)
{
hints->major = 1;
hints->minor = 1;
hints->renderer = RGFW_glSoftware;
}
if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) hints->samples = 4; if (FLAG_IS_SET(CORE.Window.flags, FLAG_MSAA_4X_HINT)) hints->samples = 4;
@ -1654,7 +1735,6 @@ int InitPlatform(void)
RGFW_setGlobalHints_OpenGL(hints); RGFW_setGlobalHints_OpenGL(hints);
platform.window = RGFW_createWindow((CORE.Window.title != 0)? CORE.Window.title : " ", 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, flags | RGFW_windowOpenGL); platform.window = RGFW_createWindow((CORE.Window.title != 0)? CORE.Window.title : " ", 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, flags | RGFW_windowOpenGL);
CORE.Time.base = get_time_seconds();
#ifndef PLATFORM_WEB_RGFW #ifndef PLATFORM_WEB_RGFW
i32 screenSizeWidth; i32 screenSizeWidth;
@ -1719,6 +1799,39 @@ int InitPlatform(void)
#endif #endif
} }
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
// apple always scales for retina
#if defined(__APPLE__)
RGFW_monitor* currentMonitor = RGFW_window_getMonitor(platform.window);
CORE.Window.screenScale = MatrixScale(currentMonitor->pixelRatio, currentMonitor->pixelRatio, 1.0f);
CORE.Window.render.width = CORE.Window.screen.width * currentMonitor->pixelRatio;
CORE.Window.render.height = CORE.Window.screen.height * currentMonitor->pixelRatio;
CORE.Window.currentFbo.width = CORE.Window.render.width;
CORE.Window.currentFbo.height = CORE.Window.render.height;
#endif
platform.surfaceWidth = CORE.Window.currentFbo.width;
platform.surfaceHeight = CORE.Window.currentFbo.height;
platform.surfacePixels = RL_MALLOC(platform.surfaceWidth * platform.surfaceHeight * 4);
if (platform.surfacePixels == NULL)
{
TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize software pixel buffer");
return -1;
}
platform.surface = RGFW_window_createSurface(platform.window, platform.surfacePixels, platform.surfaceWidth, platform.surfaceHeight, RGFW_formatBGRA8);
if (platform.surface == NULL)
{
RL_FREE(platform.surfacePixels);
TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize software surface");
return -1;
}
#endif
TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully %s", TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully %s",
FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)? "(HighDPI)" : ""); FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)? "(HighDPI)" : "");
TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height); TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
@ -1749,20 +1862,63 @@ int InitPlatform(void)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#if defined(RGFW_WAYLAND) #if defined(RGFW_WAYLAND)
if (rlGetVersion() == RL_OPENGL_SOFTWARE)
{
if (RGFW_usingWayland()) TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - Wayland, Software): Initialized successfully");
else TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - X11, Software (fallback)): Initialized successfully");
}
else
{
if (RGFW_usingWayland()) TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - Wayland): Initialized successfully"); if (RGFW_usingWayland()) TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - Wayland): Initialized successfully");
else TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - X11 (fallback)): Initialized successfully"); else TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - X11 (fallback)): Initialized successfully");
}
#elif defined(RGFW_X11) #elif defined(RGFW_X11)
#if defined(__APPLE__) #if defined(__APPLE__)
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - X11 (MacOS)): Initialized successfully"); if (rlGetVersion() == RL_OPENGL_SOFTWARE)
{
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - X11, Software, (MacOS)): Initialized successfully");
}
else
{
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - X11, (MacOS)): Initialized successfully");
}
#else #else
if (rlGetVersion() == RL_OPENGL_SOFTWARE)
{
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - X11, Software): Initialized successfully");
}
else
{
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - X11): Initialized successfully"); TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - X11): Initialized successfully");
}
#endif #endif
#elif defined (RGFW_WINDOWS) #elif defined (RGFW_WINDOWS)
if (rlGetVersion() == RL_OPENGL_SOFTWARE)
{
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - Win32, Software): Initialized successfully");
}
else
{
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - Win32): Initialized successfully"); TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - Win32): Initialized successfully");
}
#elif defined(RGFW_WASM) #elif defined(RGFW_WASM)
if (rlGetVersion() == RL_OPENGL_SOFTWARE)
{
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - WASMs, Software): Initialized successfully");
}
else
{
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - WASMs): Initialized successfully"); TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - WASMs): Initialized successfully");
}
#elif defined(RGFW_MACOS) #elif defined(RGFW_MACOS)
if (rlGetVersion() == RL_OPENGL_SOFTWARE)
{
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - MacOS, Software): Initialized successfully");
}
else
{
TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - MacOS): Initialized successfully"); TRACELOG(LOG_INFO, "PLATFORM: DESKTOP (RGFW - MacOS): Initialized successfully");
}
#endif #endif
mg_gamepads_init(&platform.minigamepad); mg_gamepads_init(&platform.minigamepad);
@ -1775,6 +1931,18 @@ void ClosePlatform(void)
{ {
mg_gamepads_free(&platform.minigamepad); mg_gamepads_free(&platform.minigamepad);
RGFW_window_close(platform.window); RGFW_window_close(platform.window);
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
if (platform.surfacePixels != NULL)
{
RL_FREE(platform.surfacePixels);
}
if (platform.surface != NULL)
{
RGFW_surface_free(platform.surface);
}
#endif
} }
// Keycode mapping // Keycode mapping
@ -1792,34 +1960,36 @@ double get_time_seconds(void)
#if defined(_WIN32) #if defined(_WIN32)
static LARGE_INTEGER freq = { 0 }; static LARGE_INTEGER freq = { 0 };
static int freq_init = 0; static bool freqInitialized = false;
LARGE_INTEGER counter; LARGE_INTEGER counter = { 0 };
if (!freq_init) { if (!freqInitialized)
{
// Lazy initialization
QueryPerformanceFrequency(&freq); QueryPerformanceFrequency(&freq);
freq_init = 1; freqInitialized = true;
} }
QueryPerformanceCounter(&counter); QueryPerformanceCounter(&counter);
currentTime = (double)counter.QuadPart / (double)freq.QuadPart; currentTime = (double)counter.QuadPart/(double)freq.QuadPart;
#elif defined(__EMSCRIPTEN__) #elif defined(__EMSCRIPTEN__)
currentTime = emscripten_get_now() / 1000.0; currentTime = emscripten_get_now()/1000.0;
#elif defined(__APPLE__) #elif defined(__APPLE__)
static mach_timebase_info_data_t tb; static mach_timebase_info_data_t tb = { 0 };
static int tb_initialized = 0; static bool tbInitialized = false;
if (!tbInitialized)
if (!tb_initialized) { {
mach_timebase_info(&tb); mach_timebase_info(&tb);
tb_initialized = 1; tbInitialized = true;
} }
uint64_t ticks = mach_absolute_time(); uint64_t ticks = mach_absolute_time();
currentTime = (double)ticks * (double)tb.numer / (double)tb.denom / 1e9; currentTime = (double)ticks*(double)tb.numer/(double)tb.denom/1e9;
#elif defined(__linux__) #elif defined(__linux__)
struct timespec ts; struct timespec ts = { 0 };
clock_gettime(CLOCK_MONOTONIC, &ts); clock_gettime(CLOCK_MONOTONIC, &ts);
currentTime = (double)ts.tv_sec + (double)ts.tv_nsec / 1e9; currentTime = (double)ts.tv_sec + (double)ts.tv_nsec/1e9;
#else #else
// fallback to cstd // Fallback to cstd
currentTime = (double)clock() / (double)CLOCKS_PER_SEC; currentTime = (double)clock()/(double)CLOCKS_PER_SEC;
#endif #endif
return currentTime; return currentTime;

View File

@ -1702,8 +1702,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
// Copy data to allocated memory for default UnloadMusicStream // Copy data to allocated memory for default UnloadMusicStream
unsigned char *newData = (unsigned char *)RL_MALLOC(dataSize); unsigned char *newData = (unsigned char *)RL_MALLOC(dataSize);
int it = dataSize/sizeof(unsigned char); for (int i = 0; i < dataSize; i++) newData[i] = data[i];
for (int i = 0; i < it; i++) newData[i] = data[i];
// Memory loaded version for jar_mod_load_file() // Memory loaded version for jar_mod_load_file()
if (dataSize && (dataSize < 32*1024*1024)) if (dataSize && (dataSize < 32*1024*1024))

View File

@ -379,14 +379,14 @@ typedef struct CoreData {
} Gamepad; } Gamepad;
} Input; } Input;
struct { struct {
double current; // Current time measure double current; // Current time measure (seconds)
double previous; // Previous time measure double previous; // Previous time measure (seconds)
double update; // Time measure for frame update double update; // Time measure for frame update (seconds)
double draw; // Time measure for frame draw double draw; // Time measure for frame draw (seconds)
double frame; // Time measure for one frame double frame; // Time measure for one frame (seconds)
double target; // Desired time for one frame, if 0 not applied double target; // Desired time for one frame, if 0 not applied (seconds)
unsigned long long int base; // Base time measure for hi-res timer (PLATFORM_ANDROID, PLATFORM_DRM) unsigned long long int base; // Base time measure for hi-res timer (ticks or nanoseconds)
unsigned int frameCounter; // Frame counter unsigned int frameCounter; // Frame counter (frames)
} Time; } Time;
} CoreData; } CoreData;

View File

@ -1139,21 +1139,23 @@ typedef struct rlglData {
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global Variables Definition // Global Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static bool isGpuReady = false;
static double rlCullDistanceNear = RL_CULL_DISTANCE_NEAR; static double rlCullDistanceNear = RL_CULL_DISTANCE_NEAR;
static double rlCullDistanceFar = RL_CULL_DISTANCE_FAR; static double rlCullDistanceFar = RL_CULL_DISTANCE_FAR;
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
static rlglData RLGL = { 0 }; static rlglData RLGL = { 0 };
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 #endif
static bool isGpuReady = false;
#if defined(GRAPHICS_API_OPENGL_ES2) && !defined(GRAPHICS_API_OPENGL_ES3) #if defined(GRAPHICS_API_OPENGL_ES2) && !defined(GRAPHICS_API_OPENGL_ES3)
// VAO functions entry points
// NOTE: VAO functionality is exposed through extensions (OES) // NOTE: VAO functionality is exposed through extensions (OES)
static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL; static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays = NULL;
static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL; static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL;
static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL; static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays = NULL;
// NOTE: Instancing functionality could also be available through extension // Instancing functionality entry points
// NOTE: Instancing functionality could be available through extensions
static PFNGLDRAWARRAYSINSTANCEDEXTPROC glDrawArraysInstanced = NULL; static PFNGLDRAWARRAYSINSTANCEDEXTPROC glDrawArraysInstanced = NULL;
static PFNGLDRAWELEMENTSINSTANCEDEXTPROC glDrawElementsInstanced = NULL; static PFNGLDRAWELEMENTSINSTANCEDEXTPROC glDrawElementsInstanced = NULL;
static PFNGLVERTEXATTRIBDIVISOREXTPROC glVertexAttribDivisor = NULL; static PFNGLVERTEXATTRIBDIVISOREXTPROC glVertexAttribDivisor = NULL;