mirror of
https://github.com/raysan5/raylib.git
synced 2026-01-31 19:29:18 -05:00
Compare commits
16 Commits
94d8d7133b
...
1fc0b4955f
| Author | SHA1 | Date | |
|---|---|---|---|
| 1fc0b4955f | |||
| eb7f8912f8 | |||
| 8343aed4f6 | |||
| c9f9219fa6 | |||
| 5c680739bd | |||
| 86d9afc10c | |||
| 715e174d13 | |||
| 7262be85fd | |||
| 4da399141a | |||
| d7893141f3 | |||
| 32960af1dc | |||
| d6a897e551 | |||
| 8388160c32 | |||
| 5b182139ae | |||
| de62be0ec5 | |||
| 060bd787b1 |
@ -101,10 +101,37 @@ elseif ("${PLATFORM}" MATCHES "DRM")
|
||||
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread m dl)
|
||||
|
||||
elseif ("${PLATFORM}" MATCHES "SDL")
|
||||
find_package(SDL2 REQUIRED)
|
||||
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
|
||||
set(LIBS_PRIVATE SDL2::SDL2)
|
||||
# First, check if SDL is included as a subdirectory
|
||||
if(TARGET SDL3::SDL3)
|
||||
message(STATUS "Using SDL3 from subdirectory")
|
||||
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
|
||||
set(LIBS_PRIVATE SDL3::SDL3)
|
||||
add_compile_definitions(USING_SDL3_PROJECT)
|
||||
elseif(TARGET SDL2::SDL2)
|
||||
message(STATUS "Using SDL2 from subdirectory")
|
||||
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
|
||||
set(LIBS_PRIVATE SDL2::SDL2)
|
||||
add_compile_definitions(USING_SDL2_PROJECT)
|
||||
else()
|
||||
# No SDL added via add_subdirectory(), try find_package()
|
||||
message(STATUS "No SDL target from subdirectory, searching via find_package()...")
|
||||
|
||||
# First try SDL3
|
||||
find_package(SDL3 QUIET)
|
||||
if(SDL3_FOUND)
|
||||
message(STATUS "Found SDL3 via find_package()")
|
||||
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
|
||||
set(LIBS_PRIVATE SDL3::SDL3)
|
||||
add_compile_definitions(USING_SDL3_PACKAGE)
|
||||
else()
|
||||
# Fallback to SDL2
|
||||
find_package(SDL2 REQUIRED)
|
||||
message(STATUS "Found SDL2 via find_package()")
|
||||
set(PLATFORM_CPP "PLATFORM_DESKTOP_SDL")
|
||||
set(LIBS_PRIVATE SDL2::SDL2)
|
||||
add_compile_definitions(USING_SDL2_PACKAGE)
|
||||
endif()
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
||||
|
||||
807
src/external/rl_gputex.h
vendored
807
src/external/rl_gputex.h
vendored
File diff suppressed because it is too large
Load Diff
@ -1862,8 +1862,8 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
||||
// WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1
|
||||
// to work properly with our implementation (IsKeyDown/IsKeyUp checks)
|
||||
if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0;
|
||||
else if(action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1;
|
||||
else if(action == GLFW_REPEAT) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
|
||||
else if (action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1;
|
||||
else if (action == GLFW_REPEAT) CORE.Input.Keyboard.keyRepeatInFrame[key] = 1;
|
||||
|
||||
// WARNING: Check if CAPS/NUM key modifiers are enabled and force down state for those keys
|
||||
if (((key == KEY_CAPS_LOCK) && ((mods & GLFW_MOD_CAPS_LOCK) > 0)) ||
|
||||
|
||||
@ -52,13 +52,27 @@
|
||||
#ifndef SDL_ENABLE_OLD_NAMES
|
||||
#define SDL_ENABLE_OLD_NAMES // Just in case we're on SDL3, we need some in-between compatibily
|
||||
#endif
|
||||
#include "SDL.h" // SDL base library (window/rendered, input, timing... functionality)
|
||||
// SDL base library (window/rendered, input, timing... functionality)
|
||||
#ifdef USING_SDL3_PROJECT
|
||||
#include "SDL3/SDL.h"
|
||||
#elif USING_SDL2_PROJECT
|
||||
#include "SDL2/SDL.h"
|
||||
#else
|
||||
#include "SDL.h"
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// It seems it does not need to be included to work
|
||||
//#include "SDL_opengles2.h"
|
||||
#else
|
||||
#include "SDL_opengl.h" // SDL OpenGL functionality (if required, instead of internal renderer)
|
||||
// SDL OpenGL functionality (if required, instead of internal renderer)
|
||||
#ifdef USING_SDL3_PROJECT
|
||||
#include "SDL3/SDL_opengl.h"
|
||||
#elif USING_SDL2_PROJECT
|
||||
#include "SDL2/SDL_opengl.h"
|
||||
#else
|
||||
#include "SDL_opengl.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -238,8 +252,7 @@ static const int CursorsLUT[] = {
|
||||
//SDL_SYSTEM_CURSOR_WAITARROW, // No equivalent implemented on MouseCursor enum on raylib.h
|
||||
};
|
||||
|
||||
|
||||
// SDL3 Migration Layer made to avoid `ifdefs` inside functions when we can.
|
||||
// SDL3 Migration Layer made to avoid 'ifdefs' inside functions when we can.
|
||||
#if defined(PLATFORM_DESKTOP_SDL3)
|
||||
|
||||
// SDL3 Migration:
|
||||
@ -290,13 +303,13 @@ int SDL_GetNumVideoDisplays(void)
|
||||
int monitorCount = 0;
|
||||
SDL_DisplayID *displays = SDL_GetDisplays(&monitorCount);
|
||||
|
||||
// Safe because If `mem` is NULL, SDL_free does nothing
|
||||
// Safe because If 'mem' is NULL, SDL_free does nothing
|
||||
SDL_free(displays);
|
||||
|
||||
return monitorCount;
|
||||
}
|
||||
|
||||
// SLD3 Migration: To emulate SDL2 this function should return `SDL_DISABLE` or `SDL_ENABLE`
|
||||
// SLD3 Migration: To emulate SDL2 this function should return 'SDL_DISABLE' or 'SDL_ENABLE'
|
||||
// representing the *processing state* of the event before this function makes any changes to it
|
||||
Uint8 SDL_EventState(Uint32 type, int state)
|
||||
{
|
||||
@ -567,7 +580,7 @@ void SetWindowState(unsigned int flags)
|
||||
if (flags & FLAG_WINDOW_UNFOCUSED)
|
||||
{
|
||||
// NOTE: To be able to implement this part it seems that we should
|
||||
// do it ourselves, via `Windows.h`, `X11/Xlib.h` or even `Cocoa.h`
|
||||
// do it ourselves, via 'windows.h', 'X11/Xlib.h' or even 'Cocoa.h'
|
||||
TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_SDL");
|
||||
}
|
||||
if (flags & FLAG_WINDOW_TOPMOST)
|
||||
@ -1155,13 +1168,13 @@ Image GetClipboardImage(void)
|
||||
image = LoadImageFromMemory(imageExtensions[i], fileData, dataSize);
|
||||
if (IsImageValid(image))
|
||||
{
|
||||
TRACELOG(LOG_INFO, "Clipboard image: Got image from clipboard as a `%s` successfully", imageExtensions[i]);
|
||||
TRACELOG(LOG_INFO, "Clipboard: Got image from clipboard successfully: %s", imageExtensions[i]);
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsImageValid(image)) TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data. Error: %s", SDL_GetError());
|
||||
if (!IsImageValid(image)) TRACELOG(LOG_WARNING, "Clipboard: Couldn't get clipboard data. ERROR: %s", SDL_GetError());
|
||||
#endif
|
||||
|
||||
return image;
|
||||
|
||||
@ -48,11 +48,11 @@
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include <fcntl.h> // POSIX file control definitions - open(), creat(), fcntl()
|
||||
#include <unistd.h> // POSIX standard function definitions - read(), close(), STDIN_FILENO
|
||||
#include <termios.h> // POSIX terminal control definitions - tcgetattr(), tcsetattr()
|
||||
#include <pthread.h> // POSIX threads management (inputs reading)
|
||||
#include <dirent.h> // POSIX directory browsing
|
||||
#include <fcntl.h> // POSIX file control definitions - open(), creat(), fcntl()
|
||||
#include <unistd.h> // POSIX standard function definitions - read(), close(), STDIN_FILENO
|
||||
#include <termios.h> // POSIX terminal control definitions - tcgetattr(), tcsetattr()
|
||||
#include <pthread.h> // POSIX threads management (inputs reading)
|
||||
#include <dirent.h> // POSIX directory browsing
|
||||
|
||||
#include <sys/ioctl.h> // Required for: ioctl() - UNIX System call for device-specific input/output operations
|
||||
#include <linux/kd.h> // Linux: KDSKBMODE, K_MEDIUMRAM constants definition
|
||||
@ -71,6 +71,14 @@
|
||||
#include "EGL/egl.h" // Native platform windowing system interface
|
||||
#include "EGL/eglext.h" // EGL extensions
|
||||
|
||||
// NOTE: DRM cache enables triple buffered DRM caching
|
||||
#if defined(SUPPORT_DRM_CACHE)
|
||||
#include <poll.h> // Required for: drmHandleEvent() poll
|
||||
#include <errno.h> // Required for: EBUSY, EAGAIN
|
||||
|
||||
#define MAX_DRM_CACHED_BUFFERS 3
|
||||
#endif // SUPPORT_DRM_CACHE
|
||||
|
||||
#ifndef EGL_OPENGL_ES3_BIT
|
||||
#define EGL_OPENGL_ES3_BIT 0x40
|
||||
#endif
|
||||
@ -78,18 +86,16 @@
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#define USE_LAST_TOUCH_DEVICE // When multiple touchscreens are connected, only use the one with the highest event<N> number
|
||||
#define USE_LAST_TOUCH_DEVICE // When multiple touchscreens are connected, only use the one with the highest event<N> number
|
||||
|
||||
#define DEFAULT_EVDEV_PATH "/dev/input/" // Path to the linux input events
|
||||
#define DEFAULT_EVDEV_PATH "/dev/input/" // Path to the linux input events
|
||||
|
||||
// So actually the biggest key is KEY_CNT but we only really map the keys up to
|
||||
// KEY_ALS_TOGGLE
|
||||
// Actually biggest key is KEY_CNT but we only really map the keys up to KEY_ALS_TOGGLE
|
||||
#define KEYMAP_SIZE KEY_ALS_TOGGLE
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
typedef struct {
|
||||
// Display data
|
||||
int fd; // File descriptor for /dev/dri/...
|
||||
@ -129,6 +135,18 @@ typedef struct {
|
||||
int gamepadCount; // The number of gamepads registered
|
||||
} PlatformData;
|
||||
|
||||
#if defined(SUPPORT_DRM_CACHE)
|
||||
typedef struct {
|
||||
struct gbm_bo *bo; // Graphics buffer object
|
||||
uint32_t fbId; // DRM framebuffer ID
|
||||
} FramebufferCache;
|
||||
|
||||
static FramebufferCache fbCache[MAX_DRM_CACHED_BUFFERS] = { 0 };
|
||||
static volatile int fbCacheCount = 0;
|
||||
static volatile bool pendingFlip = false;
|
||||
static bool crtcSet = false;
|
||||
#endif // SUPPORT_DRM_CACHE
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -551,6 +569,212 @@ void DisableCursor(void)
|
||||
CORE.Input.Mouse.cursorHidden = true;
|
||||
}
|
||||
|
||||
#if defined(SUPPORT_DRM_CACHE)
|
||||
|
||||
// Destroy cached framebuffer callback, set by gbm_bo_set_user_data()
|
||||
static void DestroyFrameBufferCallback(struct gbm_bo *bo, void *data)
|
||||
{
|
||||
uint32_t fbId = (uintptr_t)data;
|
||||
|
||||
// Remove from cache
|
||||
for (int i = 0; i < fbCacheCount; i++)
|
||||
{
|
||||
if (fbCache[i].bo == bo)
|
||||
{
|
||||
TRACELOG(LOG_INFO, "DISPLAY: DRM: Framebuffer removed [%u]", (uintptr_t)fbId);
|
||||
drmModeRmFB(platform.fd, fbCache[i].fbId); // Release DRM FB
|
||||
|
||||
// Shift remaining entries
|
||||
for (int j = i; j < fbCacheCount - 1; j++) fbCache[j] = fbCache[j + 1];
|
||||
|
||||
fbCacheCount--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create or retrieve cached DRM FB for BO
|
||||
static uint32_t GetOrCreateFbForBo(struct gbm_bo *bo)
|
||||
{
|
||||
// Try to find existing cache entry
|
||||
for (int i = 0; i < fbCacheCount; i++)
|
||||
{
|
||||
if (fbCache[i].bo == bo) return fbCache[i].fbId;
|
||||
}
|
||||
|
||||
// Create new entry if cache not full
|
||||
if (fbCacheCount >= MAX_DRM_CACHED_BUFFERS) return 0; // FB cache full
|
||||
|
||||
uint32_t handle = gbm_bo_get_handle(bo).u32;
|
||||
uint32_t stride = gbm_bo_get_stride(bo);
|
||||
uint32_t width = gbm_bo_get_width(bo);
|
||||
uint32_t height = gbm_bo_get_height(bo);
|
||||
|
||||
uint32_t fbId = 0;
|
||||
if (drmModeAddFB(platform.fd, width, height, 24, 32, stride, handle, &fbId)) return 0;
|
||||
|
||||
// Store in cache
|
||||
fbCache[fbCacheCount] = (FramebufferCache){ .bo = bo, .fbId = fbId };
|
||||
fbCacheCount++;
|
||||
|
||||
// Set destroy callback to auto-cleanup
|
||||
gbm_bo_set_user_data(bo, (void *)(uintptr_t)fbId, DestroyFrameBufferCallback);
|
||||
|
||||
TRACELOG(LOG_INFO, "DISPLAY: DRM: Added new buffer object [%u]" , (uintptr_t)fbId);
|
||||
|
||||
return fbId;
|
||||
}
|
||||
|
||||
// Renders a blank frame to allocate initial buffers
|
||||
// TODO: WARNING: Platform layers do not include OpenGL code!
|
||||
void RenderBlankFrame()
|
||||
{
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
eglSwapBuffers(platform.device, platform.surface);
|
||||
glFinish(); // Ensure the buffer is processed
|
||||
}
|
||||
|
||||
// Initialize with first buffer only
|
||||
int InitSwapScreenBuffer()
|
||||
{
|
||||
if (!platform.gbmSurface || (platform.fd < 0))
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: DRM: Swap buffers can not be initialized");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Render a blank frame to allocate buffers
|
||||
RenderBlankFrame();
|
||||
|
||||
// Get first buffer
|
||||
struct gbm_bo *bo = gbm_surface_lock_front_buffer(platform.gbmSurface);
|
||||
if (!bo)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: DRM: Failed to lock initial swap buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create FB for first buffer
|
||||
uint32_t fbId = GetOrCreateFbForBo(bo);
|
||||
if (!fbId)
|
||||
{
|
||||
gbm_surface_release_buffer(platform.gbmSurface, bo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Initial CRTC setup
|
||||
if (drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, fbId, 0, 0, &platform.connector->connector_id, 1, &platform.connector->modes[platform.modeIndex]))
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: DRM: Failed to initialize CRTC setup. ERROR: %s", strerror(errno));
|
||||
gbm_surface_release_buffer(platform.gbmSurface, bo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Keep first buffer locked until flipped
|
||||
platform.prevBO = bo;
|
||||
crtcSet = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Static page flip handler
|
||||
// NOTE: Called once the drmModePageFlip() finished from the drmHandleEvent() context
|
||||
static void PageFlipHandler(int fd, unsigned int frame, unsigned int sec, unsigned int usec, void *data)
|
||||
{
|
||||
// Unused inputs
|
||||
(void)fd;
|
||||
(void)frame;
|
||||
(void)sec;
|
||||
(void)usec;
|
||||
|
||||
pendingFlip = false;
|
||||
struct gbm_bo *boToRelease = (struct gbm_bo *)data;
|
||||
|
||||
// Buffers are released after the flip completes (via page_flip_handler), ensuring they're no longer in use
|
||||
// Prevents the GPU from writing to a buffer being scanned out
|
||||
if (boToRelease) gbm_surface_release_buffer(platform.gbmSurface, boToRelease);
|
||||
}
|
||||
|
||||
// Swap implementation with proper caching
|
||||
void SwapScreenBuffer()
|
||||
{
|
||||
if (!crtcSet || !platform.gbmSurface) return;
|
||||
|
||||
static int loopCnt = 0;
|
||||
static int errCnt[5] = {0};
|
||||
loopCnt++;
|
||||
|
||||
// Call this only, if pendingFlip is not set
|
||||
eglSwapBuffers(platform.device, platform.surface);
|
||||
|
||||
// Process pending events non-blocking
|
||||
drmEventContext evctx = {
|
||||
.version = DRM_EVENT_CONTEXT_VERSION,
|
||||
.page_flip_handler = PageFlipHandler
|
||||
};
|
||||
|
||||
struct pollfd pfd = { .fd = platform.fd, .events = POLLIN };
|
||||
|
||||
// Polling for event for 0ms
|
||||
while (poll(&pfd, 1, 0) > 0) drmHandleEvent(platform.fd, &evctx);
|
||||
|
||||
// Skip if previous flip pending
|
||||
if (pendingFlip)
|
||||
{
|
||||
errCnt[0]++; // Skip frame: flip pending
|
||||
return;
|
||||
}
|
||||
|
||||
// Get new front buffer
|
||||
struct gbm_bo *nextBO = gbm_surface_lock_front_buffer(platform.gbmSurface);
|
||||
if (!nextBO) // Failed to lock front buffer
|
||||
{
|
||||
errCnt[1]++;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get FB ID (creates new one if needed)
|
||||
uint32_t fbId = GetOrCreateFbForBo(nextBO);
|
||||
if (!fbId)
|
||||
{
|
||||
gbm_surface_release_buffer(platform.gbmSurface, nextBO);
|
||||
errCnt[2]++;
|
||||
return;
|
||||
}
|
||||
|
||||
// Attempt page flip
|
||||
// NOTE: rmModePageFlip() schedules a buffer-flip for the next vblank and then notifies us about it.
|
||||
// It takes a CRTC-id, fb-id and an arbitrary data-pointer and then schedules the page-flip.
|
||||
// This is fully asynchronous and when the page-flip happens, the DRM-fd will become readable and we can call drmHandleEvent().
|
||||
// This will read all vblank/page-flip events and call our modeset_page_flip_event() callback with the data-pointer that we passed to drmModePageFlip().
|
||||
// We simply call modeset_draw_dev() then so the next frame is rendered... returns immediately.
|
||||
if (drmModePageFlip(platform.fd, platform.crtc->crtc_id, fbId, DRM_MODE_PAGE_FLIP_EVENT, platform.prevBO))
|
||||
{
|
||||
if (errno == EBUSY) errCnt[3]++; // Display busy - skip flip
|
||||
else errCnt[4]++; // Page flip failed
|
||||
|
||||
gbm_surface_release_buffer(platform.gbmSurface, nextBO);
|
||||
return;
|
||||
}
|
||||
|
||||
// Success: update state
|
||||
pendingFlip = true;
|
||||
platform.prevBO = nextBO;
|
||||
|
||||
/*
|
||||
// Some benchmarking code
|
||||
if (loopCnt >= 600)
|
||||
{
|
||||
TRACELOG(LOG_INFO, "DRM: Error counters: %d, %d, %d, %d, %d, %d", errCnt[0], errCnt[1], errCnt[2], errCnt[3], errCnt[4], loopCnt);
|
||||
for (int i = 0; i < 5; i++) errCnt[i] = 0;
|
||||
loopCnt = 0;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#else // !SUPPORT_DRM_CACHE
|
||||
|
||||
// Swap back buffer with front buffer (screen drawing)
|
||||
void SwapScreenBuffer(void)
|
||||
{
|
||||
@ -580,6 +804,7 @@ void SwapScreenBuffer(void)
|
||||
|
||||
platform.prevBO = bo;
|
||||
}
|
||||
#endif // SUPPORT_DRM_CACHE
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition: Misc
|
||||
@ -1083,9 +1308,21 @@ int InitPlatform(void)
|
||||
CORE.Storage.basePath = GetWorkingDirectory();
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#if defined(SUPPORT_DRM_CACHE)
|
||||
if (InitSwapScreenBuffer() == 0)
|
||||
{
|
||||
TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized successfully");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized failed");
|
||||
return -1;
|
||||
}
|
||||
#else // !SUPPORT_DRM_CACHE
|
||||
TRACELOG(LOG_INFO, "PLATFORM: DRM: Initialized successfully");
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Close platform
|
||||
|
||||
@ -1547,7 +1547,8 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
|
||||
music.looping = true; // Looping enabled by default
|
||||
musicLoaded = true;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
drwav_uninit(ctxWav);
|
||||
RL_FREE(ctxWav);
|
||||
}
|
||||
|
||||
@ -539,7 +539,7 @@ const char *TextFormat(const char *text, ...); // Formatting of tex
|
||||
#pragma message ("WARNING: Getting image from the clipboard might not work without SUPPORT_FILEFORMAT_PNG or SUPPORT_FILEFORMAT_JPG")
|
||||
#endif
|
||||
|
||||
// Not needed because `rtexture.c` will automatically defined STBI_REQUIRED when any SUPPORT_FILEFORMAT_* is defined
|
||||
// Not needed because 'rtexture.c' will automatically defined STBI_REQUIRED when any SUPPORT_FILEFORMAT_* is defined
|
||||
// #if !defined(STBI_REQUIRED)
|
||||
// #pragma message ("WARNING: "STBI_REQUIRED is not defined, that means we can't load images from clipbard"
|
||||
// #endif
|
||||
|
||||
15
src/rlgl.h
15
src/rlgl.h
@ -710,6 +710,7 @@ RLAPI void rlSetBlendFactorsSeparate(int glSrcRGB, int glDstRGB, int glSrcAlpha,
|
||||
RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffers, shaders, textures, states)
|
||||
RLAPI void rlglClose(void); // De-initialize rlgl (buffers, shaders, textures)
|
||||
RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required)
|
||||
RLAPI void *rlGetProcAddress(const char *procName); // Get OpenGL procedure address
|
||||
RLAPI int rlGetVersion(void); // Get current OpenGL version
|
||||
RLAPI void rlSetFramebufferWidth(int width); // Set current framebuffer width
|
||||
RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width
|
||||
@ -1041,10 +1042,15 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
|
||||
typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions loader signature (same as GLADloadproc)
|
||||
|
||||
typedef struct rlglData {
|
||||
rlRenderBatch *currentBatch; // Current render batch
|
||||
rlRenderBatch defaultBatch; // Default internal render batch
|
||||
|
||||
rlglLoadProc loader; // OpenGL function loader
|
||||
|
||||
struct {
|
||||
int vertexCounter; // Current active render batch vertex counter (generic, used for all batches)
|
||||
float texcoordx, texcoordy; // Current active texture coordinate (added on glVertex*())
|
||||
@ -1114,8 +1120,6 @@ typedef struct rlglData {
|
||||
} ExtSupported; // Extensions supported flags
|
||||
} rlglData;
|
||||
|
||||
typedef void *(*rlglLoadProc)(const char *name); // OpenGL extension functions loader signature (same as GLADloadproc)
|
||||
|
||||
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -2567,6 +2571,8 @@ void rlLoadExtensions(void *loader)
|
||||
TRACELOG(RL_LOG_INFO, " > Version: %s", glGetString(GL_VERSION));
|
||||
TRACELOG(RL_LOG_INFO, " > GLSL: %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
RLGL.loader = (rlglLoadProc)loader;
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// NOTE: Anisotropy levels capability is an extension
|
||||
#ifndef GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT
|
||||
@ -2625,6 +2631,11 @@ void rlLoadExtensions(void *loader)
|
||||
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
||||
}
|
||||
|
||||
// Get OpenGL procedure address
|
||||
void *rlGetProcAddress(const char *procName) {
|
||||
return RLGL.loader(procName);
|
||||
}
|
||||
|
||||
// Get current OpenGL version
|
||||
int rlGetVersion(void)
|
||||
{
|
||||
|
||||
@ -4292,7 +4292,7 @@ static Model LoadOBJ(const char *fileName)
|
||||
|
||||
if (fileText == NULL)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "MODEL: [%s] Unable to read obj file", fileName);
|
||||
TRACELOG(LOG_WARNING, "MODEL: [%s] Unable to read obj file", fileName);
|
||||
return model;
|
||||
}
|
||||
|
||||
@ -4308,7 +4308,7 @@ static Model LoadOBJ(const char *fileName)
|
||||
|
||||
if (ret != TINYOBJ_SUCCESS)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "MODEL: Unable to read obj data %s", fileName);
|
||||
TRACELOG(LOG_WARNING, "MODEL: Unable to read obj data %s", fileName);
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
@ -168,23 +168,14 @@
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
|
||||
#define RL_GPUTEX_MALLOC RL_MALLOC
|
||||
#define RL_GPUTEX_CALLOC RL_CALLOC
|
||||
#define RL_GPUTEX_REALLOC RL_REALLOC
|
||||
#define RL_GPUTEX_FREE RL_FREE
|
||||
#define RL_GPUTEX_WARN(...) TRACELOG(LOG_WARNING, "IMAGE: " __VA_ARGS__)
|
||||
#define RL_GPUTEX_SHOW_WARN_INFO
|
||||
|
||||
// FIXME: probably, we should NOT export public functions from rl_gputex
|
||||
// but this is how it always worked... so let's keep it this way
|
||||
#define RLGPUTEXAPI RLAPI
|
||||
|
||||
#define RL_GPUTEX_MALLOC RL_MALLOC
|
||||
#define RL_GPUTEX_FREE RL_FREE
|
||||
#define RL_GPUTEX_LOG(...) TRACELOG(LOG_WARNING, "IMAGE: " __VA_ARGS__)
|
||||
#define RL_GPUTEX_SHOW_LOG_INFO
|
||||
#define RL_GPUTEX_IMPLEMENTATION
|
||||
#include "external/rl_gputex.h" // Required for: rl_load_xxx_from_memory()
|
||||
// NOTE: Used to read compressed textures data (multiple formats support)
|
||||
|
||||
#if defined(__GNUC__) // GCC and Clang
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user