Code gardening

This commit is contained in:
Ray
2026-03-04 01:14:26 +01:00
parent 23c06bc6f1
commit faf42366ec
23 changed files with 213 additions and 223 deletions

View File

@@ -126,7 +126,7 @@
// rcore: Configuration values
// NOTE: Below values are alread defined inside [rcore.c] so there is no need to be
// redefined here, in case it must be done, just uncomment the required line and update
// redefined here, in case it must be done, uncomment the required line and update
// the value; it can also be done on compilation with -DVALUE_TO_REDEFINE=128
//------------------------------------------------------------------------------------
//#define MAX_TRACELOG_MSG_LENGTH 256 // Max length of one trace-log message
@@ -160,7 +160,7 @@
// rlgl: Configuration values
// NOTE: Below values are alread defined inside [rlgl.h] so there is no need to be
// redefined here, in case it must be done, just uncomment the required line and update
// redefined here, in case it must be done, uncomment the required line and update
// the value; it can also be done on compilation with -DVALUE_TO_REDEFINE=128
//------------------------------------------------------------------------------------
//#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits
@@ -350,7 +350,7 @@
// raudio: Configuration values
// NOTE: Below values are alread defined inside [rlgl.h] so there is no need to be
// redefined here, in case it must be done, just uncomment the required line and update
// redefined here, in case it must be done, uncomment the required line and update
// the value; it can also be done on compilation with -DVALUE_TO_REDEFINE=128
//------------------------------------------------------------------------------------
//#define AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (miniaudio: float-32bit)

2
src/external/rlsw.h vendored
View File

@@ -48,7 +48,7 @@
* recommended under specific situations and only if the developers know
* what are they doing; this flag is not defined by default
*
* rlsw capabilities could be customized just defining some internal
* rlsw capabilities could be customized defining some internal
* values before library inclusion (default values listed):
*
* #define SW_GL_FRAMEBUFFER_COPY_BGRA true

View File

@@ -14,7 +14,7 @@ unsigned char *Win32GetClipboardImageData(int *width, int *height, unsigned long
#include <assert.h>
// NOTE: These search for architecture is taken from "windows.h", and it's necessary to avoid including windows.h
// and still make it compile on msvc, because import indirectly importing "winnt.h" (e.g. <minwindef.h>) can cause problems is these are not defined.
// and still make it compile on msvc, because import indirectly importing "winnt.h" (e.g. <minwindef.h>) can cause problems is these are not defined
#if !defined(_X86_) && !defined(_68K_) && !defined(_MPPC_) && !defined(_IA64_) && !defined(_AMD64_) && !defined(_ARM_) && !defined(_ARM64_) && !defined(_ARM64EC_) && defined(_M_IX86)
#define _X86_
#if !defined(_CHPE_X86_ARM64_) && defined(_M_HYBRID)

View File

@@ -715,7 +715,7 @@ void PollInputEvents(void)
{
#if SUPPORT_GESTURES_SYSTEM
// NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame
// because ProcessGestureEvent() is called on an event, not every frame
UpdateGestures();
#endif
@@ -1055,7 +1055,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
InitGraphicsDevice();
// Initialize OpenGL context (states and resources)
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, stored as globals in rlgl
rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
// Setup default viewport
@@ -1299,7 +1299,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
}
else if ((keycode == AKEYCODE_BACK) || (keycode == AKEYCODE_MENU))
{
// Eat BACK_BUTTON and AKEYCODE_MENU, just do nothing... and don't let to be handled by OS!
// Eat BACK_BUTTON and AKEYCODE_MENU, do nothing... and don't let to be handled by OS!
return 1;
}
else if ((keycode == AKEYCODE_VOLUME_UP) || (keycode == AKEYCODE_VOLUME_DOWN))
@@ -1547,7 +1547,7 @@ FILE *__wrap_fopen(const char *fileName, const char *mode)
}
else
{
// Just do a regular open if file is not found in the assets
// Do a regular open if file is not found in the assets
file = __real_fopen(TextFormat("%s/%s", platform.app->activity->internalDataPath, fileName), mode);
if (file == NULL) file = __real_fopen(fileName, mode);
}

View File

@@ -837,7 +837,7 @@ int GetCurrentMonitor(void)
{
// In case the window is between two monitors, below logic is used
// to try to detect the "current monitor" for that window, note that
// this is probably an overengineered solution for a very side case
// this is probably an overengineered solution for a side case
// trying to match SDL behaviour
int closestDist = 0x7FFFFFFF;
@@ -1258,7 +1258,7 @@ void PollInputEvents(void)
{
#if SUPPORT_GESTURES_SYSTEM
// NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame
// because ProcessGestureEvent() is called on an event, not every frame
UpdateGestures();
#endif
@@ -1588,7 +1588,7 @@ int InitPlatform(void)
}
// NOTE: GLFW 3.4+ defers initialization of the Joystick subsystem on the first call to any Joystick related functions
// Forcing this initialization here avoids doing it on PollInputEvents() called by EndDrawing() after first frame has been just drawn
// Forcing this initialization here avoids doing it on PollInputEvents() called by EndDrawing() after first frame has been drawn
// The initialization will still happen and possible delays still occur, but before the window is shown, which is a nicer experience
// REF: https://github.com/raysan5/raylib/issues/1554
glfwSetJoystickCallback(NULL);

View File

@@ -1198,7 +1198,7 @@ void PollInputEvents(void)
{
#if SUPPORT_GESTURES_SYSTEM
// NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame
// because ProcessGestureEvent() is called on an event, not every frame
UpdateGestures();
#endif

View File

@@ -49,7 +49,7 @@
#define USING_SDL3_PROJECT
#endif
#ifndef SDL_ENABLE_OLD_NAMES
#define SDL_ENABLE_OLD_NAMES // Just in case on SDL3, some in-between compatibily is needed
#define SDL_ENABLE_OLD_NAMES // In case on SDL3, some in-between compatibily is needed
#endif
// SDL base library (window/rendered, input, timing... functionality)
#ifdef USING_SDL3_PROJECT
@@ -1365,7 +1365,7 @@ void PollInputEvents(void)
{
#if SUPPORT_GESTURES_SYSTEM
// NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame
// because ProcessGestureEvent() is called on an event, not every frame
UpdateGestures();
#endif
@@ -1482,7 +1482,7 @@ void PollInputEvents(void)
#ifndef USING_VERSION_SDL3
// The SDL_WINDOWEVENT_* events have been moved to top level events, and SDL_WINDOWEVENT has been removed
// In general, handling this change just means checking for the individual events instead of first checking for SDL_WINDOWEVENT
// In general, handling this change means checking for the individual events instead of first checking for SDL_WINDOWEVENT
// and then checking for window events; Events >= SDL_EVENT_WINDOW_FIRST and <= SDL_EVENT_WINDOW_LAST can be compared
// to see whether it's a window event
case SDL_WINDOWEVENT:

View File

@@ -2198,7 +2198,7 @@ static unsigned SanitizeFlags(int mode, unsigned flags)
// retry loop that continues until either the desired state is reached or the state stops changing
static void UpdateFlags(HWND hwnd, unsigned desiredFlags, int width, int height)
{
// Flags that just apply immediately without needing any operations
// Flags that apply immediately without needing any operations
CORE.Window.flags |= (desiredFlags & FLAG_MASK_NO_UPDATE);
int vsync = (desiredFlags & FLAG_VSYNC_HINT)? 1 : 0;

View File

@@ -183,14 +183,14 @@ static const int evkeyToUnicodeLUT[] = {
0, 27, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 45, 61, 8, 0, 113, 119, 101, 114,
116, 121, 117, 105, 111, 112, 0, 0, 13, 0, 97, 115, 100, 102, 103, 104, 106, 107, 108, 59,
39, 96, 0, 92, 122, 120, 99, 118, 98, 110, 109, 44, 46, 47, 0, 0, 0, 32
// LUT currently incomplete, just mapped the most essential keys
// LUT currently incomplete, only mapped the most essential keys
};
// This is the map used to map any keycode returned from linux to a raylib code from 'raylib.h'
// NOTE: Use short here to save a little memory
static const short linuxToRaylibMap[KEYMAP_SIZE] = {
// We don't map those with designated initialization, because we would getting
// into loads of naming conflicts
// Don't map with designated initialization,
// it will geenrate many naming conflicts
0, 256, 49, 50, 51, 52, 53, 54,
55, 56, 57, 48, 45, 61, 259, 258,
81, 87, 69, 82, 84, 89, 85, 73,
@@ -764,9 +764,9 @@ void SwapScreenBuffer()
// 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
// This is fully asynchronous and when the page-flip happens, the DRM-fd will become readable and drmHandleEvent() can be called
// This will read all vblank/page-flip events and call our modeset_page_flip_event() callback with the data-pointer passed to drmModePageFlip()
// 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
@@ -1067,7 +1067,7 @@ void PollInputEvents(void)
{
#if SUPPORT_GESTURES_SYSTEM
// NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame
// because ProcessGestureEvent() is called on an event, not every frame
UpdateGestures();
#endif
@@ -1089,7 +1089,7 @@ void PollInputEvents(void)
PollKeyboardEvents();
#if SUPPORT_SSH_KEYBOARD_RPI
// NOTE: Keyboard reading could be done using input_event(s) or just read from stdin, both methods are used here
// NOTE: Keyboard reading could be done using input_event(s) or read from stdin, both methods are used here
// stdin reading is still used for legacy purposes, it allows keyboard input trough SSH console
if (!platform.eventKeyboardMode) ProcessKeyboard();
#endif
@@ -1225,7 +1225,7 @@ int InitPlatform(void)
if (((con->connection == DRM_MODE_CONNECTED) || (con->connection == DRM_MODE_UNKNOWNCONNECTION)) && (con->count_modes > 0))
{
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
// For hardware rendering, we need an encoder_id
// For hardware rendering, an encoder_id is needed
if (con->encoder_id)
{
TRACELOG(LOG_TRACE, "DISPLAY: DRM connector %i connected with encoder", i);
@@ -1234,7 +1234,7 @@ int InitPlatform(void)
}
else TRACELOG(LOG_TRACE, "DISPLAY: DRM connector %i connected but no encoder", i);
#else
// For software rendering, we can accept even without encoder_id
// For software rendering, accept even without encoder_id
TRACELOG(LOG_TRACE, "DISPLAY: DRM connector %i suitable for software rendering", i);
platform.connector = con;
break;
@@ -1534,7 +1534,7 @@ int InitPlatform(void)
return -1;
}
// At this point we need to manage render size vs screen size
// At this point, manage render size vs screen size
// NOTE: This function use and modify global module variables:
// -> CORE.Window.screen.width/CORE.Window.screen.height
// -> CORE.Window.render.width/CORE.Window.render.height
@@ -1572,7 +1572,7 @@ int InitPlatform(void)
// NOTE: GL procedures address loader is required to load extensions
rlLoadExtensions(eglGetProcAddress);
#else
// At this point we need to manage render size vs screen size
// At this point, manage render size vs screen size
// NOTE: This function use and modify global module variables:
// -> CORE.Window.screen.width/CORE.Window.screen.height
// -> CORE.Window.render.width/CORE.Window.render.height
@@ -1596,7 +1596,7 @@ int InitPlatform(void)
if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_MINIMIZED)) MinimizeWindow();
// If graphic device is no properly initialized, we end program
// If graphic device is no properly initialized, end program
if (!CORE.Window.ready)
{
TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device");
@@ -1745,7 +1745,7 @@ void ClosePlatform(void)
// Initialize Keyboard system (using standard input)
static void InitKeyboard(void)
{
// NOTE: We read directly from Standard Input (stdin) - STDIN_FILENO file descriptor,
// NOTE: Read directly from Standard Input (stdin) - STDIN_FILENO file descriptor,
// Reading directly from stdin will give chars already key-mapped by kernel to ASCII or UNICODE
// Save terminal keyboard settings
@@ -1978,8 +1978,8 @@ static void ConfigureEvdevDevice(char *device)
return;
}
// At this point we have a connection to the device, but we don't yet know what the device is
// It could be many things, even as simple as a power button...
// At this point, a connection to the device has been stablished, but still left to know what the device is,
// it could be many things, even as simple as a power button...
//-------------------------------------------------------------------------------------------------------
// Identify the device
@@ -1990,8 +1990,8 @@ static void ConfigureEvdevDevice(char *device)
} absinfo[ABS_CNT] = { 0 };
// These flags aren't really a one of
// Some devices could have properties we assosciate with keyboards as well as properties
// we assosciate with mice
// Some devices could have properties associated with keyboards
// as well as properties associated with mice
bool isKeyboard = false;
bool isMouse = false;
bool isTouch = false;
@@ -2027,11 +2027,10 @@ static void ConfigureEvdevDevice(char *device)
TEST_BIT(keyBits, BTN_TOOL_FINGER) ||
TEST_BIT(keyBits, BTN_TOUCH))) isTouch = true;
// Absolute mice should really only exist with VMWare, but it shouldn't
// matter if we support them
// Absolute mice should really only exist with VMWare
else if (hasAbsXY && TEST_BIT(keyBits, BTN_MOUSE)) isMouse = true;
// If any of the common joystick axes are present, we assume it's a gamepad
// If any of the common joystick axes are present, assume it's a gamepad
else
{
for (int axis = (hasAbsXY? ABS_Z : ABS_X); axis < ABS_PRESSURE; axis++)
@@ -2056,7 +2055,7 @@ static void ConfigureEvdevDevice(char *device)
{
ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relBits)), relBits);
// If it has any of the gamepad or touch features we tested so far, it's not a mouse
// If it has any of the gamepad or touch features tested so far, it's not a mouse
if (!isTouch &&
!isGamepad &&
TEST_BIT(relBits, REL_X) &&
@@ -2067,12 +2066,12 @@ static void ConfigureEvdevDevice(char *device)
if (TEST_BIT(evBits, EV_KEY))
{
// The first 32 keys as defined in input-event-codes.h are pretty much
// exclusive to keyboards, so we can test them using a mask
// exclusive to keyboards, so they can be tested using a mask
// Leave out the first bit to not test KEY_RESERVED
const unsigned long mask = 0xFFFFFFFE;
if ((keyBits[0] & mask) == mask) isKeyboard = true;
// If we find any of the common gamepad buttons we assume it's a gamepad
// If any of the common gamepad buttons is found, assume it's a gamepad
else
{
for (int button = BTN_JOYSTICK; button < BTN_DIGI; ++button)
@@ -2149,7 +2148,7 @@ static void ConfigureEvdevDevice(char *device)
if (absAxisCount > 0)
{
// TODO: Review GamepadAxis enum matching
// So gamepad axes (as in the actual linux joydev.c) are just simply enumerated
// So gamepad axes (as in the actual linux joydev.c) are simply enumerated
// and (at least for some input drivers like xpat) it's convention to use
// ABS_X, ABX_Y for one joystick ABS_RX, ABS_RY for the other and the Z axes for the shoulder buttons
// If these are now enumerated, it results to LJOY_X, LJOY_Y, LEFT_SHOULDERB, RJOY_X, ...
@@ -2197,7 +2196,7 @@ static void PollKeyboardEvents(void)
if (event.type != EV_KEY) continue;
#if SUPPORT_SSH_KEYBOARD_RPI
// If the event was a key, we know a working keyboard is connected, so disable the SSH keyboard
// If the event was a key, assume a working keyboard is connected, so disable the SSH keyboard
platform.eventKeyboardMode = true;
#endif
// Keyboard keys appear for codes 1 to 255, ignore everthing else
@@ -2206,7 +2205,7 @@ static void PollKeyboardEvents(void)
// Lookup the scancode in the keymap to get a keycode
keycode = linuxToRaylibMap[event.code];
// Make sure we got a valid keycode
// Make sure a valid keycode is obtained
if ((keycode > 0) && (keycode < MAX_KEYBOARD_KEYS))
{
// WARNING: https://www.kernel.org/doc/Documentation/input/input.txt
@@ -2380,8 +2379,8 @@ static void PollMouseEvents(void)
{
platform.touchPosition[platform.touchSlot].x = (event.value - platform.absRange.x)*CORE.Window.screen.width/platform.absRange.width;
// If this slot is active, it's a move. If not, we are just updating the buffer for when it becomes active.
// Only set to MOVE if we haven't already detected a DOWN or UP event this frame
// If this slot is active, it's a move; If not, update the buffer for when it becomes active
// Only set to MOVE if a DOWN or UP event has not been detected this frame
if (platform.touchActive[platform.touchSlot] && touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE
}
}
@@ -2392,8 +2391,8 @@ static void PollMouseEvents(void)
{
platform.touchPosition[platform.touchSlot].y = (event.value - platform.absRange.y)*CORE.Window.screen.height/platform.absRange.height;
// If this slot is active, it's a move. If not, we are just updating the buffer for when it becomes active.
// Only set to MOVE if we haven't already detected a DOWN or UP event this frame
// If this slot is active, it's a move; If not, update the buffer for when it becomes active
// Only set to MOVE if a DOWN or UP event have not been detected this frame
if (platform.touchActive[platform.touchSlot] && touchAction == -1) touchAction = 2; // TOUCH_ACTION_MOVE
}
}
@@ -2418,7 +2417,7 @@ static void PollMouseEvents(void)
platform.touchPosition[platform.touchSlot].y = -1;
platform.touchId[platform.touchSlot] = -1;
// Force UP action if we haven't already set a DOWN action
// Force UP action if DOWN action has not already been set
// (DOWN takes priority over UP if both happen in one frame, though rare)
if (touchAction != 1) touchAction = 0; // TOUCH_ACTION_UP
}
@@ -2665,7 +2664,7 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
// NOTE: Global variables CORE.Window.render.width/CORE.Window.render.height and CORE.Window.renderOffset.x/CORE.Window.renderOffset.y can be modified
static void SetupFramebuffer(int width, int height)
{
// Calculate CORE.Window.render.width and CORE.Window.render.height, we have the display size (input params) and the desired screen size (global var)
// Calculate CORE.Window.render.width and CORE.Window.render.height, using the display size (input params) and the desired screen size (global var)
if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height))
{
TRACELOG(LOG_WARNING, "DISPLAY: Downscaling required: Screen size (%ix%i) is bigger than display size (%ix%i)", CORE.Window.screen.width, CORE.Window.screen.height, CORE.Window.display.width, CORE.Window.display.height);
@@ -2693,8 +2692,8 @@ static void SetupFramebuffer(int width, int height)
float scaleRatio = (float)CORE.Window.render.width/(float)CORE.Window.screen.width;
CORE.Window.screenScale = MatrixScale(scaleRatio, scaleRatio, 1.0f);
// NOTE: We render to full display resolution!
// We just need to calculate above parameters for downscale matrix and offsets
// NOTE: Rendering to full display resolution,
// calculate above parameters for downscale matrix and offsets
CORE.Window.render.width = CORE.Window.display.width;
CORE.Window.render.height = CORE.Window.display.height;

View File

@@ -437,7 +437,7 @@ void PollInputEvents(void)
{
#if SUPPORT_GESTURES_SYSTEM
// NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame
// because ProcessGestureEvent() is called on an event, not every frame
UpdateGestures();
#endif

View File

@@ -407,7 +407,7 @@ void PollInputEvents(void)
{
#if SUPPORT_GESTURES_SYSTEM
// NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame
// because ProcessGestureEvent() is called on an event, not every frame
UpdateGestures();
#endif

View File

@@ -803,17 +803,20 @@ void SetClipboardText(const char *text)
// Async EM_JS to be able to await clickboard read asynchronous function
EM_ASYNC_JS(void, RequestClipboardData, (void), {
if (navigator.clipboard && window.isSecureContext) {
if (navigator.clipboard && window.isSecureContext)
{
let items = await navigator.clipboard.read();
for (const item of items) {
for (const item of items)
{
// Check if this item contains plain text or image
if (item.types.includes("text/plain")) {
if (item.types.includes("text/plain"))
{
const blob = await item.getType("text/plain");
const text = await blob.text();
window._lastClipboardString = text;
}
else if (item.types.find(t => t.startsWith("image/"))) {
else if (item.types.find(t => t.startsWith("image/")))
{
const blob = await item.getType(item.types.find(t => t.startsWith("image/")));
const bitmap = await createImageBitmap(blob);
@@ -831,16 +834,16 @@ EM_ASYNC_JS(void, RequestClipboardData, (void), {
window._lastImgData = imgData;
}
}
} else {
console.warn("Clipboard read() requires HTTPS/Localhost");
}
}
else console.warn("Clipboard read() requires HTTPS/Localhost");
});
// Returns the string created by RequestClipboardData from JS memory to Emscripten C memory
EM_JS(char*, GetLastPastedText, (void), {
EM_JS(char *, GetLastPastedText, (void), {
var str = window._lastClipboardString || "";
var length = lengthBytesUTF8(str) + 1;
if (length > 1) {
if (length > 1)
{
var ptr = _malloc(length);
stringToUTF8(str, ptr, length);
return ptr;
@@ -849,10 +852,12 @@ EM_JS(char*, GetLastPastedText, (void), {
});
// Returns the image created by RequestClipboardData from JS memory to Emscripten C memory
EM_JS(unsigned char*, GetLastPastedImage, (int* width, int* height), {
if (window._lastImgData) {
EM_JS(unsigned char *, GetLastPastedImage, (int *width, int *height), {
if (window._lastImgData)
{
const data = window._lastImgData;
if (data.length > 0) {
if (data.length > 0)
{
const ptr = _malloc(data.length);
HEAPU8.set(data, ptr);
@@ -861,12 +866,13 @@ EM_JS(unsigned char*, GetLastPastedImage, (int* width, int* height), {
if (width) setValue(width, window._lastImgWidth, 'i32');
if (height) setValue(height, window._lastImgHeight, 'i32');
// Clear the JS buffer so we don't fetch the same image twice
// Clear the JS buffer so there is no need to fetch the same image twice
window._lastImgData = null;
return ptr;
return ptr;
}
}
return 0;
});
@@ -1072,7 +1078,7 @@ void PollInputEvents(void)
{
#if SUPPORT_GESTURES_SYSTEM
// NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame
// because ProcessGestureEvent() is called on an event, not every frame
UpdateGestures();
#endif

View File

@@ -781,17 +781,20 @@ void SetClipboardText(const char *text)
// Async EM_JS to be able to await clickboard read asynchronous function
EM_ASYNC_JS(void, RequestClipboardData, (void), {
if (navigator.clipboard && window.isSecureContext) {
if (navigator.clipboard && window.isSecureContext)
{
let items = await navigator.clipboard.read();
for (const item of items) {
for (const item of items)
{
// Check if this item contains plain text or image
if (item.types.includes("text/plain")) {
if (item.types.includes("text/plain"))
{
const blob = await item.getType("text/plain");
const text = await blob.text();
window._lastClipboardString = text;
}
else if (item.types.find(t => t.startsWith("image/"))) {
else if (item.types.find(t => t.startsWith("image/")))
{
const blob = await item.getType(item.types.find(t => t.startsWith("image/")));
const bitmap = await createImageBitmap(blob);
@@ -809,16 +812,16 @@ EM_ASYNC_JS(void, RequestClipboardData, (void), {
window._lastImgData = imgData;
}
}
} else {
console.warn("Clipboard read() requires HTTPS/Localhost");
}
}
else console.warn("Clipboard read() requires HTTPS/Localhost");
});
// Returns the string created by RequestClipboardData from JS memory to Emscripten C memory
EM_JS(char*, GetLastPastedText, (void), {
EM_JS(char *, GetLastPastedText, (void), {
var str = window._lastClipboardString || "";
var length = lengthBytesUTF8(str) + 1;
if (length > 1) {
if (length > 1)
{
var ptr = _malloc(length);
stringToUTF8(str, ptr, length);
return ptr;
@@ -827,10 +830,12 @@ EM_JS(char*, GetLastPastedText, (void), {
});
// Returns the image created by RequestClipboardData from JS memory to Emscripten C memory
EM_JS(unsigned char*, GetLastPastedImage, (int* width, int* height), {
if (window._lastImgData) {
EM_JS(unsigned char *, GetLastPastedImage, (int *width, int *height), {
if (window._lastImgData)
{
const data = window._lastImgData;
if (data.length > 0) {
if (data.length > 0)
{
const ptr = _malloc(data.length);
HEAPU8.set(data, ptr);
@@ -839,12 +844,13 @@ EM_JS(unsigned char*, GetLastPastedImage, (int* width, int* height), {
if (width) setValue(width, window._lastImgWidth, 'i32');
if (height) setValue(height, window._lastImgHeight, 'i32');
// Clear the JS buffer so we don't fetch the same image twice
// Clear the JS buffer so there is no need to fetch the same image twice
window._lastImgData = null;
return ptr;
return ptr;
}
}
return 0;
});
@@ -1046,7 +1052,7 @@ void PollInputEvents(void)
{
#if SUPPORT_GESTURES_SYSTEM
// NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame
// because ProcessGestureEvent() is called on an event, not every frame
UpdateGestures();
#endif

View File

@@ -26,7 +26,7 @@
* #define SUPPORT_FILEFORMAT_XM
* #define SUPPORT_FILEFORMAT_MOD
* Selected desired fileformats to be supported for loading. Some of those formats are
* supported by default, to remove support, just comment unrequired #define in this module
* supported by default, to remove support, comment unrequired #define in this module
*
* DEPENDENCIES:
* miniaudio.h - Audio device management lib (https://github.com/mackron/miniaudio)
@@ -299,7 +299,7 @@ typedef struct tagBITMAPINFOHEADER {
#endif
#ifndef AUDIO_BUFFER_RESIDUAL_CAPACITY
#define AUDIO_BUFFER_RESIDUAL_CAPACITY 8 // In PCM frames. For resampling and pitch shifting.
#define AUDIO_BUFFER_RESIDUAL_CAPACITY 8 // In PCM frames, for resampling and pitch shifting
#endif
//----------------------------------------------------------------------------------
@@ -406,7 +406,7 @@ static AudioData AUDIO = { // Global AUDIO context
// NOTE: Music buffer size is defined by number of samples, independent of sample size and channels number
// After some math, considering a sampleRate of 48000, a buffer refill rate of 1/60 seconds and a
// standard double-buffering system, a 4096 samples buffer has been chosen, it should be enough
// In case of music-stalls, just increase this number
// In case of music-stalls, increase this number
.Buffer.defaultSize = 0,
.mixedProcessor = NULL
};
@@ -601,7 +601,7 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
// be consumed. Any residual input frames need to be kept track of to
// ensure there are no discontinuities. Since raylib supports pitch
// shifting, which is done through resampling, a cache will always be
// required. This will be kept relatively small to avoid too much wastage.
// required. This will be kept relatively small to avoid too much wastage
audioBuffer->converterResidualCount = 0;
audioBuffer->converterResidual = (unsigned char*)RL_CALLOC(AUDIO_BUFFER_RESIDUAL_CAPACITY*ma_get_bytes_per_frame(format, channels), 1);
@@ -721,7 +721,7 @@ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch)
if ((buffer != NULL) && (pitch > 0.0f))
{
ma_mutex_lock(&AUDIO.System.lock);
// Pitching is just an adjustment of the sample rate
// Pitching is an adjustment of the sample rate
// Note that this changes the duration of the sound:
// - higher pitches will make the sound faster
// - lower pitches make it slower
@@ -1046,7 +1046,7 @@ void UnloadSound(Sound sound)
void UnloadSoundAlias(Sound alias)
{
// Untrack and unload just the sound buffer, not the sample data, it is shared with the source for the alias
// Untrack and unload the sound buffer, not the sample data, it is shared with the source for the alias
if (alias.stream.buffer != NULL)
{
UntrackAudioBuffer(alias.stream.buffer);
@@ -2316,7 +2316,7 @@ void DetachAudioStreamProcessor(AudioStream stream, AudioCallback process)
// Add processor to audio pipeline. Order of processors is important
// Works the same way as {Attach,Detach}AudioStreamProcessor() functions, except
// these two work on the already mixed output just before sending it to the sound hardware
// these two work on the already mixed output before sending it to the sound hardware
void AttachAudioMixedProcessor(AudioCallback process)
{
ma_mutex_lock(&AUDIO.System.lock);
@@ -2397,7 +2397,7 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer,
if (currentSubBufferIndex > 1) return 0;
// Another thread can update the processed state of buffers, so
// just take a copy here to try and avoid potential synchronization problems
// take a copy here to try and avoid potential synchronization problems
bool isSubBufferProcessed[2] = { 0 };
isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0];
isSubBufferProcessed[1] = audioBuffer->isSubBufferProcessed[1];
@@ -2478,8 +2478,8 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer,
static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, float *framesOut, ma_uint32 frameCount)
{
// NOTE: Continuously converting data from the AudioBuffer's internal format to the mixing format,
// which should be defined by the output format of the data converter.
// This is done until frameCount frames have been output.
// which should be defined by the output format of the data converter
// This is done until frameCount frames have been output
ma_uint32 bpf = ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn);
ma_uint8 inputBuffer[4096] = { 0 };
ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/bpf;
@@ -2491,34 +2491,34 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f
ma_uint64 outputFramesToProcessThisIteration = frameCount - totalOutputFramesProcessed;
//ma_uint64 inputFramesToProcessThisIteration = 0;
// Process any residual input frames from the previous read first.
// Process any residual input frames from the previous read first
if (audioBuffer->converterResidualCount > 0)
{
ma_uint64 inputFramesProcessedThisIteration = audioBuffer->converterResidualCount;
ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration;
ma_data_converter_process_pcm_frames(&audioBuffer->converter, audioBuffer->converterResidual, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration);
// Make sure the data in the cache is consumed. This can be optimized to use a cursor instead of a memmove().
memmove(audioBuffer->converterResidual, audioBuffer->converterResidual + inputFramesProcessedThisIteration*bpf, (size_t)(AUDIO_BUFFER_RESIDUAL_CAPACITY - inputFramesProcessedThisIteration) * bpf);
// Make sure the data in the cache is consumed, this can be optimized to use a cursor instead of a memmove()
memmove(audioBuffer->converterResidual, audioBuffer->converterResidual + inputFramesProcessedThisIteration*bpf, (size_t)(AUDIO_BUFFER_RESIDUAL_CAPACITY - inputFramesProcessedThisIteration)*bpf);
audioBuffer->converterResidualCount -= (ma_uint32)inputFramesProcessedThisIteration; // Safe cast
totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; // Safe cast
}
else
{
// Getting here means there are no residual frames from the previous read. Fresh data can now be
// pulled from the AudioBuffer and processed.
// Getting here means there are no residual frames from the previous read
// Fresh data can now be pulled from the AudioBuffer and processed
//
// A best guess needs to be used made to determine how many input frames to pull from the
// buffer. There are three possible outcomes: 1) exact; 2) underestimated; 3) overestimated.
// A best guess needs to be used made to determine how many input frames to pull from the buffer
// There are three possible outcomes: 1) exact; 2) underestimated; 3) overestimated
//
// When the guess is exactly correct or underestimated there is nothing special to handle - it'll be
// handled naturally by the loop.
// When the guess is exactly correct or underestimated there is nothing special to handle,
// it'll be handled naturally by the loop
//
// When the guess is overestimated, that's when it gets more complicated. In this case, any overflow
// needs to be stored in a buffer for later processing by the next read.
ma_uint32 estimatedInputFrameCount = (ma_uint32)(((float)audioBuffer->converter.resampler.sampleRateIn / audioBuffer->converter.resampler.sampleRateOut) * outputFramesToProcessThisIteration);
if (estimatedInputFrameCount == 0) estimatedInputFrameCount = 1; // Make sure at least one input frame is read.
// When the guess is overestimated, that's when it gets more complicated
// In this case, any overflow needs to be stored in a buffer for later processing by the next read
ma_uint32 estimatedInputFrameCount = (ma_uint32)(((float)audioBuffer->converter.resampler.sampleRateIn / audioBuffer->converter.resampler.sampleRateOut)*outputFramesToProcessThisIteration);
if (estimatedInputFrameCount == 0) estimatedInputFrameCount = 1; // Make sure at least one input frame is read
if (estimatedInputFrameCount > inputBufferFrameCap) estimatedInputFrameCount = inputBufferFrameCap;
ma_uint32 inputFramesInInternalFormatCount = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, estimatedInputFrameCount);
@@ -2531,17 +2531,17 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f
if (inputFramesInInternalFormatCount > inputFramesProcessedThisIteration)
{
// Getting here means the estimated input frame count was overestimated. The residual needs
// be stored for later use.
// Getting here means the estimated input frame count was overestimated
// The residual needs be stored for later use
ma_uint64 residualFrameCount = inputFramesInInternalFormatCount - inputFramesProcessedThisIteration;
// A safety check to make sure the capacity of the residual cache is not exceeded.
// A safety check to make sure the capacity of the residual cache is not exceeded
if (residualFrameCount > AUDIO_BUFFER_RESIDUAL_CAPACITY)
{
residualFrameCount = AUDIO_BUFFER_RESIDUAL_CAPACITY;
}
memcpy(audioBuffer->converterResidual, inputBuffer + inputFramesProcessedThisIteration*bpf, (size_t)(residualFrameCount * bpf));
memcpy(audioBuffer->converterResidual, inputBuffer + inputFramesProcessedThisIteration*bpf, (size_t)(residualFrameCount*bpf));
audioBuffer->converterResidualCount = (unsigned int)residualFrameCount;
}
@@ -2559,7 +2559,7 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
{
(void)pDevice;
// Mixing is basically just an accumulation, need to initialize the output buffer to 0
// Mixing is basically an accumulation, need to initialize the output buffer to 0
memset(pFramesOut, 0, frameCount*pDevice->playback.channels*ma_get_bytes_per_sample(pDevice->playback.format));
// Using a mutex here for thread-safety which makes things not real-time
@@ -2577,7 +2577,7 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
{
if (framesRead >= frameCount) break;
// Just read as much data as possible from the stream
// Read as much data as possible from the stream
ma_uint32 framesToRead = (frameCount - framesRead);
while (framesToRead > 0)
@@ -2626,7 +2626,7 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
}
else
{
// Should never get here, but just for safety,
// Should never get here, but for safety,
// move the cursor position back to the start and continue the loop
audioBuffer->frameCursorPos = 0;
continue;
@@ -2651,7 +2651,7 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
ma_mutex_unlock(&AUDIO.System.lock);
}
// Main mixing function, pretty simple in this project, just an accumulation
// Main mixing function, pretty simple in this project, only an accumulation
// NOTE: framesOut is both an input and an output, it is initially filled with zeros outside of this function
static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, AudioBuffer *buffer)
{
@@ -2739,7 +2739,7 @@ static void UpdateAudioStreamInLockedState(AudioStream stream, const void *data,
}
else
{
// Just update whichever sub-buffer is processed
// Update whichever sub-buffer is processed
subBufferToUpdate = (stream.buffer->isSubBufferProcessed[0])? 0 : 1;
}

View File

@@ -159,7 +159,7 @@
// NOTE: Set some defines with some data types declared by raylib
// Other modules (raymath, rlgl) also require some of those types, so,
// to be able to use those other modules as standalone (not depending on raylib)
// this defines are very useful for internal check and avoid type (re)definitions
// this defines are useful for internal check and avoid type (re)definitions
#define RL_COLOR_TYPE
#define RL_RECTANGLE_TYPE
#define RL_VECTOR2_TYPE
@@ -733,7 +733,7 @@ typedef enum {
// Gamepad buttons
typedef enum {
GAMEPAD_BUTTON_UNKNOWN = 0, // Unknown button, just for error checking
GAMEPAD_BUTTON_UNKNOWN = 0, // Unknown button, for error checking
GAMEPAD_BUTTON_LEFT_FACE_UP, // Gamepad left DPAD up button
GAMEPAD_BUTTON_LEFT_FACE_RIGHT, // Gamepad left DPAD right button
GAMEPAD_BUTTON_LEFT_FACE_DOWN, // Gamepad left DPAD down button
@@ -878,7 +878,7 @@ typedef enum {
// NOTE 1: Filtering considers mipmaps if available in the texture
// NOTE 2: Filter is accordingly set for minification and magnification
typedef enum {
TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation
TEXTURE_FILTER_POINT = 0, // No filter, pixel approximation
TEXTURE_FILTER_BILINEAR, // Linear filtering
TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps)
TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x

View File

@@ -567,15 +567,9 @@ RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max)
{
length = sqrtf(length);
float scale = 1; // By default, 1 as the neutral element.
if (length < min)
{
scale = min/length;
}
else if (length > max)
{
scale = max/length;
}
float scale = 1; // By default, 1 as the neutral element
if (length < min) scale = min/length;
else if (length > max) scale = max/length;
result.x = v.x*scale;
result.y = v.y*scale;
@@ -1215,15 +1209,9 @@ RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max)
{
length = sqrtf(length);
float scale = 1; // By default, 1 as the neutral element.
if (length < min)
{
scale = min/length;
}
else if (length > max)
{
scale = max/length;
}
float scale = 1; // By default, 1 as the neutral element
if (length < min) scale = min/length;
else if (length > max) scale = max/length;
result.x = v.x*scale;
result.y = v.y*scale;
@@ -2574,8 +2562,8 @@ RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle
}
else
{
// This occurs when the angle is zero.
// Not a problem: just set an arbitrary normalized axis.
// This occurs when the angle is zero
// Not a problem, set an arbitrary normalized axis
resAxis.x = 1.0f;
}
@@ -2702,10 +2690,10 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
translation->y = mat.m13;
translation->z = mat.m14;
// Matrix Columns - Rotation will be extracted into here.
Vector3 matColumns[3] = { { mat.m0, mat.m4, mat.m8 },
// Matrix Columns - Rotation will be extracted into here
Vector3 matColumns[3] = {{ mat.m0, mat.m4, mat.m8 },
{ mat.m1, mat.m5, mat.m9 },
{ mat.m2, mat.m6, mat.m10 } };
{ mat.m2, mat.m6, mat.m10 }};
// Shear Parameters XY, XZ, and YZ (extract and ignored)
float shear[3] = { 0 };
@@ -2756,7 +2744,7 @@ RMAPI void MatrixDecompose(Matrix mat, Vector3 *translation, Quaternion *rotatio
shear[2] /= scl.z; // Correct YZ shear
}
// matColumns are now orthonormal in O(3). Now ensure its in SO(3) by enforcing det = 1.
// matColumns are now orthonormal in O(3). Now ensure its in SO(3) by enforcing det = 1
if (Vector3DotProduct(matColumns[0], Vector3CrossProduct(matColumns[1], matColumns[2])) < 0)
{
scl = Vector3Negate(scl);

View File

@@ -365,7 +365,7 @@ void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTa
if (lockView)
{
// In these camera modes, clamp the Pitch angle
// to allow only viewing straight up or down.
// to allow only viewing straight up or down
// Clamp view up
float maxAngleUp = Vector3Angle(up, targetPosition);
@@ -460,7 +460,6 @@ void UpdateCamera(Camera *camera, int mode)
if (mode == CAMERA_CUSTOM) {}
else if (mode == CAMERA_ORBITAL)
{
// Orbital can just orbit
Matrix rotation = MatrixRotate(GetCameraUp(camera), cameraOrbitalSpeed);
Vector3 view = Vector3Subtract(camera->position, camera->target);
view = Vector3Transform(view, rotation);

View File

@@ -1841,7 +1841,7 @@ void TakeScreenshot(const char *fileName)
// Setup window configuration flags (view FLAGS)
// NOTE: This function is expected to be called before window creation,
// because it sets up some flags for the window creation process
// To configure window states after creation, just use SetWindowState()
// To configure window states after creation, use SetWindowState()
void SetConfigFlags(unsigned int flags)
{
if (CORE.Window.ready) TRACELOG(LOG_WARNING, "WINDOW: SetConfigFlags called after window initialization, Use \"SetWindowState\" to set flags instead");

View File

@@ -43,7 +43,7 @@
* #define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT
* Enable debug context (only available on OpenGL 4.3)
*
* rlgl capabilities could be customized just defining some internal
* rlgl capabilities could be customized defining some internal
* values before library inclusion (default values listed):
*
* #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 // Default internal render batch elements limits
@@ -396,7 +396,7 @@ typedef struct rlVertexBuffer {
// Draw call type
// NOTE: Only texture changes register a new draw, other state-change-related elements are not
// used at this moment (vaoId, shaderId, matrices), raylib just forces a batch draw call if any
// used at this moment (vaoId, shaderId, matrices), raylib forces a batch draw call if any
// of those state-change happens (this is done in core module)
typedef struct rlDrawCall {
int mode; // Drawing mode: LINES, TRIANGLES, QUADS
@@ -478,7 +478,7 @@ typedef enum {
// NOTE 1: Filtering considers mipmaps if available in the texture
// NOTE 2: Filter is accordingly set for minification and magnification
typedef enum {
RL_TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation
RL_TEXTURE_FILTER_POINT = 0, // No filter, pixel approximation
RL_TEXTURE_FILTER_BILINEAR, // Linear filtering
RL_TEXTURE_FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps)
RL_TEXTURE_FILTER_ANISOTROPIC_4X, // Anisotropic filtering 4x
@@ -3356,7 +3356,7 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format,
}
// Texture parameters configuration
// NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used
// NOTE: glTexParameteri does NOT affect texture uploading
#if defined(GRAPHICS_API_OPENGL_ES2)
// NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used
if (RLGL.ExtSupported.texNPOT)
@@ -3741,7 +3741,7 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format)
// Two possible Options:
// 1 - Bind texture to color fbo attachment and glReadPixels()
// 2 - Create an fbo, activate it, render quad with texture, glReadPixels()
// Using Option 1, just need to care for texture format on retrieval
// Using Option 1, care for texture format on retrieval
// NOTE: This behaviour could be conditioned by graphic driver...
unsigned int fboId = rlLoadFramebuffer();
@@ -4199,7 +4199,7 @@ unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode)
if (fsCode != NULL) fragmentShaderId = rlCompileShader(fsCode, GL_FRAGMENT_SHADER);
else fragmentShaderId = RLGL.State.defaultFShaderId;
// In case vertex and fragment shader are the default ones, no need to recompile, just assign the default shader program id
// In case vertex and fragment shader are the default ones, no need to recompile, assign the default shader program id
if ((vertexShaderId == RLGL.State.defaultVShaderId) && (fragmentShaderId == RLGL.State.defaultFShaderId)) id = RLGL.State.defaultShaderId;
else if ((vertexShaderId > 0) && (fragmentShaderId > 0))
{

View File

@@ -792,13 +792,9 @@ void DrawCapsule(Vector3 startPos, Vector3 endPos, float radius, int slices, int
{
for (int j = 0; j < slices; j++)
{
// Building up the rings from capCenter in the direction of the 'direction' vector computed earlier
// we build up the rings from capCenter in the direction of the 'direction' vector we computed earlier
// as we iterate through the rings they must be placed higher above the center, the height we need is sin(angle(i))
// as we iterate through the rings they must get smaller by the cos(angle(i))
// compute the four vertices
// Compute the four vertices
float ringSin1 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle*( i + 0 ));
float ringCos1 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle*( i + 0 ));
Vector3 w1 = (Vector3){
@@ -935,13 +931,9 @@ void DrawCapsuleWires(Vector3 startPos, Vector3 endPos, float radius, int slices
{
for (int j = 0; j < slices; j++)
{
// Building up the rings from capCenter in the direction of the 'direction' vector computed earlier
// we build up the rings from capCenter in the direction of the 'direction' vector we computed earlier
// as we iterate through the rings they must be placed higher above the center, the height we need is sin(angle(i))
// as we iterate through the rings they must get smaller by the cos(angle(i))
// compute the four vertices
// Compute the four vertices
float ringSin1 = sinf(baseSliceAngle*(j + 0))*cosf(baseRingAngle*( i + 0 ));
float ringCos1 = cosf(baseSliceAngle*(j + 0))*cosf(baseRingAngle*( i + 0 ));
Vector3 w1 = (Vector3){
@@ -1147,7 +1139,7 @@ Model LoadModel(const char *fileName)
// Load model from generated mesh
// WARNING: A shallow copy of mesh is generated, passed by value,
// as long as struct contains pointers to data and some values, we get a copy
// as long as struct contains pointers to data and some values, get a copy
// of mesh pointing to same data as original version... be careful!
Model LoadModelFromMesh(Mesh mesh)
{
@@ -1194,7 +1186,7 @@ bool IsModelValid(Model model)
if ((model.meshes[i].boneIndices != NULL) && (model.meshes[i].vboId[7] == 0)) { result = false; break; } // Vertex boneIndices buffer not uploaded to GPU
if ((model.meshes[i].boneWeights != NULL) && (model.meshes[i].vboId[8] == 0)) { result = false; break; } // Vertex boneWeights buffer not uploaded to GPU
// NOTE: Some OpenGL versions do not support VAO, so we don't check it
// NOTE: Some OpenGL versions do not support VAO, so avoid below check
//if (model.meshes[i].vaoId == 0) { result = false; break }
}
@@ -1211,7 +1203,7 @@ void UnloadModel(Model model)
// Unload materials maps
// NOTE: As the user could be sharing shaders and textures between models,
// we don't unload the material but just free its maps,
// don't unload the material but free its maps,
// the user is responsible for freeing models shaders and textures
for (int i = 0; i < model.materialCount; i++) RL_FREE(model.materials[i].maps);
@@ -1510,8 +1502,8 @@ void DrawMesh(Mesh mesh, Material material, Matrix transform)
}
// Get a copy of current matrices to work with,
// just in case stereo render is required, and we need to modify them
// NOTE: At this point the modelview matrix just contains the view matrix (camera)
// in case stereo render is required, and they need to be modified
// NOTE: At this point the modelview matrix contains the view matrix (camera)
// That's because BeginMode3D() sets it and there is no model-drawing function
// that modifies it, all use rlPushMatrix() and rlPopMatrix()
Matrix matModel = MatrixIdentity();
@@ -1729,8 +1721,8 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
}
// Get a copy of current matrices to work with,
// just in case stereo render is required, and we need to modify them
// NOTE: At this point the modelview matrix just contains the view matrix (camera)
// in case stereo render is required, and they need to be modified
// NOTE: At this point the modelview matrix contains the view matrix (camera)
// That's because BeginMode3D() sets it and there is no model-drawing function
// that modifies it, all use rlPushMatrix() and rlPopMatrix()
Matrix matModel = MatrixIdentity();
@@ -1753,7 +1745,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i
// This could alternatively use a static VBO and either glMapBuffer() or glBufferSubData()
// It isn't clear which would be reliably faster in all cases and on all platforms,
// anecdotally glMapBuffer() seems very slow (syncs) while glBufferSubData() seems
// anecdotally glMapBuffer() seems quite slow (syncs) while glBufferSubData() seems
// no faster, since all the transform matrices are transferred anyway
instancesVboId = rlLoadVertexBuffer(instanceTransform, instances*sizeof(float16), false);
@@ -2508,7 +2500,7 @@ static void UpdateModelAnimationVertexBuffers(Model model)
bufferUpdateRequired = true;
// Normals processing
// NOTE: We use meshes.baseNormals (default normal) to calculate meshes.normals (animated normals)
// NOTE: Using meshes.baseNormals (default normal) to calculate meshes.normals (animated normals)
if ((mesh.normals != NULL) && (mesh.animNormals != NULL ))
{
animNormal = (Vector3){ mesh.normals[vCounter], mesh.normals[vCounter + 1], mesh.normals[vCounter + 2] };
@@ -3375,7 +3367,7 @@ Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
Vector2 *mapTexcoords = (Vector2 *)RL_MALLOC(maxTriangles*3*sizeof(Vector2));
Vector3 *mapNormals = (Vector3 *)RL_MALLOC(maxTriangles*3*sizeof(Vector3));
// Define the 6 normals of the cube, we will combine them accordingly later...
// Define the 6 normals of the cube, combined accordingly later
Vector3 n1 = { 1.0f, 0.0f, 0.0f };
Vector3 n2 = { -1.0f, 0.0f, 0.0f };
Vector3 n3 = { 0.0f, 1.0f, 0.0f };
@@ -3383,7 +3375,8 @@ Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
Vector3 n5 = { 0.0f, 0.0f, -1.0f };
Vector3 n6 = { 0.0f, 0.0f, 1.0f };
// NOTE: We use texture rectangles to define different textures for top-bottom-front-back-right-left (6)
// NOTE: Using texture rectangles to define different
// textures for top-bottom-front-back-right-left (6)
typedef struct RectangleF {
float x;
float y;
@@ -3402,7 +3395,7 @@ Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
{
for (int x = 0; x < cubicmap.width; x++)
{
// Define the 8 vertex of the cube, we will combine them accordingly later...
// Define the 8 vertex of the cube, to be combined accordingly later
Vector3 v1 = { w*(x - 0.5f), h2, h*(z - 0.5f) };
Vector3 v2 = { w*(x - 0.5f), h2, h*(z + 0.5f) };
Vector3 v3 = { w*(x + 0.5f), h2, h*(z + 0.5f) };
@@ -3412,7 +3405,7 @@ Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
Vector3 v7 = { w*(x - 0.5f), 0, h*(z + 0.5f) };
Vector3 v8 = { w*(x + 0.5f), 0, h*(z + 0.5f) };
// We check pixel color to be WHITE -> draw full cube
// Check pixel color to be WHITE -> draw full cube
if (COLOR_EQUAL(pixels[z*cubicmap.width + x], WHITE))
{
// Define triangles and checking collateral cubes
@@ -3589,7 +3582,7 @@ Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
tcCounter += 6;
}
}
// We check pixel color to be BLACK, we will only draw floor and roof
// Check pixel color to be BLACK, in that case only drawing floor and roof
else if (COLOR_EQUAL(pixels[z*cubicmap.width + x], BLACK))
{
// Define top triangles (2 tris, 6 vertex --> v1-v2-v3, v1-v3-v4)
@@ -4106,8 +4099,8 @@ bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, floa
{
bool collision = false;
// Simple way to check for collision, just checking distance between two points
// Unfortunately, sqrtf() is a costly operation, so we avoid it with following solution
// Simple way to check for collision, checking distance between two points
// Unfortunately, sqrtf() is a costly operation, so avoid it with following solution
/*
float dx = center1.x - center2.x; // X distance between centers
float dy = center1.y - center2.y; // Y distance between centers
@@ -4235,7 +4228,7 @@ RayCollision GetRayCollisionBox(Ray ray, BoundingBox box)
// Get vector center point->hit point
collision.normal = Vector3Subtract(collision.point, collision.normal);
// Scale vector to unit cube
// NOTE: We use an additional .01 to fix numerical errors
// NOTE: Use an additional .01 to fix numerical errors
collision.normal = Vector3Scale(collision.normal, 2.01f);
collision.normal = Vector3Divide(collision.normal, Vector3Subtract(box.max, box.min));
// The relevant elements of the vector are now slightly larger than 1.0f (or smaller than -1.0f)
@@ -4476,7 +4469,7 @@ static Model LoadOBJ(const char *fileName)
}
else if ((lastMaterial != -1) && (objAttributes.material_ids[faceId] != lastMaterial))
{
meshIndex++; // If this is a new material, we need to allocate a new mesh
meshIndex++; // If this is a new material, a new mesh is allocated
}
lastMaterial = objAttributes.material_ids[faceId];
@@ -4492,7 +4485,7 @@ static Model LoadOBJ(const char *fileName)
model.materialCount = objMaterialCount;
model.materials = (Material *)MemAlloc(sizeof(Material)*objMaterialCount);
}
else // We must allocate at least one material
else // Allocate at least one material
{
model.materialCount = 1;
model.materials = (Material *)MemAlloc(sizeof(Material)*1);
@@ -4515,7 +4508,7 @@ static Model LoadOBJ(const char *fileName)
// Walk all the faces
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
{
bool newMesh = false; // Do we need a new mesh?
bool newMesh = false; // Is a new mesh required?
if (faceId >= nextShapeEnd)
{
// Try to find the last vert in the next shape
@@ -4585,7 +4578,7 @@ static Model LoadOBJ(const char *fileName)
// Walk all the faces
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
{
bool newMesh = false; // Do we need a new mesh?
bool newMesh = false; // Is a new mesh required?
if (faceId >= nextShapeEnd)
{
// Try to find the last vert in the next shape
@@ -4595,7 +4588,7 @@ static Model LoadOBJ(const char *fileName)
newMesh = true;
}
// If this is a new material, we need to allocate a new mesh
// If this is a new material, a new mesh is allocated
if (lastMaterial != -1 && objAttributes.material_ids[faceId] != lastMaterial) newMesh = true;
lastMaterial = objAttributes.material_ids[faceId];
@@ -4841,7 +4834,7 @@ static Model LoadIQM(const char *fileName)
model.meshes[i].indices = (unsigned short *)RL_CALLOC(model.meshes[i].triangleCount*3, sizeof(unsigned short));
#if !SUPPORT_GPU_SKINNING
// Animated vertex data, what we actually process for rendering
// Animated vertex data, processed for rendering
// NOTE: Animated vertex should be re-uploaded to GPU (if not using GPU skinning)
model.meshes[i].animVertices = (float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float));
model.meshes[i].animNormals = (float *)RL_CALLOC(model.meshes[i].vertexCount*3, sizeof(float));
@@ -4861,7 +4854,7 @@ static Model LoadIQM(const char *fileName)
for (unsigned int i = imesh[m].first_triangle; i < (imesh[m].first_triangle + imesh[m].num_triangles); i++)
{
// IQM triangles indexes are stored in counter-clockwise, but raylib processes the index in linear order,
// expecting they point to the counter-clockwise vertex triangle, so we need to reverse triangle indexes
// expecting they point to the counter-clockwise vertex triangle, so triangle indexes need to be reversed
// NOTE: raylib renders vertex data in counter-clockwise order (standard convention) by default
model.meshes[m].indices[tcounter + 2] = tri[i].vertex[0] - imesh[m].first_vertex;
model.meshes[m].indices[tcounter + 1] = tri[i].vertex[1] - imesh[m].first_vertex;
@@ -5496,7 +5489,7 @@ static Model LoadGLTF(const char *fileName)
int primitivesCount = 0;
bool dracoCompression = false;
// NOTE: We will load every primitive in the glTF as a separate raylib Mesh
// NOTE: Load every primitive in the glTF as a separate raylib Mesh
// Determine total number of meshes needed from the node hierarchy
for (unsigned int i = 0; i < data->nodes_count; i++)
{
@@ -5528,7 +5521,7 @@ static Model LoadGLTF(const char *fileName)
model.meshCount = primitivesCount;
model.meshes = (Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh));
// NOTE: We keep an extra slot for default material, in case some mesh requires it
// NOTE: Keep an extra slot for default material, in case some mesh requires it
model.materialCount = (int)data->materials_count + 1;
model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material));
model.materials[0] = LoadMaterialDefault(); // Load default material (index: 0)
@@ -5684,7 +5677,7 @@ static Model LoadGLTF(const char *fileName)
for (unsigned int p = 0; p < mesh->primitives_count; p++)
{
// NOTE: We only support primitives defined by triangles
// NOTE: Only support primitives defined by triangles
// Other alternatives: points, lines, line_strip, triangle_strip
if (mesh->primitives[p].type != cgltf_primitive_type_triangles) continue;
@@ -6067,7 +6060,7 @@ static Model LoadGLTF(const char *fileName)
float *temp = (float *)RL_MALLOC(attribute->count*4*sizeof(float));
LOAD_ATTRIBUTE(attribute, 4, float, temp);
// Convert data to raylib color data type (4 bytes), we expect the color data normalized
// Convert data to raylib color data type (4 bytes), color data must be normalized
for (unsigned int c = 0; c < attribute->count*4; c++) model.meshes[meshIndex].colors[c] = (unsigned char)(temp[c]*255.0f);
RL_FREE(temp);
@@ -6125,7 +6118,7 @@ static Model LoadGLTF(const char *fileName)
{
// The primitive actually keeps the pointer to the corresponding material,
// raylib instead assigns to the mesh the by its index, as loaded in model.materials array
// To get the index, we check if material pointers match, and we assign the corresponding index,
// To get the index, check if material pointers match, and assign the corresponding index,
// skipping index 0, the default material
if (&data->materials[m] == mesh->primitives[p].material)
{
@@ -6187,7 +6180,7 @@ static Model LoadGLTF(const char *fileName)
{
bool hasJoints = false;
// NOTE: We only support primitives defined by triangles
// NOTE: Only support primitives defined by triangles
if (mesh->primitives[p].type != cgltf_primitive_type_triangles) continue;
for (unsigned int j = 0; j < mesh->primitives[p].attributes_count; j++)
@@ -6234,7 +6227,7 @@ static Model LoadGLTF(const char *fileName)
boneIdOverflowWarning = true;
}
// Despite the possible overflow, we convert data to unsigned char
// Despite the possible overflow, convert data to unsigned char
model.meshes[meshIndex].boneIndices[b] = (unsigned char)temp[b];
}
@@ -6284,8 +6277,7 @@ static Model LoadGLTF(const char *fileName)
model.meshes[meshIndex].boneWeights = (float *)RL_CALLOC(model.meshes[meshIndex].vertexCount*4, sizeof(float));
// Load 4 components of float data type into mesh.boneWeights
// for cgltf_attribute_type_weights we have:
// for cgltf_attribute_type_weights:
// - data.meshes[0] (256 vertices)
// - 256 values, provided as cgltf_type_vec4 of float (4 byte per joint, stride 16)
LOAD_ATTRIBUTE(attribute, 4, float, model.meshes[meshIndex].boneWeights)
@@ -6296,9 +6288,9 @@ static Model LoadGLTF(const char *fileName)
}
}
// Check if we are animated, and the mesh was not given any bone assignments, but is the child of a bone node
// in this case we need to fully attach all the verts to the parent bone so it will animate with the bone
if (data->skins_count > 0 && !hasJoints && node->parent != NULL && node->parent->mesh == NULL)
// Check if animated, and the mesh was not given any bone assignments, but is the child of a bone node
// in this case, all the verts need to be attached to the parent bone so it will animate with the bone
if ((data->skins_count > 0) && !hasJoints && (node->parent != NULL) && (node->parent->mesh == NULL))
{
int parentBoneId = -1;
for (int joint = 0; joint < model.skeleton.boneCount; joint++)
@@ -6435,7 +6427,7 @@ static bool GetPoseAtTimeGLTF(cgltf_interpolation_type interpolationType, cgltf_
}
else if (output->type == cgltf_type_vec4)
{
// Only v4 is for rotations, so we know it's a quaternion
// Only v4 is for rotations, so it's a quaternion
switch (interpolationType)
{
case cgltf_interpolation_type_step:
@@ -6822,7 +6814,7 @@ static Model LoadM3D(const char *fileName)
}
else TRACELOG(LOG_INFO, "MODEL: [%s] M3D data loaded successfully: %i faces/%i materials", fileName, m3d->numface, m3d->nummaterial);
// no face? this is probably just a material library
// Check if face is found, if not, probably just a material library
if (!m3d->numface)
{
m3d_free(m3d);
@@ -6841,12 +6833,12 @@ static Model LoadM3D(const char *fileName)
TRACELOG(LOG_INFO, "MODEL: No materials, putting all meshes in a default material");
}
// We always need a default material, so we add +1
// A default material is always required, so adding +1
model.materialCount++;
// Faces must be in non-decreasing materialid order. Verify that quickly, sorting them otherwise
// WARNING: Sorting is not needed, valid M3D model files should already be sorted
// Just keeping the sorting function for reference (Check PR #3363 #3385)
// Keeping the sorting function for reference (Check PR #3363 #3385)
/*
for (a = 1; a < m3d->numface; a++)
{
@@ -6902,7 +6894,7 @@ static Model LoadM3D(const char *fileName)
mi = m3d->face[i].materialid;
// Only allocate colors VertexBuffer if there's a color vertex in the model for this material batch
// if all colors are fully transparent black for all verteces of this materal, then we assume no vertex colors
// if all colors are fully transparent black for all verteces of this materal, then assuming no vertex colors
for (j = i, l = vcolor = 0; (j < (int)m3d->numface) && (mi == m3d->face[j].materialid); j++, l++)
{
if (!m3d->vertex[m3d->face[j].vertex[0]].color ||
@@ -6916,11 +6908,11 @@ static Model LoadM3D(const char *fileName)
model.meshes[k].texcoords = (float *)RL_CALLOC(model.meshes[k].vertexCount*2, sizeof(float));
model.meshes[k].normals = (float *)RL_CALLOC(model.meshes[k].vertexCount*3, sizeof(float));
// If no map is provided, or we have colors defined, we allocate storage for vertex colors
// If no map is provided, or colors are defined, allocate storage for vertex colors
// M3D specs only consider vertex colors if no material is provided, however raylib uses both and mixes the colors
if ((mi == M3D_UNDEF) || vcolor) model.meshes[k].colors = (unsigned char *)RL_CALLOC(model.meshes[k].vertexCount*4, sizeof(unsigned char));
// If no map is provided and we allocated vertex colors, set them to white
// If no map is provided and vertex colors are allocated, set them to white
if ((mi == M3D_UNDEF) && (model.meshes[k].colors != NULL))
{
for (int c = 0; c < model.meshes[k].vertexCount*4; c++) model.meshes[k].colors[c] = 255;
@@ -6951,7 +6943,7 @@ static Model LoadM3D(const char *fileName)
model.meshes[k].vertices[l*9 + 7] = m3d->vertex[m3d->face[i].vertex[2]].y*m3d->scale;
model.meshes[k].vertices[l*9 + 8] = m3d->vertex[m3d->face[i].vertex[2]].z*m3d->scale;
// Without vertex color (full transparency), we use the default color
// Without vertex color (full transparency), using the default color
if (model.meshes[k].colors != NULL)
{
if (m3d->vertex[m3d->face[i].vertex[0]].color & 0xff000000)
@@ -6992,7 +6984,7 @@ static Model LoadM3D(const char *fileName)
{
int skinid = m3d->vertex[m3d->face[i].vertex[n]].skinid;
// Check if there is a skin for this mesh, should be, just failsafe
// Check if there is a skin for this mesh
if ((skinid != M3D_UNDEF) && (skinid < (int)m3d->numskin))
{
for (j = 0; j < 4; j++)
@@ -7003,8 +6995,8 @@ static Model LoadM3D(const char *fileName)
}
else
{
// raylib does not handle boneless meshes with skeletal animations, so
// we put all vertices without a bone into a special "no bone" bone
// Boneless meshes with skeletal animations are not supported, so
// putting all vertices without a bone into a special "no bone" bone
model.meshes[k].boneIndices[l*12 + n*4] = m3d->numbone;
model.meshes[k].boneWeights[l*12 + n*4] = 1.0f;
}
@@ -7215,7 +7207,7 @@ static ModelAnimation *LoadModelAnimationsM3D(const char *fileName, int *animCou
bones[i].parent = -1;
memcpy(bones[i].name, "NO BONE", 7);
// M3D stores frames at arbitrary intervals with sparse skeletons. We need full skeletons at
// M3D stores frames at arbitrary intervals with sparse skeletons; Full skeletons is required at
// regular intervals, so let the M3D SDK do the heavy lifting and calculate interpolated bones
for (i = 0; i < animations[a].keyframeCount; i++)
{

View File

@@ -1946,7 +1946,7 @@ void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, C
// Draw spline segment: Linear, 2 points
void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color)
{
// NOTE: For the linear spline no subdivisions are used, just a single quad
// NOTE: For the linear spline no subdivisions are used, only a single quad
Vector2 delta = { p2.x - p1.x, p2.y - p1.y };
float length = sqrtf(delta.x*delta.x + delta.y*delta.y);

View File

@@ -10,7 +10,7 @@
* #define SUPPORT_FILEFORMAT_TTF
* #define SUPPORT_FILEFORMAT_BDF
* Selected desired fileformats to be supported for loading. Some of those formats are
* supported by default, to remove support, just comment unrequired #define in this module
* supported by default, to remove support, comment unrequired #define in this module
*
* #define TEXTSPLIT_MAX_TEXT_BUFFER_LENGTH
* TextSplit() function static buffer max size
@@ -157,7 +157,7 @@ extern void LoadFontDefault(void)
#define BIT_CHECK(a,b) ((a) & (1u << (b)))
// Check to see if the font for an image has alreeady been allocated,
// and if no need to upload, then just return
// and if no need to upload, then return
if (defaultFont.glyphs != NULL) return;
// NOTE: Using UTF-8 encoding table for Unicode U+0000..U+00FF Basic Latin + Latin-1 Supplement

View File

@@ -22,7 +22,7 @@
* #define SUPPORT_FILEFORMAT_PVR
* #define SUPPORT_FILEFORMAT_ASTC
* Select desired fileformats to be supported for image data loading. Some of those formats are
* supported by default, to remove support, just comment unrequired #define in this module
* supported by default, to remove support, comment unrequired #define in this module
*
* #define SUPPORT_IMAGE_EXPORT
* Support image export in multiple file formats
@@ -1870,7 +1870,7 @@ void ImageToPOT(Image *image, Color fill)
if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return;
// Calculate next power-of-two values
// NOTE: Just add the required amount of pixels at the right and bottom sides of image...
// NOTE: Add the required amount of pixels at the right and bottom sides of image...
int potWidth = (int)powf(2, ceilf(logf((float)image->width)/logf(2)));
int potHeight = (int)powf(2, ceilf(logf((float)image->height)/logf(2)));
@@ -2014,7 +2014,7 @@ void ImageAlphaMask(Image *image, Image alphaMask)
Image mask = ImageCopy(alphaMask);
if (mask.format != PIXELFORMAT_UNCOMPRESSED_GRAYSCALE) ImageFormat(&mask, PIXELFORMAT_UNCOMPRESSED_GRAYSCALE);
// In case image is only grayscale, just add alpha channel
// In case image is only grayscale, add alpha channel
if (image->format == PIXELFORMAT_UNCOMPRESSED_GRAYSCALE)
{
unsigned char *data = (unsigned char *)RL_MALLOC(image->width*image->height*2);
@@ -2589,7 +2589,7 @@ void ImageFlipHorizontal(Image *image)
// OPTION 1: Move pixels with memcpy()
//memcpy(flippedData + (y*image->width + x)*bytesPerPixel, ((unsigned char *)image->data) + (y*image->width + (image->width - 1 - x))*bytesPerPixel, bytesPerPixel);
// OPTION 2: Just copy data pixel by pixel
// OPTION 2: Copy data pixel by pixel
for (int i = 0; i < bytesPerPixel; i++) flippedData[(y*image->width + x)*bytesPerPixel + i] = ((unsigned char *)image->data)[(y*image->width + (image->width - 1 - x))*bytesPerPixel + i];
}
}
@@ -4587,10 +4587,10 @@ void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2
rlSetTexture(0);
// NOTE: Vertex position can be transformed using matrices
// but the process is way more costly than just calculating
// but the process is way more costly than calculating
// the vertex positions manually, like done above
// Old implementation is left here for educational purposes,
// just in case someone wants to do some performance test
// in case someone wants to do some performance test
/*
rlSetTexture(texture.id);
rlPushMatrix();