Browse Source

Remove trailing spaces

pull/1428/head
Ray 4 years ago
parent
commit
3e1cd487df
11 changed files with 337 additions and 325 deletions
  1. +4
    -4
      src/camera.h
  2. +31
    -31
      src/core.c
  3. +43
    -43
      src/models.c
  4. +16
    -16
      src/raudio.c
  5. +1
    -1
      src/raylib.h
  6. +16
    -16
      src/raymath.h
  7. +56
    -56
      src/rlgl.h
  8. +4
    -2
      src/shapes.c
  9. +13
    -13
      src/text.c
  10. +152
    -142
      src/textures.c
  11. +1
    -1
      src/utils.c

+ 4
- 4
src/camera.h View File

@ -319,7 +319,7 @@ void UpdateCamera(Camera *camera)
CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
if (CAMERA.targetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) CAMERA.targetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP; if (CAMERA.targetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) CAMERA.targetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP;
} }
// Camera looking down // Camera looking down
else if ((camera->position.y > camera->target.y) && (CAMERA.targetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) else if ((camera->position.y > camera->target.y) && (CAMERA.targetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{ {
@ -443,7 +443,7 @@ void UpdateCamera(Camera *camera)
camera->target.x = camera->position.x - transform.m12; camera->target.x = camera->position.x - transform.m12;
camera->target.y = camera->position.y - transform.m13; camera->target.y = camera->position.y - transform.m13;
camera->target.z = camera->position.z - transform.m14; camera->target.z = camera->position.z - transform.m14;
// If movement detected (some key pressed), increase swinging // If movement detected (some key pressed), increase swinging
for (int i = 0; i < 6; i++) if (direction[i]) { swingCounter++; break; } for (int i = 0; i < 6; i++) if (direction[i]) { swingCounter++; break; }
@ -487,10 +487,10 @@ void UpdateCamera(Camera *camera)
// TODO: It seems camera->position is not correctly updated or some rounding issue makes the camera move straight to camera->target... // TODO: It seems camera->position is not correctly updated or some rounding issue makes the camera move straight to camera->target...
camera->position.x = sinf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.x; camera->position.x = sinf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.x;
if (CAMERA.angle.y <= 0.0f) camera->position.y = sinf(CAMERA.angle.y)*CAMERA.targetDistance*sinf(CAMERA.angle.y) + camera->target.y; if (CAMERA.angle.y <= 0.0f) camera->position.y = sinf(CAMERA.angle.y)*CAMERA.targetDistance*sinf(CAMERA.angle.y) + camera->target.y;
else camera->position.y = -sinf(CAMERA.angle.y)*CAMERA.targetDistance*sinf(CAMERA.angle.y) + camera->target.y; else camera->position.y = -sinf(CAMERA.angle.y)*CAMERA.targetDistance*sinf(CAMERA.angle.y) + camera->target.y;
camera->position.z = cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.z; camera->position.z = cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.z;
} break; } break;

+ 31
- 31
src/core.c View File

@ -229,12 +229,12 @@
#include <termios.h> // POSIX terminal control definitions - tcgetattr(), tcsetattr() #include <termios.h> // POSIX terminal control definitions - tcgetattr(), tcsetattr()
#include <pthread.h> // POSIX threads management (inputs reading) #include <pthread.h> // POSIX threads management (inputs reading)
#include <dirent.h> // POSIX directory browsing #include <dirent.h> // POSIX directory browsing
#include <sys/ioctl.h> // UNIX System call for device-specific input/output operations - ioctl() #include <sys/ioctl.h> // UNIX System call for device-specific input/output operations - ioctl()
#include <linux/kd.h> // Linux: KDSKBMODE, K_MEDIUMRAM constants definition #include <linux/kd.h> // Linux: KDSKBMODE, K_MEDIUMRAM constants definition
#include <linux/input.h> // Linux: Keycodes constants definition (KEY_A, ...) #include <linux/input.h> // Linux: Keycodes constants definition (KEY_A, ...)
#include <linux/joystick.h> // Linux: Joystick support library #include <linux/joystick.h> // Linux: Joystick support library
#if defined(PLATFORM_RPI) #if defined(PLATFORM_RPI)
#include "bcm_host.h" // Raspberry Pi VideoCore IV access functions #include "bcm_host.h" // Raspberry Pi VideoCore IV access functions
#endif #endif
@ -244,7 +244,7 @@
#include <xf86drm.h> // Direct Rendering Manager user-level library interface #include <xf86drm.h> // Direct Rendering Manager user-level library interface
#include <xf86drmMode.h> // Direct Rendering Manager modesetting interface #include <xf86drmMode.h> // Direct Rendering Manager modesetting interface
#endif #endif
#include "EGL/egl.h" // EGL library - Native platform display device control functions #include "EGL/egl.h" // EGL library - Native platform display device control functions
#include "EGL/eglext.h" // EGL library - Extensions #include "EGL/eglext.h" // EGL library - Extensions
#include "GLES2/gl2.h" // OpenGL ES 2.0 library #include "GLES2/gl2.h" // OpenGL ES 2.0 library
@ -656,7 +656,7 @@ void InitWindow(int width, int height, const char *title)
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f }; CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW; CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
CORE.Input.Gamepad.lastButtonPressed = -1; CORE.Input.Gamepad.lastButtonPressed = -1;
#if defined(PLATFORM_UWP) #if defined(PLATFORM_UWP)
// The axis count is 6 (2 thumbsticks and left and right trigger) // The axis count is 6 (2 thumbsticks and left and right trigger)
CORE.Input.Gamepad.axisCount = 6; CORE.Input.Gamepad.axisCount = 6;
@ -834,7 +834,7 @@ void CloseWindow(void)
CORE.Window.gbmDevice = NULL; CORE.Window.gbmDevice = NULL;
} }
if(CORE.Window.crtc) if (CORE.Window.crtc)
{ {
if (CORE.Window.connector) if (CORE.Window.connector)
{ {
@ -925,7 +925,7 @@ bool WindowShouldClose(void)
while (!CORE.Window.alwaysRun && CORE.Window.minimized) glfwWaitEvents(); while (!CORE.Window.alwaysRun && CORE.Window.minimized) glfwWaitEvents();
CORE.Window.shouldClose = glfwWindowShouldClose(CORE.Window.handle); CORE.Window.shouldClose = glfwWindowShouldClose(CORE.Window.handle);
// Reset close status for next frame // Reset close status for next frame
glfwSetWindowShouldClose(CORE.Window.handle, GLFW_FALSE); glfwSetWindowShouldClose(CORE.Window.handle, GLFW_FALSE);
@ -1029,7 +1029,7 @@ void ToggleFullscreen(void)
else Module.requestFullscreen(true, true); else Module.requestFullscreen(true, true);
); );
*/ */
//EM_ASM(Module.requestFullscreen(false, false);); //EM_ASM(Module.requestFullscreen(false, false););
/* /*
@ -1043,13 +1043,13 @@ void ToggleFullscreen(void)
.canvasResizedCallback = EmscriptenWindowResizedCallback, //on_canvassize_changed, .canvasResizedCallback = EmscriptenWindowResizedCallback, //on_canvassize_changed,
.canvasResizedCallbackUserData = NULL .canvasResizedCallbackUserData = NULL
}; };
emscripten_request_fullscreen("#canvas", false); emscripten_request_fullscreen("#canvas", false);
//emscripten_request_fullscreen_strategy("#canvas", EM_FALSE, &strategy); //emscripten_request_fullscreen_strategy("#canvas", EM_FALSE, &strategy);
//emscripten_enter_soft_fullscreen("canvas", &strategy); //emscripten_enter_soft_fullscreen("canvas", &strategy);
TRACELOG(LOG_INFO, "emscripten_request_fullscreen_strategy"); TRACELOG(LOG_INFO, "emscripten_request_fullscreen_strategy");
} }
else else
{ {
TRACELOG(LOG_INFO, "emscripten_exit_fullscreen"); TRACELOG(LOG_INFO, "emscripten_exit_fullscreen");
emscripten_exit_fullscreen(); emscripten_exit_fullscreen();
@ -1350,12 +1350,12 @@ Vector2 GetWindowPosition(void)
Vector2 GetWindowScaleDPI(void) Vector2 GetWindowScaleDPI(void)
{ {
Vector2 scale = { 1.0f, 1.0f }; Vector2 scale = { 1.0f, 1.0f };
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
float xdpi = 1.0; float xdpi = 1.0;
float ydpi = 1.0; float ydpi = 1.0;
Vector2 windowPos = GetWindowPosition(); Vector2 windowPos = GetWindowPosition();
int monitorCount = 0; int monitorCount = 0;
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount); GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
@ -1363,12 +1363,12 @@ Vector2 GetWindowScaleDPI(void)
for (int i = 0; i < monitorCount; i++) for (int i = 0; i < monitorCount; i++)
{ {
glfwGetMonitorContentScale(monitors[i], &xdpi, &ydpi); glfwGetMonitorContentScale(monitors[i], &xdpi, &ydpi);
int xpos, ypos, width, height; int xpos, ypos, width, height;
glfwGetMonitorWorkarea(monitors[i], &xpos, &ypos, &width, &height); glfwGetMonitorWorkarea(monitors[i], &xpos, &ypos, &width, &height);
if ((windowPos.x >= xpos) && (windowPos.x < xpos + width) &&
if ((windowPos.x >= xpos) && (windowPos.x < xpos + width) && (windowPos.y >= ypos) && (windowPos.y < ypos + height))
(windowPos.y >= ypos) && (windowPos.y < ypos + height))
{ {
scale.x = xdpi; scale.x = xdpi;
scale.y = ydpi; scale.y = ydpi;
@ -2146,7 +2146,7 @@ const char *GetPrevDirectoryPath(const char *dirPath)
{ {
// Check for root: "C:\" or "/" // Check for root: "C:\" or "/"
if (((i == 2) && (dirPath[1] ==':')) || (i == 0)) i++; if (((i == 2) && (dirPath[1] ==':')) || (i == 0)) i++;
strncpy(prevDirPath, dirPath, i); strncpy(prevDirPath, dirPath, i);
break; break;
} }
@ -2221,9 +2221,9 @@ void ClearDirectoryFiles(void)
bool ChangeDirectory(const char *dir) bool ChangeDirectory(const char *dir)
{ {
bool result = CHDIR(dir); bool result = CHDIR(dir);
if (result != 0) TRACELOG(LOG_WARNING, "SYSTEM: Failed to change to directory: %s", dir); if (result != 0) TRACELOG(LOG_WARNING, "SYSTEM: Failed to change to directory: %s", dir);
return (result == 0); return (result == 0);
} }
@ -2330,13 +2330,13 @@ void SaveStorageValue(unsigned int position, int value)
{ {
// RL_REALLOC succeded // RL_REALLOC succeded
int *dataPtr = (int *)newFileData; int *dataPtr = (int *)newFileData;
dataPtr[position] = value; dataPtr[position] = value;
} }
else else
{ {
// RL_REALLOC failed // RL_REALLOC failed
TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to realloc data (%u), position in bytes (%u) bigger than actual file size", path, dataSize, position*sizeof(int)); TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to realloc data (%u), position in bytes (%u) bigger than actual file size", path, dataSize, position*sizeof(int));
// We store the old size of the file // We store the old size of the file
newFileData = fileData; newFileData = fileData;
newDataSize = dataSize; newDataSize = dataSize;
@ -3556,7 +3556,7 @@ static bool InitGraphicsDevice(int width, int height)
eglGetConfigAttrib(CORE.Window.device, CORE.Window.config, EGL_NATIVE_VISUAL_ID, &displayFormat); eglGetConfigAttrib(CORE.Window.device, CORE.Window.config, EGL_NATIVE_VISUAL_ID, &displayFormat);
// At this point we need to manage render size vs screen size // At this point we need to manage render size vs screen size
// NOTE: This function use and modify global module variables: // NOTE: This function use and modify global module variables:
// -> CORE.Window.screen.width/CORE.Window.screen.height // -> CORE.Window.screen.width/CORE.Window.screen.height
// -> CORE.Window.render.width/CORE.Window.render.height // -> CORE.Window.render.width/CORE.Window.render.height
// -> CORE.Window.screenScale // -> CORE.Window.screenScale
@ -3570,16 +3570,16 @@ static bool InitGraphicsDevice(int width, int height)
#if defined(PLATFORM_RPI) #if defined(PLATFORM_RPI)
graphics_get_display_size(0, &CORE.Window.display.width, &CORE.Window.display.height); graphics_get_display_size(0, &CORE.Window.display.width, &CORE.Window.display.height);
// Screen size security check // Screen size security check
if (CORE.Window.screen.width <= 0) CORE.Window.screen.width = CORE.Window.display.width; if (CORE.Window.screen.width <= 0) CORE.Window.screen.width = CORE.Window.display.width;
if (CORE.Window.screen.height <= 0) CORE.Window.screen.height = CORE.Window.display.height; if (CORE.Window.screen.height <= 0) CORE.Window.screen.height = CORE.Window.display.height;
// At this point we need to manage render size vs screen size // At this point we need to manage render size vs screen size
// NOTE: This function use and modify global module variables: // NOTE: This function use and modify global module variables:
// -> CORE.Window.screen.width/CORE.Window.screen.height // -> CORE.Window.screen.width/CORE.Window.screen.height
// -> CORE.Window.render.width/CORE.Window.render.height // -> CORE.Window.render.width/CORE.Window.render.height
// -> CORE.Window.screenScale // -> CORE.Window.screenScale
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height); SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
dstRect.x = 0; dstRect.x = 0;
@ -3632,10 +3632,10 @@ static bool InitGraphicsDevice(int width, int height)
} }
// At this point we need to manage render size vs screen size // At this point we need to manage render size vs screen size
// NOTE: This function use and modify global module variables: // NOTE: This function use and modify global module variables:
// -> CORE.Window.screen.width/CORE.Window.screen.height // -> CORE.Window.screen.width/CORE.Window.screen.height
// -> CORE.Window.render.width/CORE.Window.render.height // -> CORE.Window.render.width/CORE.Window.render.height
// -> CORE.Window.screenScale // -> CORE.Window.screenScale
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height); SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
#endif // PLATFORM_DRM #endif // PLATFORM_DRM
@ -4008,7 +4008,7 @@ static void PollInputEvents(void)
// Get remapped buttons // Get remapped buttons
GLFWgamepadstate state = { 0 }; GLFWgamepadstate state = { 0 };
glfwGetGamepadState(i, &state); // This remapps all gamepads so they have their buttons mapped like an xbox controller glfwGetGamepadState(i, &state); // This remapps all gamepads so they have their buttons mapped like an xbox controller
const unsigned char *buttons = state.buttons; const unsigned char *buttons = state.buttons;
for (int k = 0; (buttons != NULL) && (k < GLFW_GAMEPAD_BUTTON_DPAD_LEFT + 1) && (k < MAX_GAMEPAD_BUTTONS); k++) for (int k = 0; (buttons != NULL) && (k < GLFW_GAMEPAD_BUTTON_DPAD_LEFT + 1) && (k < MAX_GAMEPAD_BUTTONS); k++)
@ -4528,7 +4528,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
if (type == AINPUT_EVENT_TYPE_MOTION) if (type == AINPUT_EVENT_TYPE_MOTION)
{ {
if (((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK) || if (((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK) ||
((source & AINPUT_SOURCE_GAMEPAD) == AINPUT_SOURCE_GAMEPAD)) ((source & AINPUT_SOURCE_GAMEPAD) == AINPUT_SOURCE_GAMEPAD))
{ {
// Get first touch position // Get first touch position
@ -4682,7 +4682,7 @@ static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboar
if ((eventType == EMSCRIPTEN_EVENT_KEYDOWN) && (keyEvent->keyCode == 27)) // ESCAPE key (strcmp(keyEvent->code, "Escape") == 0) if ((eventType == EMSCRIPTEN_EVENT_KEYDOWN) && (keyEvent->keyCode == 27)) // ESCAPE key (strcmp(keyEvent->code, "Escape") == 0)
{ {
// WARNING: Not executed when pressing Esc to exit fullscreen, it seems document has priority over #canvas // WARNING: Not executed when pressing Esc to exit fullscreen, it seems document has priority over #canvas
emscripten_exit_pointerlock(); emscripten_exit_pointerlock();
CORE.Window.fullscreen = false; CORE.Window.fullscreen = false;
TRACELOG(LOG_INFO, "CORE.Window.fullscreen = %s", CORE.Window.fullscreen? "true" : "false"); TRACELOG(LOG_INFO, "CORE.Window.fullscreen = %s", CORE.Window.fullscreen? "true" : "false");
@ -5253,7 +5253,7 @@ static void *EventThread(void *arg)
while (!CORE.Window.shouldClose) while (!CORE.Window.shouldClose)
{ {
// Try to read data from the device and only continue if successful // Try to read data from the device and only continue if successful
while(read(worker->fd, &event, sizeof(event)) == (int)sizeof(event)) while (read(worker->fd, &event, sizeof(event)) == (int)sizeof(event))
{ {
// Relative movement parsing // Relative movement parsing
if (event.type == EV_REL) if (event.type == EV_REL)

+ 43
- 43
src/models.c View File

@ -828,9 +828,9 @@ void ExportMesh(Mesh mesh, const char *fileName)
if (IsFileExtension(fileName, ".obj")) if (IsFileExtension(fileName, ".obj"))
{ {
// Estimated data size, it should be enough... // Estimated data size, it should be enough...
int dataSize = mesh.vertexCount/3*strlen("v 0000.00f 0000.00f 0000.00f") + int dataSize = mesh.vertexCount/3*strlen("v 0000.00f 0000.00f 0000.00f") +
mesh.vertexCount/2*strlen("vt 0.000f 0.00f") + mesh.vertexCount/2*strlen("vt 0.000f 0.00f") +
mesh.vertexCount/3*strlen("vn 0.000f 0.00f 0.00f") + mesh.vertexCount/3*strlen("vn 0.000f 0.00f 0.00f") +
mesh.triangleCount/3*strlen("f 00000/00000/00000 00000/00000/00000 00000/00000/00000"); mesh.triangleCount/3*strlen("f 00000/00000/00000 00000/00000/00000 00000/00000/00000");
// NOTE: Text data buffer size is estimated considering mesh data size // NOTE: Text data buffer size is estimated considering mesh data size
@ -879,7 +879,7 @@ void ExportMesh(Mesh mesh, const char *fileName)
RL_FREE(txtData); RL_FREE(txtData);
} }
else if (IsFileExtension(fileName, ".raw")) else if (IsFileExtension(fileName, ".raw"))
{ {
// TODO: Support additional file formats to export mesh vertex data // TODO: Support additional file formats to export mesh vertex data
} }
@ -897,7 +897,7 @@ Material *LoadMaterials(const char *fileName, int *materialCount)
if (IsFileExtension(fileName, ".mtl")) if (IsFileExtension(fileName, ".mtl"))
{ {
tinyobj_material_t *mats = NULL; tinyobj_material_t *mats = NULL;
int result = tinyobj_parse_mtl_file(&mats, &count, fileName); int result = tinyobj_parse_mtl_file(&mats, &count, fileName);
if (result != TINYOBJ_SUCCESS) { if (result != TINYOBJ_SUCCESS) {
TRACELOG(LOG_WARNING, "MATERIAL: [%s] Failed to parse materials file", fileName); TRACELOG(LOG_WARNING, "MATERIAL: [%s] Failed to parse materials file", fileName);
@ -970,7 +970,7 @@ ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount)
{ {
#define IQM_MAGIC "INTERQUAKEMODEL" // IQM file magic number #define IQM_MAGIC "INTERQUAKEMODEL" // IQM file magic number
#define IQM_VERSION 2 // only IQM version 2 supported #define IQM_VERSION 2 // only IQM version 2 supported
unsigned int fileSize = 0; unsigned int fileSize = 0;
unsigned char *fileData = LoadFileData(fileName, &fileSize); unsigned char *fileData = LoadFileData(fileName, &fileSize);
unsigned char *fileDataPtr = fileData; unsigned char *fileDataPtr = fileData;
@ -1036,7 +1036,7 @@ ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount)
//fseek(iqmFile, iqmHeader->ofs_anims, SEEK_SET); //fseek(iqmFile, iqmHeader->ofs_anims, SEEK_SET);
//fread(anim, iqmHeader->num_anims*sizeof(IQMAnim), 1, iqmFile); //fread(anim, iqmHeader->num_anims*sizeof(IQMAnim), 1, iqmFile);
memcpy(anim, fileDataPtr + iqmHeader->ofs_anims, iqmHeader->num_anims*sizeof(IQMAnim)); memcpy(anim, fileDataPtr + iqmHeader->ofs_anims, iqmHeader->num_anims*sizeof(IQMAnim));
ModelAnimation *animations = RL_MALLOC(iqmHeader->num_anims*sizeof(ModelAnimation)); ModelAnimation *animations = RL_MALLOC(iqmHeader->num_anims*sizeof(ModelAnimation));
// frameposes // frameposes
@ -1166,7 +1166,7 @@ ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount)
} }
} }
} }
RL_FREE(fileData); RL_FREE(fileData);
RL_FREE(framedata); RL_FREE(framedata);
@ -2566,11 +2566,11 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
for (int i = 0; i < model.meshCount; i++) for (int i = 0; i < model.meshCount; i++)
{ {
// TODO: Review color + tint premultiplication mechanism // TODO: Review color + tint premultiplication mechanism
// (codifies) Ray not only does this work as expected but // (codifies) Ray not only does this work as expected but
// multiplying *is* definately the way to tint // multiplying *is* definately the way to tint
// can we call it reviewed ? // can we call it reviewed ?
// would you prefer an extra model.tint, that rlDrawMesh uses ? // would you prefer an extra model.tint, that rlDrawMesh uses ?
Color color = model.materials[model.meshMaterial[i]].maps[MAP_DIFFUSE].color; Color color = model.materials[model.meshMaterial[i]].maps[MAP_DIFFUSE].color;
@ -2978,10 +2978,10 @@ static Model LoadOBJ(const char *fileName)
if (ret != TINYOBJ_SUCCESS) TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load OBJ data", fileName); if (ret != TINYOBJ_SUCCESS) TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load OBJ data", fileName);
else TRACELOG(LOG_INFO, "MODEL: [%s] OBJ data loaded successfully: %i meshes / %i materials", fileName, meshCount, materialCount); else TRACELOG(LOG_INFO, "MODEL: [%s] OBJ data loaded successfully: %i meshes / %i materials", fileName, meshCount, materialCount);
model.meshCount = materialCount; model.meshCount = materialCount;
// Init model materials array // Init model materials array
if (materialCount > 0) if (materialCount > 0)
{ {
@ -2989,16 +2989,16 @@ static Model LoadOBJ(const char *fileName)
model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material)); model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material));
TraceLog(LOG_INFO, "MODEL: model has %i material meshes", materialCount); TraceLog(LOG_INFO, "MODEL: model has %i material meshes", materialCount);
} else { } else {
model.meshCount = 1; model.meshCount = 1;
TraceLog(LOG_INFO, "MODEL: No materials, putting all meshes in a default material"); TraceLog(LOG_INFO, "MODEL: No materials, putting all meshes in a default material");
} }
model.meshes = (Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh)); model.meshes = (Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh));
model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int)); model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int));
// count the faces for each material // count the faces for each material
int* matFaces = RL_CALLOC(meshCount, sizeof(int)); int* matFaces = RL_CALLOC(meshCount, sizeof(int));
for (int mi=0; mi<meshCount; mi++) { for (int mi=0; mi<meshCount; mi++) {
for (int fi=0; fi<meshes[mi].length; fi++) { for (int fi=0; fi<meshes[mi].length; fi++) {
int idx = attrib.material_ids[meshes[mi].face_offset + fi]; int idx = attrib.material_ids[meshes[mi].face_offset + fi];
@ -3006,19 +3006,19 @@ static Model LoadOBJ(const char *fileName)
matFaces[idx]++; matFaces[idx]++;
} }
} }
//-------------------------------------- //--------------------------------------
// create the material meshes // create the material meshes
// running counts / indexes for each material mesh as we are
// running counts / indexes for each material mesh as we are // building them at the same time
// building them at the same time
int* vCount = RL_CALLOC(model.meshCount, sizeof(int)); int* vCount = RL_CALLOC(model.meshCount, sizeof(int));
int* vtCount = RL_CALLOC(model.meshCount, sizeof(int)); int* vtCount = RL_CALLOC(model.meshCount, sizeof(int));
int* vnCount = RL_CALLOC(model.meshCount, sizeof(int)); int* vnCount = RL_CALLOC(model.meshCount, sizeof(int));
int* faceCount = RL_CALLOC(model.meshCount, sizeof(int)); int* faceCount = RL_CALLOC(model.meshCount, sizeof(int));
// allocate space for each of the material meshes // allocate space for each of the material meshes
for (int mi=0; mi<model.meshCount; mi++) for (int mi=0; mi<model.meshCount; mi++)
{ {
model.meshes[mi].vertexCount = matFaces[mi] * 3; model.meshes[mi].vertexCount = matFaces[mi] * 3;
model.meshes[mi].triangleCount = matFaces[mi]; model.meshes[mi].triangleCount = matFaces[mi];
@ -3028,26 +3028,26 @@ static Model LoadOBJ(const char *fileName)
model.meshes[mi].vboId = (unsigned int *)RL_CALLOC(DEFAULT_MESH_VERTEX_BUFFERS, sizeof(unsigned int)); model.meshes[mi].vboId = (unsigned int *)RL_CALLOC(DEFAULT_MESH_VERTEX_BUFFERS, sizeof(unsigned int));
model.meshMaterial[mi] = mi; model.meshMaterial[mi] = mi;
} }
// scan through the combined sub meshes and pick out each material mesh // scan through the combined sub meshes and pick out each material mesh
for (unsigned int af = 0; af < attrib.num_faces; af++) for (unsigned int af = 0; af < attrib.num_faces; af++)
{ {
int mm = attrib.material_ids[af]; // mesh material for this face int mm = attrib.material_ids[af]; // mesh material for this face
if (mm == -1) { mm = 0; } // no material object.. if (mm == -1) { mm = 0; } // no material object..
// Get indices for the face // Get indices for the face
tinyobj_vertex_index_t idx0 = attrib.faces[3 * af + 0]; tinyobj_vertex_index_t idx0 = attrib.faces[3 * af + 0];
tinyobj_vertex_index_t idx1 = attrib.faces[3 * af + 1]; tinyobj_vertex_index_t idx1 = attrib.faces[3 * af + 1];
tinyobj_vertex_index_t idx2 = attrib.faces[3 * af + 2]; tinyobj_vertex_index_t idx2 = attrib.faces[3 * af + 2];
// Fill vertices buffer (float) using vertex index of the face // Fill vertices buffer (float) using vertex index of the face
for (int v = 0; v < 3; v++) { model.meshes[mm].vertices[vCount[mm] + v] = attrib.vertices[idx0.v_idx*3 + v]; } vCount[mm] +=3; for (int v = 0; v < 3; v++) { model.meshes[mm].vertices[vCount[mm] + v] = attrib.vertices[idx0.v_idx*3 + v]; } vCount[mm] +=3;
for (int v = 0; v < 3; v++) { model.meshes[mm].vertices[vCount[mm] + v] = attrib.vertices[idx1.v_idx*3 + v]; } vCount[mm] +=3; for (int v = 0; v < 3; v++) { model.meshes[mm].vertices[vCount[mm] + v] = attrib.vertices[idx1.v_idx*3 + v]; } vCount[mm] +=3;
for (int v = 0; v < 3; v++) { model.meshes[mm].vertices[vCount[mm] + v] = attrib.vertices[idx2.v_idx*3 + v]; } vCount[mm] +=3; for (int v = 0; v < 3; v++) { model.meshes[mm].vertices[vCount[mm] + v] = attrib.vertices[idx2.v_idx*3 + v]; } vCount[mm] +=3;
if (attrib.num_texcoords > 0) if (attrib.num_texcoords > 0)
{ {
// Fill texcoords buffer (float) using vertex index of the face // Fill texcoords buffer (float) using vertex index of the face
// NOTE: Y-coordinate must be flipped upside-down to account for // NOTE: Y-coordinate must be flipped upside-down to account for
// raylib's upside down textures... // raylib's upside down textures...
model.meshes[mm].texcoords[vtCount[mm] + 0] = attrib.texcoords[idx0.vt_idx*2 + 0]; model.meshes[mm].texcoords[vtCount[mm] + 0] = attrib.texcoords[idx0.vt_idx*2 + 0];
model.meshes[mm].texcoords[vtCount[mm] + 1] = 1.0f - attrib.texcoords[idx0.vt_idx*2 + 1]; vtCount[mm] += 2; model.meshes[mm].texcoords[vtCount[mm] + 1] = 1.0f - attrib.texcoords[idx0.vt_idx*2 + 1]; vtCount[mm] += 2;
@ -3055,23 +3055,23 @@ static Model LoadOBJ(const char *fileName)
model.meshes[mm].texcoords[vtCount[mm] + 1] = 1.0f - attrib.texcoords[idx1.vt_idx*2 + 1]; vtCount[mm] += 2; model.meshes[mm].texcoords[vtCount[mm] + 1] = 1.0f - attrib.texcoords[idx1.vt_idx*2 + 1]; vtCount[mm] += 2;
model.meshes[mm].texcoords[vtCount[mm] + 0] = attrib.texcoords[idx2.vt_idx*2 + 0]; model.meshes[mm].texcoords[vtCount[mm] + 0] = attrib.texcoords[idx2.vt_idx*2 + 0];
model.meshes[mm].texcoords[vtCount[mm] + 1] = 1.0f - attrib.texcoords[idx2.vt_idx*2 + 1]; vtCount[mm] += 2; model.meshes[mm].texcoords[vtCount[mm] + 1] = 1.0f - attrib.texcoords[idx2.vt_idx*2 + 1]; vtCount[mm] += 2;
} }
if (attrib.num_normals > 0) if (attrib.num_normals > 0)
{ {
// Fill normals buffer (float) using vertex index of the face // Fill normals buffer (float) using vertex index of the face
for (int v = 0; v < 3; v++) { model.meshes[mm].normals[vnCount[mm] + v] = attrib.normals[idx0.vn_idx*3 + v]; } vnCount[mm] +=3; for (int v = 0; v < 3; v++) { model.meshes[mm].normals[vnCount[mm] + v] = attrib.normals[idx0.vn_idx*3 + v]; } vnCount[mm] +=3;
for (int v = 0; v < 3; v++) { model.meshes[mm].normals[vnCount[mm] + v] = attrib.normals[idx1.vn_idx*3 + v]; } vnCount[mm] +=3; for (int v = 0; v < 3; v++) { model.meshes[mm].normals[vnCount[mm] + v] = attrib.normals[idx1.vn_idx*3 + v]; } vnCount[mm] +=3;
for (int v = 0; v < 3; v++) { model.meshes[mm].normals[vnCount[mm] + v] = attrib.normals[idx2.vn_idx*3 + v]; } vnCount[mm] +=3; for (int v = 0; v < 3; v++) { model.meshes[mm].normals[vnCount[mm] + v] = attrib.normals[idx2.vn_idx*3 + v]; } vnCount[mm] +=3;
} }
} }
// Init model materials // Init model materials
for (unsigned int m = 0; m < materialCount; m++) for (unsigned int m = 0; m < materialCount; m++)
{ {
// Init material to default // Init material to default
// NOTE: Uses default shader, which only supports MAP_DIFFUSE // NOTE: Uses default shader, which only supports MAP_DIFFUSE
// (codifies) TODO my lighting shader should support at least // (codifies) TODO my lighting shader should support at least
// diffuse AND specular ... // diffuse AND specular ...
model.materials[m] = LoadMaterialDefault(); model.materials[m] = LoadMaterialDefault();
@ -3083,7 +3083,7 @@ static Model LoadOBJ(const char *fileName)
} else { } else {
model.materials[m].maps[MAP_DIFFUSE].texture = GetTextureDefault(); model.materials[m].maps[MAP_DIFFUSE].texture = GetTextureDefault();
} }
model.materials[m].maps[MAP_DIFFUSE].color = (Color){ (unsigned char)(materials[m].diffuse[0]*255.0f), (unsigned char)(materials[m].diffuse[1]*255.0f), (unsigned char)(materials[m].diffuse[2]*255.0f), 255 }; //float diffuse[3]; model.materials[m].maps[MAP_DIFFUSE].color = (Color){ (unsigned char)(materials[m].diffuse[0]*255.0f), (unsigned char)(materials[m].diffuse[1]*255.0f), (unsigned char)(materials[m].diffuse[2]*255.0f), 255 }; //float diffuse[3];
model.materials[m].maps[MAP_DIFFUSE].value = 0.0f; model.materials[m].maps[MAP_DIFFUSE].value = 0.0f;
@ -3103,9 +3103,9 @@ static Model LoadOBJ(const char *fileName)
tinyobj_attrib_free(&attrib); tinyobj_attrib_free(&attrib);
tinyobj_shapes_free(meshes, meshCount); tinyobj_shapes_free(meshes, meshCount);
tinyobj_materials_free(materials, materialCount); tinyobj_materials_free(materials, materialCount);
RL_FREE(fileData); RL_FREE(fileData);
RL_FREE(vCount); RL_FREE(vCount);
RL_FREE(vtCount); RL_FREE(vtCount);
RL_FREE(vnCount); RL_FREE(vnCount);
@ -3128,7 +3128,7 @@ static Model LoadIQM(const char *fileName)
#define BONE_NAME_LENGTH 32 // BoneInfo name string length #define BONE_NAME_LENGTH 32 // BoneInfo name string length
#define MESH_NAME_LENGTH 32 // Mesh name string length #define MESH_NAME_LENGTH 32 // Mesh name string length
#define MATERIAL_NAME_LENGTH 32 // Material name string length #define MATERIAL_NAME_LENGTH 32 // Material name string length
unsigned int fileSize = 0; unsigned int fileSize = 0;
unsigned char *fileData = LoadFileData(fileName, &fileSize); unsigned char *fileData = LoadFileData(fileName, &fileSize);
unsigned char *fileDataPtr = fileData; unsigned char *fileDataPtr = fileData;
@ -3246,7 +3246,7 @@ static Model LoadIQM(const char *fileName)
TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file version not supported (%i)", fileName, iqmHeader->version); TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file version not supported (%i)", fileName, iqmHeader->version);
return model; return model;
} }
//fileDataPtr += sizeof(IQMHeader); // Move file data pointer //fileDataPtr += sizeof(IQMHeader); // Move file data pointer
// Meshes data processing // Meshes data processing
@ -3312,7 +3312,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++) 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, // 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 we need to reverse triangle indexes
// NOTE: raylib renders vertex data in counter-clockwise order (standard convention) by default // 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 + 2] = tri[i].vertex[0] - imesh[m].first_vertex;
model.meshes[m].indices[tcounter + 1] = tri[i].vertex[1] - imesh[m].first_vertex; model.meshes[m].indices[tcounter + 1] = tri[i].vertex[1] - imesh[m].first_vertex;
@ -3467,7 +3467,7 @@ static Model LoadIQM(const char *fileName)
} }
RL_FREE(fileData); RL_FREE(fileData);
RL_FREE(imesh); RL_FREE(imesh);
RL_FREE(tri); RL_FREE(tri);
RL_FREE(va); RL_FREE(va);

+ 16
- 16
src/raudio.c View File

@ -175,7 +175,7 @@ typedef struct tagBITMAPINFOHEADER {
#if !defined(TRACELOG) #if !defined(TRACELOG)
#define TRACELOG(level, ...) (void)0 #define TRACELOG(level, ...) (void)0
#endif #endif
// Allow custom memory allocators // Allow custom memory allocators
#ifndef RL_MALLOC #ifndef RL_MALLOC
#define RL_MALLOC(sz) malloc(sz) #define RL_MALLOC(sz) malloc(sz)
@ -689,7 +689,7 @@ void UntrackAudioBuffer(AudioBuffer *buffer)
Wave LoadWave(const char *fileName) Wave LoadWave(const char *fileName)
{ {
Wave wave = { 0 }; Wave wave = { 0 };
// Loading file to memory // Loading file to memory
unsigned int fileSize = 0; unsigned int fileSize = 0;
unsigned char *fileData = LoadFileData(fileName, &fileSize); unsigned char *fileData = LoadFileData(fileName, &fileSize);
@ -709,10 +709,10 @@ Wave LoadWave(const char *fileName)
Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize) Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize)
{ {
Wave wave = { 0 }; Wave wave = { 0 };
char fileExtLower[16] = { 0 }; char fileExtLower[16] = { 0 };
strcpy(fileExtLower, TextToLower(fileType)); strcpy(fileExtLower, TextToLower(fileType));
if (false) { } if (false) { }
#if defined(SUPPORT_FILEFORMAT_WAV) #if defined(SUPPORT_FILEFORMAT_WAV)
else if (TextIsEqual(fileExtLower, "wav")) wave = LoadWAV(fileData, dataSize); else if (TextIsEqual(fileExtLower, "wav")) wave = LoadWAV(fileData, dataSize);
@ -727,7 +727,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
else if (TextIsEqual(fileExtLower, "mp3")) wave = LoadMP3(fileData, dataSize); else if (TextIsEqual(fileExtLower, "mp3")) wave = LoadMP3(fileData, dataSize);
#endif #endif
else TRACELOG(LOG_WARNING, "WAVE: File format not supported"); else TRACELOG(LOG_WARNING, "WAVE: File format not supported");
return wave; return wave;
} }
@ -1116,7 +1116,7 @@ Music LoadMusicStream(const char *fileName)
{ {
music.ctxType = MUSIC_AUDIO_WAV; music.ctxType = MUSIC_AUDIO_WAV;
music.ctxData = ctxWav; music.ctxData = ctxWav;
int sampleSize = ctxWav->bitsPerSample; int sampleSize = ctxWav->bitsPerSample;
if (ctxWav->bitsPerSample == 24) sampleSize = 16; // Forcing conversion to s16 on UpdateMusicStream() if (ctxWav->bitsPerSample == 24) sampleSize = 16; // Forcing conversion to s16 on UpdateMusicStream()
@ -1228,7 +1228,7 @@ Music LoadMusicStream(const char *fileName)
} }
#endif #endif
else TRACELOG(LOG_WARNING, "STREAM: [%s] Fileformat not supported", fileName); else TRACELOG(LOG_WARNING, "STREAM: [%s] Fileformat not supported", fileName);
if (!musicLoaded) if (!musicLoaded)
{ {
if (false) { } if (false) { }
@ -1900,7 +1900,7 @@ static void InitAudioBufferPool(void)
// WARNING: An empty audioBuffer is created (data = 0) // WARNING: An empty audioBuffer is created (data = 0)
AUDIO.MultiChannel.pool[i] = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO_DEVICE_SAMPLE_RATE, 0, AUDIO_BUFFER_USAGE_STATIC); AUDIO.MultiChannel.pool[i] = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO_DEVICE_SAMPLE_RATE, 0, AUDIO_BUFFER_USAGE_STATIC);
} }
// TODO: Verification required for log // TODO: Verification required for log
TRACELOG(LOG_INFO, "AUDIO: Multichannel pool size: %i", MAX_AUDIO_BUFFER_POOL_CHANNELS); TRACELOG(LOG_INFO, "AUDIO: Multichannel pool size: %i", MAX_AUDIO_BUFFER_POOL_CHANNELS);
} }
@ -1918,9 +1918,9 @@ static Wave LoadWAV(const unsigned char *fileData, unsigned int fileSize)
{ {
Wave wave = { 0 }; Wave wave = { 0 };
drwav wav = { 0 }; drwav wav = { 0 };
bool success = drwav_init_memory(&wav, fileData, fileSize, NULL); bool success = drwav_init_memory(&wav, fileData, fileSize, NULL);
if (success) if (success)
{ {
wave.sampleCount = wav.totalPCMFrameCount*wav.channels; wave.sampleCount = wav.totalPCMFrameCount*wav.channels;
@ -1931,7 +1931,7 @@ static Wave LoadWAV(const unsigned char *fileData, unsigned int fileSize)
drwav_read_pcm_frames_s16(&wav, wav.totalPCMFrameCount, wave.data); drwav_read_pcm_frames_s16(&wav, wav.totalPCMFrameCount, wave.data);
} }
else TRACELOG(LOG_WARNING, "WAVE: Failed to load WAV data"); else TRACELOG(LOG_WARNING, "WAVE: Failed to load WAV data");
drwav_uninit(&wav); drwav_uninit(&wav);
return wave; return wave;
@ -1948,16 +1948,16 @@ static int SaveWAV(Wave wave, const char *fileName)
format.channels = wave.channels; format.channels = wave.channels;
format.sampleRate = wave.sampleRate; format.sampleRate = wave.sampleRate;
format.bitsPerSample = wave.sampleSize; format.bitsPerSample = wave.sampleSize;
unsigned char *fileData = NULL; unsigned char *fileData = NULL;
unsigned int fileDataSize = 0; unsigned int fileDataSize = 0;
drwav_init_memory_write(&wav, &fileData, &fileDataSize, &format, NULL); drwav_init_memory_write(&wav, &fileData, &fileDataSize, &format, NULL);
drwav_write_pcm_frames(&wav, wave.sampleCount/wave.channels, wave.data); drwav_write_pcm_frames(&wav, wave.sampleCount/wave.channels, wave.data);
drwav_uninit(&wav); drwav_uninit(&wav);
SaveFileData(fileName, fileData, fileDataSize); SaveFileData(fileName, fileData, fileDataSize);
drwav_free(fileData, NULL); drwav_free(fileData, NULL);
return true; return true;
} }
#endif #endif
@ -2016,7 +2016,7 @@ static Wave LoadFLAC(const unsigned char *fileData, unsigned int fileSize)
TRACELOG(LOG_INFO, "WAVE: FLAC data loaded successfully (%i Hz, %i bit, %s)", wave.sampleRate, wave.sampleSize, (wave.channels == 1)? "Mono" : "Stereo"); TRACELOG(LOG_INFO, "WAVE: FLAC data loaded successfully (%i Hz, %i bit, %s)", wave.sampleRate, wave.sampleSize, (wave.channels == 1)? "Mono" : "Stereo");
} }
else TRACELOG(LOG_WARNING, "WAVE: Failed to load FLAC data"); else TRACELOG(LOG_WARNING, "WAVE: Failed to load FLAC data");
return wave; return wave;
} }
#endif #endif
@ -2028,7 +2028,7 @@ static Wave LoadMP3(const unsigned char *fileData, unsigned int fileSize)
{ {
Wave wave = { 0 }; Wave wave = { 0 };
drmp3_config config = { 0 }; drmp3_config config = { 0 };
// Decode the entire MP3 file in one go // Decode the entire MP3 file in one go
unsigned long long int totalFrameCount = 0; unsigned long long int totalFrameCount = 0;
wave.data = drmp3_open_memory_and_read_f32(fileData, fileSize, &config, &totalFrameCount); wave.data = drmp3_open_memory_and_read_f32(fileData, fileSize, &config, &totalFrameCount);

+ 1
- 1
src/raylib.h View File

@ -1184,7 +1184,7 @@ RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Col
RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw circle within an image (Vector version) RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw circle within an image (Vector version)
RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image
RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version) RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version)
RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image
RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image
RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source) RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source)
RLAPI void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination) RLAPI void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination)

+ 16
- 16
src/raymath.h View File

@ -164,7 +164,7 @@ RMDEF float Normalize(float value, float start, float end)
} }
// Remap input value within input range to output range // Remap input value within input range to output range
RMDEF float Remap(float value, float inputStart, float inputEnd, float outputStart, float outputEnd) RMDEF float Remap(float value, float inputStart, float inputEnd, float outputStart, float outputEnd)
{ {
return (value - inputStart) / (inputEnd - inputStart) * (outputEnd - outputStart) + outputStart; return (value - inputStart) / (inputEnd - inputStart) * (outputEnd - outputStart) + outputStart;
} }
@ -325,14 +325,14 @@ RMDEF Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDistance)
float dx = target.x - v.x; float dx = target.x - v.x;
float dy = target.y - v.y; float dy = target.y - v.y;
float value = (dx*dx) + (dy*dy); float value = (dx*dx) + (dy*dy);
if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) result = target; if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) result = target;
float dist = sqrtf(value); float dist = sqrtf(value);
result.x = v.x + dx/dist*maxDistance; result.x = v.x + dx/dist*maxDistance;
result.y = v.y + dy/dist*maxDistance; result.y = v.y + dy/dist*maxDistance;
return result; return result;
} }
@ -970,14 +970,14 @@ RMDEF Matrix MatrixRotateXYZ(Vector3 ang)
} }
// Returns zyx-rotation matrix (angles in radians) // Returns zyx-rotation matrix (angles in radians)
// TODO: This solution is suboptimal, it should be possible to create this matrix in one go // TODO: This solution is suboptimal, it should be possible to create this matrix in one go
// instead of using a 3 matrix multiplication // instead of using a 3 matrix multiplication
RMDEF Matrix MatrixRotateZYX(Vector3 ang) RMDEF Matrix MatrixRotateZYX(Vector3 ang)
{ {
Matrix result = MatrixRotateZ(ang.z); Matrix result = MatrixRotateZ(ang.z);
result = MatrixMultiply(result, MatrixRotateY(ang.y)); result = MatrixMultiply(result, MatrixRotateY(ang.y));
result = MatrixMultiply(result, MatrixRotateX(ang.x)); result = MatrixMultiply(result, MatrixRotateX(ang.x));
return result; return result;
} }
@ -1329,16 +1329,16 @@ RMDEF Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to)
RMDEF Quaternion QuaternionFromMatrix(Matrix mat) RMDEF Quaternion QuaternionFromMatrix(Matrix mat)
{ {
Quaternion result = { 0 }; Quaternion result = { 0 };
if ((mat.m0 > mat.m5) && (mat.m0 > mat.m10)) if ((mat.m0 > mat.m5) && (mat.m0 > mat.m10))
{ {
float s = sqrtf(1.0f + mat.m0 - mat.m5 - mat.m10)*2; float s = sqrtf(1.0f + mat.m0 - mat.m5 - mat.m10)*2;
result.x = 0.25f*s; result.x = 0.25f*s;
result.y = (mat.m4 + mat.m1)/s; result.y = (mat.m4 + mat.m1)/s;
result.z = (mat.m2 + mat.m8)/s; result.z = (mat.m2 + mat.m8)/s;
result.w = (mat.m9 - mat.m6)/s; result.w = (mat.m9 - mat.m6)/s;
} }
else if (mat.m5 > mat.m10) else if (mat.m5 > mat.m10)
{ {
float s = sqrtf(1.0f + mat.m5 - mat.m0 - mat.m10)*2; float s = sqrtf(1.0f + mat.m5 - mat.m0 - mat.m10)*2;
@ -1346,7 +1346,7 @@ RMDEF Quaternion QuaternionFromMatrix(Matrix mat)
result.y = 0.25f*s; result.y = 0.25f*s;
result.z = (mat.m9 + mat.m6)/s; result.z = (mat.m9 + mat.m6)/s;
result.w = (mat.m2 - mat.m8)/s; result.w = (mat.m2 - mat.m8)/s;
} }
else else
{ {
float s = sqrtf(1.0f + mat.m10 - mat.m0 - mat.m5)*2; float s = sqrtf(1.0f + mat.m10 - mat.m0 - mat.m5)*2;
@ -1355,7 +1355,7 @@ RMDEF Quaternion QuaternionFromMatrix(Matrix mat)
result.z = 0.25f*s; result.z = 0.25f*s;
result.w = (mat.m4 - mat.m1)/s; result.w = (mat.m4 - mat.m1)/s;
} }
return result; return result;
} }
@ -1363,20 +1363,20 @@ RMDEF Quaternion QuaternionFromMatrix(Matrix mat)
RMDEF Matrix QuaternionToMatrix(Quaternion q) RMDEF Matrix QuaternionToMatrix(Quaternion q)
{ {
Matrix result = MatrixIdentity(); Matrix result = MatrixIdentity();
float a2 = 2*(q.x*q.x), b2=2*(q.y*q.y), c2=2*(q.z*q.z); //, d2=2*(q.w*q.w); float a2 = 2*(q.x*q.x), b2=2*(q.y*q.y), c2=2*(q.z*q.z); //, d2=2*(q.w*q.w);
float ab = 2*(q.x*q.y), ac=2*(q.x*q.z), bc=2*(q.y*q.z); float ab = 2*(q.x*q.y), ac=2*(q.x*q.z), bc=2*(q.y*q.z);
float ad = 2*(q.x*q.w), bd=2*(q.y*q.w), cd=2*(q.z*q.w); float ad = 2*(q.x*q.w), bd=2*(q.y*q.w), cd=2*(q.z*q.w);
result.m0 = 1 - b2 - c2; result.m0 = 1 - b2 - c2;
result.m1 = ab - cd; result.m1 = ab - cd;
result.m2 = ac + bd; result.m2 = ac + bd;
result.m4 = ab + cd; result.m4 = ab + cd;
result.m5 = 1 - a2 - c2; result.m5 = 1 - a2 - c2;
result.m6 = bc - ad; result.m6 = bc - ad;
result.m8 = ac - bd; result.m8 = ac - bd;
result.m9 = bc + ad; result.m9 = bc + ad;
result.m10 = 1 - a2 - b2; result.m10 = 1 - a2 - b2;

+ 56
- 56
src/rlgl.h View File

@ -138,7 +138,7 @@
#define DEFAULT_BATCH_BUFFER_ELEMENTS 8192 #define DEFAULT_BATCH_BUFFER_ELEMENTS 8192
#elif defined(GRAPHICS_API_OPENGL_ES2) #elif defined(GRAPHICS_API_OPENGL_ES2)
// We reduce memory sizes for embedded systems (RPI and HTML5) // We reduce memory sizes for embedded systems (RPI and HTML5)
// NOTE: On HTML5 (emscripten) this is allocated on heap, // NOTE: On HTML5 (emscripten) this is allocated on heap,
// by default it's only 16MB!...just take care... // by default it's only 16MB!...just take care...
#define DEFAULT_BATCH_BUFFER_ELEMENTS 2048 #define DEFAULT_BATCH_BUFFER_ELEMENTS 2048
#endif #endif
@ -790,7 +790,7 @@ RLAPI int GetPixelDataSize(int width, int height, int format);// Get pixel data
// Dynamic vertex buffers (position + texcoords + colors + indices arrays) // Dynamic vertex buffers (position + texcoords + colors + indices arrays)
typedef struct VertexBuffer { typedef struct VertexBuffer {
int elementsCount; // Number of elements in the buffer (QUADS) int elementsCount; // Number of elements in the buffer (QUADS)
int vCounter; // Vertex position counter to process (and draw) from full buffer int vCounter; // Vertex position counter to process (and draw) from full buffer
int tcCounter; // Vertex texcoord counter to process (and draw) from full buffer int tcCounter; // Vertex texcoord counter to process (and draw) from full buffer
int cCounter; // Vertex color counter to process (and draw) from full buffer int cCounter; // Vertex color counter to process (and draw) from full buffer
@ -808,7 +808,7 @@ typedef struct VertexBuffer {
} VertexBuffer; } VertexBuffer;
// Draw call type // Draw call type
// NOTE: Only texture changes register a new draw, other state-change-related elements are not // 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 just forces a batch draw call if any
// of those state-change happens (this is done in core module) // of those state-change happens (this is done in core module)
typedef struct DrawCall { typedef struct DrawCall {
@ -868,7 +868,7 @@ typedef struct rlglData {
unsigned int defaultFShaderId; // Default fragment shader Id (used by default shader program) unsigned int defaultFShaderId; // Default fragment shader Id (used by default shader program)
Shader defaultShader; // Basic shader, support vertex color and diffuse texture Shader defaultShader; // Basic shader, support vertex color and diffuse texture
Shader currentShader; // Shader to be used on rendering (by default, defaultShader) Shader currentShader; // Shader to be used on rendering (by default, defaultShader)
int currentBlendMode; // Blending mode active int currentBlendMode; // Blending mode active
int glBlendSrcFactor; // Blending source factor int glBlendSrcFactor; // Blending source factor
int glBlendDstFactor; // Blending destination factor int glBlendDstFactor; // Blending destination factor
@ -1477,7 +1477,7 @@ void rlDisableWireMode(void)
void rlUnloadFramebuffer(unsigned int id) void rlUnloadFramebuffer(unsigned int id)
{ {
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT) #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
// Query depth attachment to automatically delete texture/renderbuffer // Query depth attachment to automatically delete texture/renderbuffer
int depthType = 0, depthId = 0; int depthType = 0, depthId = 0;
glBindFramebuffer(GL_FRAMEBUFFER, id); // Bind framebuffer to query depth texture type glBindFramebuffer(GL_FRAMEBUFFER, id); // Bind framebuffer to query depth texture type
@ -1488,7 +1488,7 @@ void rlUnloadFramebuffer(unsigned int id)
if (depthType == GL_RENDERBUFFER) glDeleteRenderbuffers(1, &depthIdU); if (depthType == GL_RENDERBUFFER) glDeleteRenderbuffers(1, &depthIdU);
else if (depthType == GL_RENDERBUFFER) glDeleteTextures(1, &depthIdU); else if (depthType == GL_RENDERBUFFER) glDeleteTextures(1, &depthIdU);
// NOTE: If a texture object is deleted while its image is attached to the *currently bound* framebuffer, // NOTE: If a texture object is deleted while its image is attached to the *currently bound* framebuffer,
// the texture image is automatically detached from the currently bound framebuffer. // the texture image is automatically detached from the currently bound framebuffer.
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -1755,7 +1755,7 @@ void rlglInit(int width, int height)
glCullFace(GL_BACK); // Cull the back face (default) glCullFace(GL_BACK); // Cull the back face (default)
glFrontFace(GL_CCW); // Front face are defined counter clockwise (default) glFrontFace(GL_CCW); // Front face are defined counter clockwise (default)
glEnable(GL_CULL_FACE); // Enable backface culling glEnable(GL_CULL_FACE); // Enable backface culling
// Init state: Cubemap seamless // Init state: Cubemap seamless
#if defined(GRAPHICS_API_OPENGL_33) #if defined(GRAPHICS_API_OPENGL_33)
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // Seamless cubemaps (not supported on OpenGL ES 2.0) glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // Seamless cubemaps (not supported on OpenGL ES 2.0)
@ -1778,7 +1778,7 @@ void rlglInit(int width, int height)
TRACELOG(LOG_INFO, "RLGL: Default state initialized successfully"); TRACELOG(LOG_INFO, "RLGL: Default state initialized successfully");
#endif #endif
// Init state: Color/Depth buffers clear // Init state: Color/Depth buffers clear
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black) glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black)
glClearDepth(1.0f); // Set clear depth value (default) glClearDepth(1.0f); // Set clear depth value (default)
@ -2098,7 +2098,7 @@ unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
TRACELOG(LOG_INFO, "TEXTURE: Depth texture loaded successfully"); TRACELOG(LOG_INFO, "TEXTURE: Depth texture loaded successfully");
} }
else else
@ -2110,7 +2110,7 @@ unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer)
glRenderbufferStorage(GL_RENDERBUFFER, glInternalFormat, width, height); glRenderbufferStorage(GL_RENDERBUFFER, glInternalFormat, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0);
TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Depth renderbuffer loaded successfully (%i bits)", id, (RLGL.ExtSupported.maxDepthBits >= 24)? RLGL.ExtSupported.maxDepthBits : 16); TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Depth renderbuffer loaded successfully (%i bits)", id, (RLGL.ExtSupported.maxDepthBits >= 24)? RLGL.ExtSupported.maxDepthBits : 16);
} }
#endif #endif
@ -2141,7 +2141,7 @@ unsigned int rlLoadTextureCubemap(void *data, int size, int format)
{ {
if (data == NULL) if (data == NULL)
{ {
if (format < COMPRESSED_DXT1_RGB) if (format < COMPRESSED_DXT1_RGB)
{ {
if (format == UNCOMPRESSED_R32G32B32) if (format == UNCOMPRESSED_R32G32B32)
{ {
@ -2296,12 +2296,12 @@ void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType,
{ {
case RL_ATTACHMENT_COLOR_CHANNEL0: case RL_ATTACHMENT_COLOR_CHANNEL0:
case RL_ATTACHMENT_COLOR_CHANNEL1: case RL_ATTACHMENT_COLOR_CHANNEL1:
case RL_ATTACHMENT_COLOR_CHANNEL2: case RL_ATTACHMENT_COLOR_CHANNEL2:
case RL_ATTACHMENT_COLOR_CHANNEL3: case RL_ATTACHMENT_COLOR_CHANNEL3:
case RL_ATTACHMENT_COLOR_CHANNEL4: case RL_ATTACHMENT_COLOR_CHANNEL4:
case RL_ATTACHMENT_COLOR_CHANNEL5: case RL_ATTACHMENT_COLOR_CHANNEL5:
case RL_ATTACHMENT_COLOR_CHANNEL6: case RL_ATTACHMENT_COLOR_CHANNEL6:
case RL_ATTACHMENT_COLOR_CHANNEL7: case RL_ATTACHMENT_COLOR_CHANNEL7:
{ {
if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_2D, texId, 0); if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_TEXTURE_2D, texId, 0);
else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_RENDERBUFFER, texId); else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachType, GL_RENDERBUFFER, texId);
@ -2312,13 +2312,13 @@ void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType,
{ {
if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texId, 0); if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texId, 0);
else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, texId); else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, texId);
} break; } break;
case RL_ATTACHMENT_STENCIL: case RL_ATTACHMENT_STENCIL:
{ {
if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texId, 0); if (texType == RL_ATTACHMENT_TEXTURE2D) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texId, 0);
else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, texId); else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, texId);
} break; } break;
default: break; default: break;
} }
@ -2636,7 +2636,7 @@ void rlUpdateMeshAt(Mesh mesh, int buffer, int count, int index)
if (index == 0 && count >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, count*4*sizeof(float), mesh.tangents, GL_DYNAMIC_DRAW); if (index == 0 && count >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, count*4*sizeof(float), mesh.tangents, GL_DYNAMIC_DRAW);
else if (index + count >= mesh.vertexCount) break; else if (index + count >= mesh.vertexCount) break;
else glBufferSubData(GL_ARRAY_BUFFER, index*4*sizeof(float), count*4*sizeof(float), mesh.tangents); else glBufferSubData(GL_ARRAY_BUFFER, index*4*sizeof(float), count*4*sizeof(float), mesh.tangents);
} break; } break;
case 5: // Update texcoords2 (vertex second texture coordinates) case 5: // Update texcoords2 (vertex second texture coordinates)
{ {
@ -2644,18 +2644,18 @@ void rlUpdateMeshAt(Mesh mesh, int buffer, int count, int index)
if (index == 0 && count >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, count*2*sizeof(float), mesh.texcoords2, GL_DYNAMIC_DRAW); if (index == 0 && count >= mesh.vertexCount) glBufferData(GL_ARRAY_BUFFER, count*2*sizeof(float), mesh.texcoords2, GL_DYNAMIC_DRAW);
else if (index + count >= mesh.vertexCount) break; else if (index + count >= mesh.vertexCount) break;
else glBufferSubData(GL_ARRAY_BUFFER, index*2*sizeof(float), count*2*sizeof(float), mesh.texcoords2); else glBufferSubData(GL_ARRAY_BUFFER, index*2*sizeof(float), count*2*sizeof(float), mesh.texcoords2);
} break; } break;
case 6: // Update indices (triangle index buffer) case 6: // Update indices (triangle index buffer)
{ {
// the * 3 is because each triangle has 3 indices // the * 3 is because each triangle has 3 indices
unsigned short *indices = mesh.indices; unsigned short *indices = mesh.indices;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vboId[6]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vboId[6]);
if (index == 0 && count >= mesh.triangleCount) glBufferData(GL_ELEMENT_ARRAY_BUFFER, count*3*sizeof(*indices), indices, GL_DYNAMIC_DRAW); if (index == 0 && count >= mesh.triangleCount) glBufferData(GL_ELEMENT_ARRAY_BUFFER, count*3*sizeof(*indices), indices, GL_DYNAMIC_DRAW);
else if (index + count >= mesh.triangleCount) break; else if (index + count >= mesh.triangleCount) break;
else glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, index*3*sizeof(*indices), count*3*sizeof(*indices), indices); else glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, index*3*sizeof(*indices), count*3*sizeof(*indices), indices);
} break; } break;
default: break; default: break;
} }
@ -2906,7 +2906,7 @@ void rlDrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int c
// At this point the modelview matrix just contains the view matrix (camera) // At this point the modelview matrix just contains the view matrix (camera)
// For instanced shaders "mvp" is not premultiplied by any instance transform, only RLGL.State.transform // For instanced shaders "mvp" is not premultiplied by any instance transform, only RLGL.State.transform
glUniformMatrix4fv(material.shader.locs[LOC_MATRIX_MVP], 1, false, glUniformMatrix4fv(material.shader.locs[LOC_MATRIX_MVP], 1, false,
MatrixToFloat(MatrixMultiply(MatrixMultiply(RLGL.State.transform, RLGL.State.modelview), RLGL.State.projection))); MatrixToFloat(MatrixMultiply(MatrixMultiply(RLGL.State.transform, RLGL.State.modelview), RLGL.State.projection)));
float16* instances = RL_MALLOC(count*sizeof(float16)); float16* instances = RL_MALLOC(count*sizeof(float16));
@ -3189,13 +3189,13 @@ Shader LoadShaderCode(const char *vsCode, const char *fsCode)
{ {
shader.id = LoadShaderProgram(vertexShaderId, fragmentShaderId); shader.id = LoadShaderProgram(vertexShaderId, fragmentShaderId);
if (vertexShaderId != RLGL.State.defaultVShaderId) if (vertexShaderId != RLGL.State.defaultVShaderId)
{ {
// Detach shader before deletion to make sure memory is freed // Detach shader before deletion to make sure memory is freed
glDetachShader(shader.id, vertexShaderId); glDetachShader(shader.id, vertexShaderId);
glDeleteShader(vertexShaderId); glDeleteShader(vertexShaderId);
} }
if (fragmentShaderId != RLGL.State.defaultFShaderId) if (fragmentShaderId != RLGL.State.defaultFShaderId)
{ {
// Detach shader before deletion to make sure memory is freed // Detach shader before deletion to make sure memory is freed
glDetachShader(shader.id, fragmentShaderId); glDetachShader(shader.id, fragmentShaderId);
@ -3245,7 +3245,7 @@ void UnloadShader(Shader shader)
{ {
glDeleteProgram(shader.id); glDeleteProgram(shader.id);
RL_FREE(shader.locs); RL_FREE(shader.locs);
TRACELOG(LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", shader.id); TRACELOG(LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", shader.id);
} }
#endif #endif
@ -3345,13 +3345,13 @@ void SetShaderValueTexture(Shader shader, int uniformLoc, Texture2D texture)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glUseProgram(shader.id); glUseProgram(shader.id);
// Check if texture is already active // Check if texture is already active
for (int i = 0; i < MAX_BATCH_ACTIVE_TEXTURES; i++) if (RLGL.State.activeTextureId[i] == texture.id) return; for (int i = 0; i < MAX_BATCH_ACTIVE_TEXTURES; i++) if (RLGL.State.activeTextureId[i] == texture.id) return;
// Register a new active texture for the internal batch system // Register a new active texture for the internal batch system
// NOTE: Default texture is always activated as GL_TEXTURE0 // NOTE: Default texture is always activated as GL_TEXTURE0
for (int i = 0; i < MAX_BATCH_ACTIVE_TEXTURES; i++) for (int i = 0; i < MAX_BATCH_ACTIVE_TEXTURES; i++)
{ {
if (RLGL.State.activeTextureId[i] == 0) if (RLGL.State.activeTextureId[i] == 0)
{ {
@ -3426,11 +3426,11 @@ TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, in
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
unsigned int rbo = rlLoadTextureDepth(size, size, true); unsigned int rbo = rlLoadTextureDepth(size, size, true);
cubemap.id = rlLoadTextureCubemap(NULL, size, format); cubemap.id = rlLoadTextureCubemap(NULL, size, format);
unsigned int fbo = rlLoadFramebuffer(size, size); unsigned int fbo = rlLoadFramebuffer(size, size);
rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER); rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER);
rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X); rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X);
// Check if framebuffer is complete with attachments (valid) // Check if framebuffer is complete with attachments (valid)
if (rlFramebufferComplete(fbo)) TRACELOG(LOG_INFO, "FBO: [ID %i] Framebuffer object created successfully", fbo); if (rlFramebufferComplete(fbo)) TRACELOG(LOG_INFO, "FBO: [ID %i] Framebuffer object created successfully", fbo);
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
@ -3442,7 +3442,7 @@ TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, in
// Define projection matrix and send it to shader // Define projection matrix and send it to shader
Matrix fboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); Matrix fboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_PROJECTION], fboProjection); SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_PROJECTION], fboProjection);
// Define view matrix for every side of the cubemap // Define view matrix for every side of the cubemap
Matrix fboViews[6] = { Matrix fboViews[6] = {
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }), MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
@ -3472,7 +3472,7 @@ TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, in
#endif #endif
rlClearScreenBuffers(); rlClearScreenBuffers();
GenDrawCube(); GenDrawCube();
#if defined(GENTEXTURECUBEMAP_USE_BATCH_SYSTEM) #if defined(GENTEXTURECUBEMAP_USE_BATCH_SYSTEM)
// Using internal batch system instead of raw OpenGL cube creating+drawing // Using internal batch system instead of raw OpenGL cube creating+drawing
// NOTE: DrawCubeV() is actually provided by models.c! -> GenTextureCubemap() should be moved to user code! // NOTE: DrawCubeV() is actually provided by models.c! -> GenTextureCubemap() should be moved to user code!
@ -3514,7 +3514,7 @@ TextureCubemap GenTextureIrradiance(Shader shader, TextureCubemap cubemap, int s
//------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------
unsigned int rbo = rlLoadTextureDepth(size, size, true); unsigned int rbo = rlLoadTextureDepth(size, size, true);
irradiance.id = rlLoadTextureCubemap(NULL, size, UNCOMPRESSED_R32G32B32); irradiance.id = rlLoadTextureCubemap(NULL, size, UNCOMPRESSED_R32G32B32);
unsigned int fbo = rlLoadFramebuffer(size, size); unsigned int fbo = rlLoadFramebuffer(size, size);
rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER); rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER);
rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X); rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X);
@ -3527,7 +3527,7 @@ TextureCubemap GenTextureIrradiance(Shader shader, TextureCubemap cubemap, int s
// Define projection matrix and send it to shader // Define projection matrix and send it to shader
Matrix fboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); Matrix fboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_PROJECTION], fboProjection); SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_PROJECTION], fboProjection);
// Define view matrix for every side of the cubemap // Define view matrix for every side of the cubemap
Matrix fboViews[6] = { Matrix fboViews[6] = {
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }), MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
@ -3537,7 +3537,7 @@ TextureCubemap GenTextureIrradiance(Shader shader, TextureCubemap cubemap, int s
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }), MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, 1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }) MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, 0.0f, -1.0f }, (Vector3){ 0.0f, -1.0f, 0.0f })
}; };
rlEnableShader(shader.id); rlEnableShader(shader.id);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id); glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap.id);
@ -3588,7 +3588,7 @@ TextureCubemap GenTexturePrefilter(Shader shader, TextureCubemap cubemap, int si
unsigned int rbo = rlLoadTextureDepth(size, size, true); unsigned int rbo = rlLoadTextureDepth(size, size, true);
prefilter.id = rlLoadTextureCubemap(NULL, size, UNCOMPRESSED_R32G32B32); prefilter.id = rlLoadTextureCubemap(NULL, size, UNCOMPRESSED_R32G32B32);
rlTextureParameters(prefilter.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_LINEAR); rlTextureParameters(prefilter.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_LINEAR);
unsigned int fbo = rlLoadFramebuffer(size, size); unsigned int fbo = rlLoadFramebuffer(size, size);
rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER); rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER);
rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X); rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X);
@ -3605,7 +3605,7 @@ TextureCubemap GenTexturePrefilter(Shader shader, TextureCubemap cubemap, int si
// Define projection matrix and send it to shader // Define projection matrix and send it to shader
Matrix fboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR); Matrix fboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_PROJECTION], fboProjection); SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_PROJECTION], fboProjection);
// Define view matrix for every side of the cubemap // Define view matrix for every side of the cubemap
Matrix fboViews[6] = { Matrix fboViews[6] = {
MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }), MatrixLookAt((Vector3){ 0.0f, 0.0f, 0.0f }, (Vector3){ 1.0f, 0.0f, 0.0f }, (Vector3){ 0.0f, -1.0f, 0.0f }),
@ -3632,12 +3632,12 @@ TextureCubemap GenTexturePrefilter(Shader shader, TextureCubemap cubemap, int si
// Resize framebuffer according to mip-level size. // Resize framebuffer according to mip-level size.
unsigned int mipWidth = size*(int)powf(0.5f, (float)mip); unsigned int mipWidth = size*(int)powf(0.5f, (float)mip);
unsigned int mipHeight = size*(int)powf(0.5f, (float)mip); unsigned int mipHeight = size*(int)powf(0.5f, (float)mip);
rlViewport(0, 0, mipWidth, mipHeight); rlViewport(0, 0, mipWidth, mipHeight);
glBindRenderbuffer(GL_RENDERBUFFER, rbo); glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mipWidth, mipHeight); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mipWidth, mipHeight);
float roughness = (float)mip/(float)(MAX_MIPMAP_LEVELS - 1); float roughness = (float)mip/(float)(MAX_MIPMAP_LEVELS - 1);
glUniform1f(roughnessLoc, roughness); glUniform1f(roughnessLoc, roughness);
@ -3697,7 +3697,7 @@ Texture2D GenTextureBRDF(Shader shader, int size)
rlEnableShader(shader.id); rlEnableShader(shader.id);
rlViewport(0, 0, size, size); rlViewport(0, 0, size, size);
rlEnableFramebuffer(fbo); rlEnableFramebuffer(fbo);
rlClearScreenBuffers(); rlClearScreenBuffers();
GenDrawQuad(); GenDrawQuad();
@ -3733,15 +3733,15 @@ void BeginBlendMode(int mode)
switch (mode) switch (mode)
{ {
case BLEND_ALPHA: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break; case BLEND_ALPHA: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break;
case BLEND_ADDITIVE: glBlendFunc(GL_SRC_ALPHA, GL_ONE); glBlendEquation(GL_FUNC_ADD); break; case BLEND_ADDITIVE: glBlendFunc(GL_SRC_ALPHA, GL_ONE); glBlendEquation(GL_FUNC_ADD); break;
case BLEND_MULTIPLIED: glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break; case BLEND_MULTIPLIED: glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); break;
case BLEND_ADD_COLORS: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_ADD); break; case BLEND_ADD_COLORS: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_ADD); break;
case BLEND_SUBTRACT_COLORS: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_SUBTRACT); break; case BLEND_SUBTRACT_COLORS: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_SUBTRACT); break;
case BLEND_CUSTOM: glBlendFunc(RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor); glBlendEquation(RLGL.State.glBlendEquation); break; case BLEND_CUSTOM: glBlendFunc(RLGL.State.glBlendSrcFactor, RLGL.State.glBlendDstFactor); glBlendEquation(RLGL.State.glBlendEquation); break;
default: break; default: break;
} }
RLGL.State.currentBlendMode = mode; RLGL.State.currentBlendMode = mode;
} }
#endif #endif
@ -3788,7 +3788,7 @@ void UpdateVrTracking(Camera *camera)
void CloseVrSimulator(void) void CloseVrSimulator(void)
{ {
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if (RLGL.Vr.simulatorReady) if (RLGL.Vr.simulatorReady)
{ {
rlUnloadTexture(RLGL.Vr.stereoTexId); // Unload color texture rlUnloadTexture(RLGL.Vr.stereoTexId); // Unload color texture
rlUnloadFramebuffer(RLGL.Vr.stereoFboId); // Unload stereo framebuffer and depth texture/renderbuffer rlUnloadFramebuffer(RLGL.Vr.stereoFboId); // Unload stereo framebuffer and depth texture/renderbuffer
@ -4245,15 +4245,15 @@ static void UnloadShaderDefault(void)
static RenderBatch LoadRenderBatch(int numBuffers, int bufferElements) static RenderBatch LoadRenderBatch(int numBuffers, int bufferElements)
{ {
RenderBatch batch = { 0 }; RenderBatch batch = { 0 };
// Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes) // Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes)
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
batch.vertexBuffer = (VertexBuffer *)RL_MALLOC(sizeof(VertexBuffer)*numBuffers); batch.vertexBuffer = (VertexBuffer *)RL_MALLOC(sizeof(VertexBuffer)*numBuffers);
for (int i = 0; i < numBuffers; i++) for (int i = 0; i < numBuffers; i++)
{ {
batch.vertexBuffer[i].elementsCount = bufferElements; batch.vertexBuffer[i].elementsCount = bufferElements;
batch.vertexBuffer[i].vertices = (float *)RL_MALLOC(bufferElements*3*4*sizeof(float)); // 3 float by vertex, 4 vertex by quad batch.vertexBuffer[i].vertices = (float *)RL_MALLOC(bufferElements*3*4*sizeof(float)); // 3 float by vertex, 4 vertex by quad
batch.vertexBuffer[i].texcoords = (float *)RL_MALLOC(bufferElements*2*4*sizeof(float)); // 2 float by texcoord, 4 texcoord by quad batch.vertexBuffer[i].texcoords = (float *)RL_MALLOC(bufferElements*2*4*sizeof(float)); // 2 float by texcoord, 4 texcoord by quad
batch.vertexBuffer[i].colors = (unsigned char *)RL_MALLOC(bufferElements*4*4*sizeof(unsigned char)); // 4 float by color, 4 colors by quad batch.vertexBuffer[i].colors = (unsigned char *)RL_MALLOC(bufferElements*4*4*sizeof(unsigned char)); // 4 float by color, 4 colors by quad
@ -4338,7 +4338,7 @@ static RenderBatch LoadRenderBatch(int numBuffers, int bufferElements)
// Unbind the current VAO // Unbind the current VAO
if (RLGL.ExtSupported.vao) glBindVertexArray(0); if (RLGL.ExtSupported.vao) glBindVertexArray(0);
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
// Init draw calls tracking system // Init draw calls tracking system
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
batch.draws = (DrawCall *)RL_MALLOC(DEFAULT_BATCH_DRAWCALLS*sizeof(DrawCall)); batch.draws = (DrawCall *)RL_MALLOC(DEFAULT_BATCH_DRAWCALLS*sizeof(DrawCall));
@ -4359,7 +4359,7 @@ static RenderBatch LoadRenderBatch(int numBuffers, int bufferElements)
batch.drawsCounter = 1; // Reset draws counter batch.drawsCounter = 1; // Reset draws counter
batch.currentDepth = -1.0f; // Reset depth value batch.currentDepth = -1.0f; // Reset depth value
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
return batch; return batch;
} }
@ -4410,7 +4410,7 @@ static void DrawRenderBatch(RenderBatch *batch)
if (RLGL.ExtSupported.vao) glBindVertexArray(0); if (RLGL.ExtSupported.vao) glBindVertexArray(0);
} }
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
// Draw batch vertex buffers (considering VR stereo if required) // Draw batch vertex buffers (considering VR stereo if required)
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
Matrix matProjection = RLGL.State.projection; Matrix matProjection = RLGL.State.projection;
@ -4460,12 +4460,12 @@ static void DrawRenderBatch(RenderBatch *batch)
// Setup some default shader values // Setup some default shader values
glUniform4f(RLGL.State.currentShader.locs[LOC_COLOR_DIFFUSE], 1.0f, 1.0f, 1.0f, 1.0f); glUniform4f(RLGL.State.currentShader.locs[LOC_COLOR_DIFFUSE], 1.0f, 1.0f, 1.0f, 1.0f);
glUniform1i(RLGL.State.currentShader.locs[LOC_MAP_DIFFUSE], 0); // Active default sampler2D: texture0 glUniform1i(RLGL.State.currentShader.locs[LOC_MAP_DIFFUSE], 0); // Active default sampler2D: texture0
// Activate additional sampler textures // Activate additional sampler textures
// Those additional textures will be common for all draw calls of the batch // Those additional textures will be common for all draw calls of the batch
for (int i = 0; i < MAX_BATCH_ACTIVE_TEXTURES; i++) for (int i = 0; i < MAX_BATCH_ACTIVE_TEXTURES; i++)
{ {
if (RLGL.State.activeTextureId[i] > 0) if (RLGL.State.activeTextureId[i] > 0)
{ {
glActiveTexture(GL_TEXTURE0 + 1 + i); glActiveTexture(GL_TEXTURE0 + 1 + i);
glBindTexture(GL_TEXTURE_2D, RLGL.State.activeTextureId[i]); glBindTexture(GL_TEXTURE_2D, RLGL.State.activeTextureId[i]);
@ -4511,7 +4511,7 @@ static void DrawRenderBatch(RenderBatch *batch)
glUseProgram(0); // Unbind shader program glUseProgram(0); // Unbind shader program
} }
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
// Reset batch buffers // Reset batch buffers
//------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------
// Reset vertex counters for next frame // Reset vertex counters for next frame
@ -4533,7 +4533,7 @@ static void DrawRenderBatch(RenderBatch *batch)
batch->draws[i].vertexCount = 0; batch->draws[i].vertexCount = 0;
batch->draws[i].textureId = RLGL.State.defaultTextureId; batch->draws[i].textureId = RLGL.State.defaultTextureId;
} }
// Reset active texture units for next batch // Reset active texture units for next batch
for (int i = 0; i < MAX_BATCH_ACTIVE_TEXTURES; i++) RLGL.State.activeTextureId[i] = 0; for (int i = 0; i < MAX_BATCH_ACTIVE_TEXTURES; i++) RLGL.State.activeTextureId[i] = 0;
@ -4684,7 +4684,7 @@ static void GenDrawCube(void)
// Gen VAO to contain VBO // Gen VAO to contain VBO
glGenVertexArrays(1, &cubeVAO); glGenVertexArrays(1, &cubeVAO);
glBindVertexArray(cubeVAO); glBindVertexArray(cubeVAO);
// Gen and fill vertex buffer (VBO) // Gen and fill vertex buffer (VBO)
glGenBuffers(1, &cubeVBO); glGenBuffers(1, &cubeVBO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO); glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);

+ 4
- 2
src/shapes.c View File

@ -619,7 +619,7 @@ void DrawRectangleRec(Rectangle rec, Color color)
void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color) void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color)
{ {
if (rlCheckBufferLimit(4)) rlglDraw(); if (rlCheckBufferLimit(4)) rlglDraw();
rlEnableTexture(GetShapesTexture().id); rlEnableTexture(GetShapesTexture().id);
rlPushMatrix(); rlPushMatrix();
@ -1178,13 +1178,15 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int
angle += stepLength; angle += stepLength;
} }
} }
// And now the remaining 4 lines // And now the remaining 4 lines
for(int i = 0; i < 8; i += 2) for (int i = 0; i < 8; i += 2)
{ {
rlColor4ub(color.r, color.g, color.b, color.a); rlColor4ub(color.r, color.g, color.b, color.a);
rlVertex2f(point[i].x, point[i].y); rlVertex2f(point[i].x, point[i].y);
rlVertex2f(point[i + 1].x, point[i + 1].y); rlVertex2f(point[i + 1].x, point[i + 1].y);
} }
rlEnd(); rlEnd();
} }
} }

+ 13
- 13
src/text.c View File

@ -193,7 +193,7 @@ extern void LoadFontDefault(void)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
Image imFont = { Image imFont = {
.data = calloc(128*128, 2), // 2 bytes per pixel (gray + alpha) .data = calloc(128*128, 2), // 2 bytes per pixel (gray + alpha)
.width = 128, .width = 128,
.height = 128, .height = 128,
.format = UNCOMPRESSED_GRAY_ALPHA, .format = UNCOMPRESSED_GRAY_ALPHA,
.mipmaps = 1 .mipmaps = 1
@ -335,16 +335,16 @@ Font LoadFont(const char *fileName)
Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int charsCount) Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int charsCount)
{ {
Font font = { 0 }; Font font = { 0 };
// Loading file to memory // Loading file to memory
unsigned int fileSize = 0; unsigned int fileSize = 0;
unsigned char *fileData = LoadFileData(fileName, &fileSize); unsigned char *fileData = LoadFileData(fileName, &fileSize);
if (fileData != NULL) if (fileData != NULL)
{ {
// Loading font from memory data // Loading font from memory data
font = LoadFontFromMemory(GetFileExtension(fileName), fileData, fileSize, fontSize, fontChars, charsCount); font = LoadFontFromMemory(GetFileExtension(fileName), fileData, fileSize, fontSize, fontChars, charsCount);
RL_FREE(fileData); RL_FREE(fileData);
} }
else font = GetFontDefault(); else font = GetFontDefault();
@ -358,7 +358,7 @@ Font LoadFontFromImage(Image image, Color key, int firstChar)
#ifndef MAX_GLYPHS_FROM_IMAGE #ifndef MAX_GLYPHS_FROM_IMAGE
#define MAX_GLYPHS_FROM_IMAGE 256 // Maximum number of glyphs supported on image scan #define MAX_GLYPHS_FROM_IMAGE 256 // Maximum number of glyphs supported on image scan
#endif #endif
#define COLOR_EQUAL(col1, col2) ((col1.r == col2.r)&&(col1.g == col2.g)&&(col1.b == col2.b)&&(col1.a == col2.a)) #define COLOR_EQUAL(col1, col2) ((col1.r == col2.r)&&(col1.g == col2.g)&&(col1.b == col2.b)&&(col1.a == col2.a))
int charSpacing = 0; int charSpacing = 0;
@ -478,7 +478,7 @@ Font LoadFontFromImage(Image image, Color key, int firstChar)
Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int charsCount) Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int charsCount)
{ {
Font font = { 0 }; Font font = { 0 };
char fileExtLower[16] = { 0 }; char fileExtLower[16] = { 0 };
strcpy(fileExtLower, TextToLower(fileType)); strcpy(fileExtLower, TextToLower(fileType));
@ -604,7 +604,7 @@ CharInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize
.format = UNCOMPRESSED_GRAYSCALE, .format = UNCOMPRESSED_GRAYSCALE,
.mipmaps = 1 .mipmaps = 1
}; };
chars[i].image = imSpace; chars[i].image = imSpace;
} }
@ -1103,7 +1103,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
// Returns index position for a unicode character on spritefont // Returns index position for a unicode character on spritefont
int GetGlyphIndex(Font font, int codepoint) int GetGlyphIndex(Font font, int codepoint)
{ {
#ifndef GLYPH_NOTFOUND_CHAR_FALLBACK #ifndef GLYPH_NOTFOUND_CHAR_FALLBACK
#define GLYPH_NOTFOUND_CHAR_FALLBACK 63 // Character used if requested codepoint is not found: '?' #define GLYPH_NOTFOUND_CHAR_FALLBACK 63 // Character used if requested codepoint is not found: '?'
#endif #endif
@ -1150,7 +1150,7 @@ const char *TextFormat(const char *text, ...)
#ifndef MAX_TEXTFORMAT_BUFFERS #ifndef MAX_TEXTFORMAT_BUFFERS
#define MAX_TEXTFORMAT_BUFFERS 4 // Maximum number of static buffers for text formatting #define MAX_TEXTFORMAT_BUFFERS 4 // Maximum number of static buffers for text formatting
#endif #endif
// We create an array of buffers so strings don't expire until MAX_TEXTFORMAT_BUFFERS invocations // We create an array of buffers so strings don't expire until MAX_TEXTFORMAT_BUFFERS invocations
static char buffers[MAX_TEXTFORMAT_BUFFERS][MAX_TEXT_BUFFER_LENGTH] = { 0 }; static char buffers[MAX_TEXTFORMAT_BUFFERS][MAX_TEXT_BUFFER_LENGTH] = { 0 };
static int index = 0; static int index = 0;
@ -1254,7 +1254,7 @@ char *TextReplace(char *text, const char *replace, const char *by)
{ {
// Sanity checks and initialization // Sanity checks and initialization
if (!text || !replace || !by) return NULL; if (!text || !replace || !by) return NULL;
char *result; char *result;
char *insertPoint; // Next insert point char *insertPoint; // Next insert point
@ -1718,7 +1718,7 @@ static Font LoadBMFont(const char *fileName)
int fontSize = 0; int fontSize = 0;
int charsCount = 0; int charsCount = 0;
int imWidth = 0; int imWidth = 0;
int imHeight = 0; int imHeight = 0;
char imFileName[129]; char imFileName[129];
@ -1730,7 +1730,7 @@ static Font LoadBMFont(const char *fileName)
if (fileText == NULL) return font; if (fileText == NULL) return font;
char *fileTextPtr = fileText; char *fileTextPtr = fileText;
// NOTE: We skip first line, it contains no useful information // NOTE: We skip first line, it contains no useful information
int lineBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE); int lineBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE);
fileTextPtr += (lineBytes + 1); fileTextPtr += (lineBytes + 1);
@ -1795,7 +1795,7 @@ static Font LoadBMFont(const char *fileName)
((unsigned char *)(imFontAlpha.data))[p] = 0xff; ((unsigned char *)(imFontAlpha.data))[p] = 0xff;
((unsigned char *)(imFontAlpha.data))[p + 1] = ((unsigned char *)imFont.data)[i]; ((unsigned char *)(imFontAlpha.data))[p + 1] = ((unsigned char *)imFont.data)[i];
} }
UnloadImage(imFont); UnloadImage(imFont);
imFont = imFontAlpha; imFont = imFontAlpha;
} }

+ 152
- 142
src/textures.c View File

@ -210,7 +210,7 @@ Image LoadImage(const char *fileName)
// Loading file to memory // Loading file to memory
unsigned int fileSize = 0; unsigned int fileSize = 0;
unsigned char *fileData = LoadFileData(fileName, &fileSize); unsigned char *fileData = LoadFileData(fileName, &fileSize);
if (fileData != NULL) if (fileData != NULL)
{ {
// Loading image from memory data // Loading image from memory data
@ -218,7 +218,7 @@ Image LoadImage(const char *fileName)
if (image.data != NULL) TRACELOG(LOG_INFO, "IMAGE: [%s] Data loaded successfully (%ix%i)", fileName, image.width, image.height); if (image.data != NULL) TRACELOG(LOG_INFO, "IMAGE: [%s] Data loaded successfully (%ix%i)", fileName, image.width, image.height);
else TRACELOG(LOG_WARNING, "IMAGE: [%s] Failed to load data", fileName); else TRACELOG(LOG_WARNING, "IMAGE: [%s] Failed to load data", fileName);
RL_FREE(fileData); RL_FREE(fileData);
} }
@ -262,7 +262,7 @@ Image LoadImageAnim(const char *fileName, int *frames)
{ {
Image image = { 0 }; Image image = { 0 };
int framesCount = 1; int framesCount = 1;
#if defined(SUPPORT_FILEFORMAT_GIF) #if defined(SUPPORT_FILEFORMAT_GIF)
if (IsFileExtension(fileName, ".gif")) if (IsFileExtension(fileName, ".gif"))
{ {
@ -286,7 +286,7 @@ Image LoadImageAnim(const char *fileName, int *frames)
if (false) { } if (false) { }
#endif #endif
else image = LoadImage(fileName); else image = LoadImage(fileName);
// TODO: Support APNG animated images? // TODO: Support APNG animated images?
*frames = framesCount; *frames = framesCount;
@ -297,7 +297,7 @@ Image LoadImageAnim(const char *fileName, int *frames)
Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize) Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize)
{ {
Image image = { 0 }; Image image = { 0 };
char fileExtLower[16] = { 0 }; char fileExtLower[16] = { 0 };
strcpy(fileExtLower, TextToLower(fileType)); strcpy(fileExtLower, TextToLower(fileType));
@ -313,7 +313,7 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
|| (TextIsEqual(fileExtLower, "tga")) || (TextIsEqual(fileExtLower, "tga"))
#endif #endif
#if defined(SUPPORT_FILEFORMAT_JPG) #if defined(SUPPORT_FILEFORMAT_JPG)
|| (TextIsEqual(fileExtLower, "jpg") || || (TextIsEqual(fileExtLower, "jpg") ||
TextIsEqual(fileExtLower, "jpeg")) TextIsEqual(fileExtLower, "jpeg"))
#endif #endif
#if defined(SUPPORT_FILEFORMAT_GIF) #if defined(SUPPORT_FILEFORMAT_GIF)
@ -329,7 +329,7 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
{ {
#if defined(STBI_REQUIRED) #if defined(STBI_REQUIRED)
// NOTE: Using stb_image to load images (Supports multiple image formats) // NOTE: Using stb_image to load images (Supports multiple image formats)
if (fileData != NULL) if (fileData != NULL)
{ {
int comp = 0; int comp = 0;
@ -383,7 +383,7 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
else if (TextIsEqual(fileExtLower, "astc")) image = LoadASTC(fileData, dataSize); else if (TextIsEqual(fileExtLower, "astc")) image = LoadASTC(fileData, dataSize);
#endif #endif
else TRACELOG(LOG_WARNING, "IMAGE: File format not supported"); else TRACELOG(LOG_WARNING, "IMAGE: File format not supported");
return image; return image;
} }
@ -403,7 +403,7 @@ void ExportImage(Image image, const char *fileName)
int channels = 4; int channels = 4;
bool allocatedData = false; bool allocatedData = false;
unsigned char *imgData = (unsigned char *)image.data; unsigned char *imgData = (unsigned char *)image.data;
if (image.format == UNCOMPRESSED_GRAYSCALE) channels = 1; if (image.format == UNCOMPRESSED_GRAYSCALE) channels = 1;
else if (image.format == UNCOMPRESSED_GRAY_ALPHA) channels = 2; else if (image.format == UNCOMPRESSED_GRAY_ALPHA) channels = 2;
else if (image.format == UNCOMPRESSED_R8G8B8) channels = 3; else if (image.format == UNCOMPRESSED_R8G8B8) channels = 3;
@ -414,7 +414,7 @@ void ExportImage(Image image, const char *fileName)
imgData = (unsigned char *)GetImageData(image); imgData = (unsigned char *)GetImageData(image);
allocatedData = true; allocatedData = true;
} }
#if defined(SUPPORT_FILEFORMAT_PNG) #if defined(SUPPORT_FILEFORMAT_PNG)
if (IsFileExtension(fileName, ".png")) success = stbi_write_png(fileName, image.width, image.height, channels, imgData, image.width*channels); if (IsFileExtension(fileName, ".png")) success = stbi_write_png(fileName, image.width, image.height, channels, imgData, image.width*channels);
#else #else
@ -439,7 +439,7 @@ void ExportImage(Image image, const char *fileName)
SaveFileData(fileName, image.data, GetPixelDataSize(image.width, image.height, image.format)); SaveFileData(fileName, image.data, GetPixelDataSize(image.width, image.height, image.format));
success = true; success = true;
} }
if (allocatedData) RL_FREE(imgData); if (allocatedData) RL_FREE(imgData);
#endif // SUPPORT_IMAGE_EXPORT #endif // SUPPORT_IMAGE_EXPORT
@ -455,7 +455,7 @@ void ExportImageAsCode(Image image, const char *fileName)
#endif #endif
int dataSize = GetPixelDataSize(image.width, image.height, image.format); int dataSize = GetPixelDataSize(image.width, image.height, image.format);
// NOTE: Text data buffer size is estimated considering image data size in bytes // NOTE: Text data buffer size is estimated considering image data size in bytes
// and requiring 6 char bytes for every byte: "0x00, " // and requiring 6 char bytes for every byte: "0x00, "
char *txtData = (char *)RL_CALLOC(6*dataSize + 2000, sizeof(char)); char *txtData = (char *)RL_CALLOC(6*dataSize + 2000, sizeof(char));
@ -801,9 +801,9 @@ Image ImageCopy(Image image)
Image ImageFromImage(Image image, Rectangle rec) Image ImageFromImage(Image image, Rectangle rec)
{ {
Image result = { 0 }; Image result = { 0 };
int bytesPerPixel = GetPixelDataSize(1, 1, image.format); int bytesPerPixel = GetPixelDataSize(1, 1, image.format);
// TODO: Check rec is valid? // TODO: Check rec is valid?
result.width = rec.width; result.width = rec.width;
@ -811,7 +811,7 @@ Image ImageFromImage(Image image, Rectangle rec)
result.data = RL_CALLOC(rec.width*rec.height*bytesPerPixel, 1); result.data = RL_CALLOC(rec.width*rec.height*bytesPerPixel, 1);
result.format = image.format; result.format = image.format;
result.mipmaps = 1; result.mipmaps = 1;
for (int y = 0; y < rec.height; y++) for (int y = 0; y < rec.height; y++)
{ {
memcpy(((unsigned char *)result.data) + y*(int)rec.width*bytesPerPixel, ((unsigned char *)image.data) + ((y + (int)rec.y)*image.width + (int)rec.x)*bytesPerPixel, (int)rec.width*bytesPerPixel); memcpy(((unsigned char *)result.data) + y*(int)rec.width*bytesPerPixel, ((unsigned char *)image.data) + ((y + (int)rec.y)*image.width + (int)rec.x)*bytesPerPixel, (int)rec.width*bytesPerPixel);
@ -832,7 +832,7 @@ void ImageCrop(Image *image, Rectangle crop)
if (crop.y < 0) { crop.height += crop.y; crop.y = 0; } if (crop.y < 0) { crop.height += crop.y; crop.y = 0; }
if ((crop.x + crop.width) > image->width) crop.width = image->width - crop.x; if ((crop.x + crop.width) > image->width) crop.width = image->width - crop.x;
if ((crop.y + crop.height) > image->height) crop.height = image->height - crop.y; if ((crop.y + crop.height) > image->height) crop.height = image->height - crop.y;
if ((crop.x > image->width) || (crop.y > image->height)) if ((crop.x > image->width) || (crop.y > image->height))
{ {
TRACELOG(LOG_WARNING, "IMAGE: Failed to crop, rectangle out of bounds"); TRACELOG(LOG_WARNING, "IMAGE: Failed to crop, rectangle out of bounds");
return; return;
@ -843,16 +843,16 @@ void ImageCrop(Image *image, Rectangle crop)
else else
{ {
int bytesPerPixel = GetPixelDataSize(1, 1, image->format); int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *croppedData = (unsigned char *)RL_MALLOC(crop.width*crop.height*bytesPerPixel); unsigned char *croppedData = (unsigned char *)RL_MALLOC(crop.width*crop.height*bytesPerPixel);
// OPTION 1: Move cropped data line-by-line // OPTION 1: Move cropped data line-by-line
for (int y = (int)crop.y, offsetSize = 0; y < (int)(crop.y + crop.height); y++) for (int y = (int)crop.y, offsetSize = 0; y < (int)(crop.y + crop.height); y++)
{ {
memcpy(croppedData + offsetSize, ((unsigned char *)image->data) + (y*image->width + (int)crop.x)*bytesPerPixel, (int)crop.width*bytesPerPixel); memcpy(croppedData + offsetSize, ((unsigned char *)image->data) + (y*image->width + (int)crop.x)*bytesPerPixel, (int)crop.width*bytesPerPixel);
offsetSize += ((int)crop.width*bytesPerPixel); offsetSize += ((int)crop.width*bytesPerPixel);
} }
/* /*
// OPTION 2: Move cropped data pixel-by-pixel or byte-by-byte // OPTION 2: Move cropped data pixel-by-pixel or byte-by-byte
for (int y = (int)crop.y; y < (int)(crop.y + crop.height); y++) for (int y = (int)crop.y; y < (int)(crop.y + crop.height); y++)
@ -1157,7 +1157,7 @@ void ImageAlphaClear(Image *image, Color color, float threshold)
{ {
// Security check to avoid program crash // Security check to avoid program crash
if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return; if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return;
if (image->mipmaps > 1) TRACELOG(LOG_WARNING, "Image manipulation only applied to base mipmap level"); if (image->mipmaps > 1) TRACELOG(LOG_WARNING, "Image manipulation only applied to base mipmap level");
if (image->format >= COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Image manipulation not supported for compressed formats"); if (image->format >= COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Image manipulation not supported for compressed formats");
else else
@ -1167,7 +1167,7 @@ void ImageAlphaClear(Image *image, Color color, float threshold)
case UNCOMPRESSED_GRAY_ALPHA: case UNCOMPRESSED_GRAY_ALPHA:
{ {
unsigned char thresholdValue = (unsigned char)(threshold*255.0f); unsigned char thresholdValue = (unsigned char)(threshold*255.0f);
for (int i = 1; i < image->width*image->height*2; i += 2) for (int i = 1; i < image->width*image->height*2; i += 2)
{ {
if (((unsigned char *)image->data)[i] <= thresholdValue) if (((unsigned char *)image->data)[i] <= thresholdValue)
{ {
@ -1179,7 +1179,7 @@ void ImageAlphaClear(Image *image, Color color, float threshold)
case UNCOMPRESSED_R5G5B5A1: case UNCOMPRESSED_R5G5B5A1:
{ {
unsigned char thresholdValue = ((threshold < 0.5f)? 0 : 1); unsigned char thresholdValue = ((threshold < 0.5f)? 0 : 1);
unsigned char r = (unsigned char)(round((float)color.r*31.0f)); unsigned char r = (unsigned char)(round((float)color.r*31.0f));
unsigned char g = (unsigned char)(round((float)color.g*31.0f)); unsigned char g = (unsigned char)(round((float)color.g*31.0f));
unsigned char b = (unsigned char)(round((float)color.b*31.0f)); unsigned char b = (unsigned char)(round((float)color.b*31.0f));
@ -1196,7 +1196,7 @@ void ImageAlphaClear(Image *image, Color color, float threshold)
case UNCOMPRESSED_R4G4B4A4: case UNCOMPRESSED_R4G4B4A4:
{ {
unsigned char thresholdValue = (unsigned char)(threshold*15.0f); unsigned char thresholdValue = (unsigned char)(threshold*15.0f);
unsigned char r = (unsigned char)(round((float)color.r*15.0f)); unsigned char r = (unsigned char)(round((float)color.r*15.0f));
unsigned char g = (unsigned char)(round((float)color.g*15.0f)); unsigned char g = (unsigned char)(round((float)color.g*15.0f));
unsigned char b = (unsigned char)(round((float)color.b*15.0f)); unsigned char b = (unsigned char)(round((float)color.b*15.0f));
@ -1213,7 +1213,7 @@ void ImageAlphaClear(Image *image, Color color, float threshold)
case UNCOMPRESSED_R8G8B8A8: case UNCOMPRESSED_R8G8B8A8:
{ {
unsigned char thresholdValue = (unsigned char)(threshold*255.0f); unsigned char thresholdValue = (unsigned char)(threshold*255.0f);
for (int i = 3; i < image->width*image->height*4; i += 4) for (int i = 3; i < image->width*image->height*4; i += 4)
{ {
if (((unsigned char *)image->data)[i] <= thresholdValue) if (((unsigned char *)image->data)[i] <= thresholdValue)
{ {
@ -1226,7 +1226,7 @@ void ImageAlphaClear(Image *image, Color color, float threshold)
} break; } break;
case UNCOMPRESSED_R32G32B32A32: case UNCOMPRESSED_R32G32B32A32:
{ {
for (int i = 3; i < image->width*image->height*4; i += 4) for (int i = 3; i < image->width*image->height*4; i += 4)
{ {
if (((float *)image->data)[i] <= threshold) if (((float *)image->data)[i] <= threshold)
{ {
@ -1324,7 +1324,7 @@ void ImageAlphaPremultiply(Image *image)
int format = image->format; int format = image->format;
image->data = pixels; image->data = pixels;
image->format = UNCOMPRESSED_R8G8B8A8; image->format = UNCOMPRESSED_R8G8B8A8;
ImageFormat(image, format); ImageFormat(image, format);
} }
@ -1336,15 +1336,15 @@ void ImageResize(Image *image, int newWidth, int newHeight)
{ {
// Security check to avoid program crash // Security check to avoid program crash
if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return; if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return;
bool fastPath = true; bool fastPath = true;
if ((image->format != UNCOMPRESSED_GRAYSCALE) && (image->format != UNCOMPRESSED_GRAY_ALPHA) && (image->format != UNCOMPRESSED_R8G8B8) && (image->format != UNCOMPRESSED_R8G8B8A8)) fastPath = true; if ((image->format != UNCOMPRESSED_GRAYSCALE) && (image->format != UNCOMPRESSED_GRAY_ALPHA) && (image->format != UNCOMPRESSED_R8G8B8) && (image->format != UNCOMPRESSED_R8G8B8A8)) fastPath = true;
if (fastPath) if (fastPath)
{ {
int bytesPerPixel = GetPixelDataSize(1, 1, image->format); int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *output = RL_MALLOC(newWidth*newHeight*bytesPerPixel); unsigned char *output = RL_MALLOC(newWidth*newHeight*bytesPerPixel);
switch (image->format) switch (image->format)
{ {
case UNCOMPRESSED_GRAYSCALE: stbir_resize_uint8((unsigned char *)image->data, image->width, image->height, 0, output, newWidth, newHeight, 0, 1); break; case UNCOMPRESSED_GRAYSCALE: stbir_resize_uint8((unsigned char *)image->data, image->width, image->height, 0, output, newWidth, newHeight, 0, 1); break;
@ -1369,7 +1369,7 @@ void ImageResize(Image *image, int newWidth, int newHeight)
stbir_resize_uint8((unsigned char *)pixels, image->width, image->height, 0, (unsigned char *)output, newWidth, newHeight, 0, 4); stbir_resize_uint8((unsigned char *)pixels, image->width, image->height, 0, (unsigned char *)output, newWidth, newHeight, 0, 4);
int format = image->format; int format = image->format;
RL_FREE(pixels); RL_FREE(pixels);
RL_FREE(image->data); RL_FREE(image->data);
@ -1410,7 +1410,7 @@ void ImageResizeNN(Image *image,int newWidth,int newHeight)
int format = image->format; int format = image->format;
RL_FREE(image->data); RL_FREE(image->data);
image->data = output; image->data = output;
image->width = newWidth; image->width = newWidth;
image->height = newHeight; image->height = newHeight;
@ -1427,14 +1427,14 @@ void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, i
{ {
// Security check to avoid program crash // Security check to avoid program crash
if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return; if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return;
if (image->mipmaps > 1) TRACELOG(LOG_WARNING, "Image manipulation only applied to base mipmap level"); if (image->mipmaps > 1) TRACELOG(LOG_WARNING, "Image manipulation only applied to base mipmap level");
if (image->format >= COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Image manipulation not supported for compressed formats"); if (image->format >= COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Image manipulation not supported for compressed formats");
else if ((newWidth != image->width) || (newHeight != image->height)) else if ((newWidth != image->width) || (newHeight != image->height))
{ {
Rectangle srcRec = { 0, 0, image->width, image->height }; Rectangle srcRec = { 0, 0, image->width, image->height };
Vector2 dstPos = { offsetX, offsetY }; Vector2 dstPos = { offsetX, offsetY };
if (offsetX < 0) if (offsetX < 0)
{ {
srcRec.x = -offsetX; srcRec.x = -offsetX;
@ -1456,17 +1456,17 @@ void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, i
int bytesPerPixel = GetPixelDataSize(1, 1, image->format); int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *resizedData = (unsigned char *)RL_CALLOC(newWidth*newHeight*bytesPerPixel, 1); unsigned char *resizedData = (unsigned char *)RL_CALLOC(newWidth*newHeight*bytesPerPixel, 1);
// TODO: Fill resizedData with fill color (must be formatted to image->format) // TODO: Fill resizedData with fill color (must be formatted to image->format)
int dstOffsetSize = ((int)dstPos.y*newWidth + (int)dstPos.x)*bytesPerPixel; int dstOffsetSize = ((int)dstPos.y*newWidth + (int)dstPos.x)*bytesPerPixel;
for (int y = 0; y < (int)srcRec.height; y++) for (int y = 0; y < (int)srcRec.height; y++)
{ {
memcpy(resizedData + dstOffsetSize, ((unsigned char *)image->data) + ((y + (int)srcRec.y)*image->width + (int)srcRec.x)*bytesPerPixel, (int)srcRec.width*bytesPerPixel); memcpy(resizedData + dstOffsetSize, ((unsigned char *)image->data) + ((y + (int)srcRec.y)*image->width + (int)srcRec.x)*bytesPerPixel, (int)srcRec.width*bytesPerPixel);
dstOffsetSize += (newWidth*bytesPerPixel); dstOffsetSize += (newWidth*bytesPerPixel);
} }
RL_FREE(image->data); RL_FREE(image->data);
image->data = resizedData; image->data = resizedData;
image->width = newWidth; image->width = newWidth;
@ -1668,13 +1668,13 @@ void ImageFlipVertical(Image *image)
{ {
int bytesPerPixel = GetPixelDataSize(1, 1, image->format); int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *flippedData = (unsigned char *)RL_MALLOC(image->width*image->height*bytesPerPixel); unsigned char *flippedData = (unsigned char *)RL_MALLOC(image->width*image->height*bytesPerPixel);
for (int i = (image->height - 1), offsetSize = 0; i >= 0; i--) for (int i = (image->height - 1), offsetSize = 0; i >= 0; i--)
{ {
memcpy(flippedData + offsetSize, ((unsigned char *)image->data) + i*image->width*bytesPerPixel, image->width*bytesPerPixel); memcpy(flippedData + offsetSize, ((unsigned char *)image->data) + i*image->width*bytesPerPixel, image->width*bytesPerPixel);
offsetSize += image->width*bytesPerPixel; offsetSize += image->width*bytesPerPixel;
} }
RL_FREE(image->data); RL_FREE(image->data);
image->data = flippedData; image->data = flippedData;
} }
@ -1692,19 +1692,19 @@ void ImageFlipHorizontal(Image *image)
{ {
int bytesPerPixel = GetPixelDataSize(1, 1, image->format); int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *flippedData = (unsigned char *)RL_MALLOC(image->width*image->height*bytesPerPixel); unsigned char *flippedData = (unsigned char *)RL_MALLOC(image->width*image->height*bytesPerPixel);
for (int y = 0; y < image->height; y++) for (int y = 0; y < image->height; y++)
{ {
for (int x = 0; x < image->width; x++) for (int x = 0; x < image->width; x++)
{ {
// OPTION 1: Move pixels with memcopy() // OPTION 1: Move pixels with memcopy()
//memcpy(flippedData + (y*image->width + x)*bytesPerPixel, ((unsigned char *)image->data) + (y*image->width + (image->width - 1 - x))*bytesPerPixel, bytesPerPixel); //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: Just 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]; 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];
} }
} }
RL_FREE(image->data); RL_FREE(image->data);
image->data = flippedData; image->data = flippedData;
@ -1737,7 +1737,7 @@ void ImageRotateCW(Image *image)
{ {
int bytesPerPixel = GetPixelDataSize(1, 1, image->format); int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *rotatedData = (unsigned char *)RL_MALLOC(image->width*image->height*bytesPerPixel); unsigned char *rotatedData = (unsigned char *)RL_MALLOC(image->width*image->height*bytesPerPixel);
for (int y = 0; y < image->height; y++) for (int y = 0; y < image->height; y++)
{ {
for (int x = 0; x < image->width; x++) for (int x = 0; x < image->width; x++)
@ -1746,12 +1746,12 @@ void ImageRotateCW(Image *image)
for (int i = 0; i < bytesPerPixel; i++) rotatedData[(x*image->height + (image->height - y - 1))*bytesPerPixel + i] = ((unsigned char *)image->data)[(y*image->width + x)*bytesPerPixel + i]; for (int i = 0; i < bytesPerPixel; i++) rotatedData[(x*image->height + (image->height - y - 1))*bytesPerPixel + i] = ((unsigned char *)image->data)[(y*image->width + x)*bytesPerPixel + i];
} }
} }
RL_FREE(image->data); RL_FREE(image->data);
image->data = rotatedData; image->data = rotatedData;
int width = image->width; int width = image->width;
int height = image-> height; int height = image-> height;
image->width = height; image->width = height;
image->height = width; image->height = width;
} }
@ -1769,7 +1769,7 @@ void ImageRotateCCW(Image *image)
{ {
int bytesPerPixel = GetPixelDataSize(1, 1, image->format); int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *rotatedData = (unsigned char *)RL_MALLOC(image->width*image->height*bytesPerPixel); unsigned char *rotatedData = (unsigned char *)RL_MALLOC(image->width*image->height*bytesPerPixel);
for (int y = 0; y < image->height; y++) for (int y = 0; y < image->height; y++)
{ {
for (int x = 0; x < image->width; x++) for (int x = 0; x < image->width; x++)
@ -1778,12 +1778,12 @@ void ImageRotateCCW(Image *image)
for (int i = 0; i < bytesPerPixel; i++) rotatedData[(x*image->height + y)*bytesPerPixel + i] = ((unsigned char *)image->data)[(y*image->width + (image->width - x - 1))*bytesPerPixel + i]; for (int i = 0; i < bytesPerPixel; i++) rotatedData[(x*image->height + y)*bytesPerPixel + i] = ((unsigned char *)image->data)[(y*image->width + (image->width - x - 1))*bytesPerPixel + i];
} }
} }
RL_FREE(image->data); RL_FREE(image->data);
image->data = rotatedData; image->data = rotatedData;
int width = image->width; int width = image->width;
int height = image-> height; int height = image-> height;
image->width = height; image->width = height;
image->height = width; image->height = width;
} }
@ -1821,10 +1821,10 @@ void ImageColorTint(Image *image, Color color)
int format = image->format; int format = image->format;
RL_FREE(image->data); RL_FREE(image->data);
image->data = pixels; image->data = pixels;
image->format = UNCOMPRESSED_R8G8B8A8; image->format = UNCOMPRESSED_R8G8B8A8;
ImageFormat(image, format); ImageFormat(image, format);
} }
@ -1848,10 +1848,10 @@ void ImageColorInvert(Image *image)
int format = image->format; int format = image->format;
RL_FREE(image->data); RL_FREE(image->data);
image->data = pixels; image->data = pixels;
image->format = UNCOMPRESSED_R8G8B8A8; image->format = UNCOMPRESSED_R8G8B8A8;
ImageFormat(image, format); ImageFormat(image, format);
} }
@ -1912,10 +1912,10 @@ void ImageColorContrast(Image *image, float contrast)
int format = image->format; int format = image->format;
RL_FREE(image->data); RL_FREE(image->data);
image->data = pixels; image->data = pixels;
image->format = UNCOMPRESSED_R8G8B8A8; image->format = UNCOMPRESSED_R8G8B8A8;
ImageFormat(image, format); ImageFormat(image, format);
} }
@ -1956,10 +1956,10 @@ void ImageColorBrightness(Image *image, int brightness)
int format = image->format; int format = image->format;
RL_FREE(image->data); RL_FREE(image->data);
image->data = pixels; image->data = pixels;
image->format = UNCOMPRESSED_R8G8B8A8; image->format = UNCOMPRESSED_R8G8B8A8;
ImageFormat(image, format); ImageFormat(image, format);
} }
@ -1990,10 +1990,10 @@ void ImageColorReplace(Image *image, Color color, Color replace)
int format = image->format; int format = image->format;
RL_FREE(image->data); RL_FREE(image->data);
image->data = pixels; image->data = pixels;
image->format = UNCOMPRESSED_R8G8B8A8; image->format = UNCOMPRESSED_R8G8B8A8;
ImageFormat(image, format); ImageFormat(image, format);
} }
#endif // SUPPORT_IMAGE_MANIPULATION #endif // SUPPORT_IMAGE_MANIPULATION
@ -2333,24 +2333,24 @@ void ImageDrawPixel(Image *dst, int x, int y, Color color)
{ {
// Security check to avoid program crash // Security check to avoid program crash
if ((dst->data == NULL) || (x < 0) || (x >= dst->width) || (y < 0) || (y >= dst->height)) return; if ((dst->data == NULL) || (x < 0) || (x >= dst->width) || (y < 0) || (y >= dst->height)) return;
switch (dst->format) switch (dst->format)
{ {
case UNCOMPRESSED_GRAYSCALE: case UNCOMPRESSED_GRAYSCALE:
{ {
// NOTE: Calculate grayscale equivalent color // NOTE: Calculate grayscale equivalent color
Vector3 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f }; Vector3 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f };
unsigned char gray = (unsigned char)((coln.x*0.299f + coln.y*0.587f + coln.z*0.114f)*255.0f); unsigned char gray = (unsigned char)((coln.x*0.299f + coln.y*0.587f + coln.z*0.114f)*255.0f);
((unsigned char *)dst->data)[y*dst->width + x] = gray;
((unsigned char *)dst->data)[y*dst->width + x] = gray;
} break; } break;
case UNCOMPRESSED_GRAY_ALPHA: case UNCOMPRESSED_GRAY_ALPHA:
{ {
// NOTE: Calculate grayscale equivalent color // NOTE: Calculate grayscale equivalent color
Vector3 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f }; Vector3 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f };
unsigned char gray = (unsigned char)((coln.x*0.299f + coln.y*0.587f + coln.z*0.114f)*255.0f); unsigned char gray = (unsigned char)((coln.x*0.299f + coln.y*0.587f + coln.z*0.114f)*255.0f);
((unsigned char *)dst->data)[(y*dst->width + x)*2] = gray; ((unsigned char *)dst->data)[(y*dst->width + x)*2] = gray;
((unsigned char *)dst->data)[(y*dst->width + x)*2 + 1] = color.a; ((unsigned char *)dst->data)[(y*dst->width + x)*2 + 1] = color.a;
@ -2365,7 +2365,7 @@ void ImageDrawPixel(Image *dst, int x, int y, Color color)
unsigned char b = (unsigned char)(round(coln.z*31.0f)); unsigned char b = (unsigned char)(round(coln.z*31.0f));
((unsigned short *)dst->data)[y*dst->width + x] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b; ((unsigned short *)dst->data)[y*dst->width + x] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b;
} break; } break;
case UNCOMPRESSED_R5G5B5A1: case UNCOMPRESSED_R5G5B5A1:
{ {
@ -2391,14 +2391,14 @@ void ImageDrawPixel(Image *dst, int x, int y, Color color)
unsigned char a = (unsigned char)(round(coln.w*15.0f)); unsigned char a = (unsigned char)(round(coln.w*15.0f));
((unsigned short *)dst->data)[y*dst->width + x] = (unsigned short)r << 12 | (unsigned short)g << 8 | (unsigned short)b << 4 | (unsigned short)a; ((unsigned short *)dst->data)[y*dst->width + x] = (unsigned short)r << 12 | (unsigned short)g << 8 | (unsigned short)b << 4 | (unsigned short)a;
} break; } break;
case UNCOMPRESSED_R8G8B8: case UNCOMPRESSED_R8G8B8:
{ {
((unsigned char *)dst->data)[(y*dst->width + x)*3] = color.r; ((unsigned char *)dst->data)[(y*dst->width + x)*3] = color.r;
((unsigned char *)dst->data)[(y*dst->width + x)*3 + 1] = color.g; ((unsigned char *)dst->data)[(y*dst->width + x)*3 + 1] = color.g;
((unsigned char *)dst->data)[(y*dst->width + x)*3 + 2] = color.b; ((unsigned char *)dst->data)[(y*dst->width + x)*3 + 2] = color.b;
} break; } break;
case UNCOMPRESSED_R8G8B8A8: case UNCOMPRESSED_R8G8B8A8:
{ {
@ -2413,25 +2413,25 @@ void ImageDrawPixel(Image *dst, int x, int y, Color color)
// NOTE: Calculate grayscale equivalent color (normalized to 32bit) // NOTE: Calculate grayscale equivalent color (normalized to 32bit)
Vector3 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f }; Vector3 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f };
((float *)dst->data)[y*dst->width + x] = coln.x*0.299f + coln.y*0.587f + coln.z*0.114f; ((float *)dst->data)[y*dst->width + x] = coln.x*0.299f + coln.y*0.587f + coln.z*0.114f;
} break; } break;
case UNCOMPRESSED_R32G32B32: case UNCOMPRESSED_R32G32B32:
{ {
// NOTE: Calculate R32G32B32 equivalent color (normalized to 32bit) // NOTE: Calculate R32G32B32 equivalent color (normalized to 32bit)
Vector3 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f }; Vector3 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f };
((float *)dst->data)[(y*dst->width + x)*3] = coln.x; ((float *)dst->data)[(y*dst->width + x)*3] = coln.x;
((float *)dst->data)[(y*dst->width + x)*3 + 1] = coln.y; ((float *)dst->data)[(y*dst->width + x)*3 + 1] = coln.y;
((float *)dst->data)[(y*dst->width + x)*3 + 2] = coln.z; ((float *)dst->data)[(y*dst->width + x)*3 + 2] = coln.z;
} break; } break;
case UNCOMPRESSED_R32G32B32A32: case UNCOMPRESSED_R32G32B32A32:
{ {
// NOTE: Calculate R32G32B32A32 equivalent color (normalized to 32bit) // NOTE: Calculate R32G32B32A32 equivalent color (normalized to 32bit)
Vector4 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f, (float)color.a/255.0f }; Vector4 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f, (float)color.a/255.0f };
((float *)dst->data)[(y*dst->width + x)*4] = coln.x; ((float *)dst->data)[(y*dst->width + x)*4] = coln.x;
((float *)dst->data)[(y*dst->width + x)*4 + 1] = coln.y; ((float *)dst->data)[(y*dst->width + x)*4 + 1] = coln.y;
((float *)dst->data)[(y*dst->width + x)*4 + 2] = coln.z; ((float *)dst->data)[(y*dst->width + x)*4 + 2] = coln.z;
((float *)dst->data)[(y*dst->width + x)*4 + 3] = coln.w; ((float *)dst->data)[(y*dst->width + x)*4 + 3] = coln.w;
@ -2603,9 +2603,9 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
Color colSrc, colDst, blend; Color colSrc, colDst, blend;
bool blendRequired = true; bool blendRequired = true;
// Fast path: Avoid blend if source has no alpha to blend // Fast path: Avoid blend if source has no alpha to blend
if ((tint.a == 255) && ((srcPtr->format == UNCOMPRESSED_GRAYSCALE) || (srcPtr->format == UNCOMPRESSED_R8G8B8) || (srcPtr->format == UNCOMPRESSED_R5G6B5))) blendRequired = false; if ((tint.a == 255) && ((srcPtr->format == UNCOMPRESSED_GRAYSCALE) || (srcPtr->format == UNCOMPRESSED_R8G8B8) || (srcPtr->format == UNCOMPRESSED_R5G6B5))) blendRequired = false;
int strideDst = GetPixelDataSize(dst->width, 1, dst->format); int strideDst = GetPixelDataSize(dst->width, 1, dst->format);
int bytesPerPixelDst = strideDst/(dst->width); int bytesPerPixelDst = strideDst/(dst->width);
@ -2629,7 +2629,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
{ {
colSrc = GetPixelColor(pSrc, srcPtr->format); colSrc = GetPixelColor(pSrc, srcPtr->format);
colDst = GetPixelColor(pDst, dst->format); colDst = GetPixelColor(pDst, dst->format);
// Fast path: Avoid blend if source has no alpha to blend // Fast path: Avoid blend if source has no alpha to blend
if (blendRequired) blend = ColorAlphaBlend(colDst, colSrc, tint); if (blendRequired) blend = ColorAlphaBlend(colDst, colSrc, tint);
else blend = colSrc; else blend = colSrc;
@ -2797,13 +2797,13 @@ TextureCubemap LoadTextureCubemap(Image image, int layoutType)
RenderTexture2D LoadRenderTexture(int width, int height) RenderTexture2D LoadRenderTexture(int width, int height)
{ {
RenderTexture2D target = { 0 }; RenderTexture2D target = { 0 };
target.id = rlLoadFramebuffer(width, height); // Load an empty framebuffer target.id = rlLoadFramebuffer(width, height); // Load an empty framebuffer
if (target.id > 0) if (target.id > 0)
{ {
rlEnableFramebuffer(target.id); rlEnableFramebuffer(target.id);
// Create color texture (default to RGBA) // Create color texture (default to RGBA)
target.texture.id = rlLoadTexture(NULL, width, height, UNCOMPRESSED_R8G8B8A8, 1); target.texture.id = rlLoadTexture(NULL, width, height, UNCOMPRESSED_R8G8B8A8, 1);
target.texture.width = width; target.texture.width = width;
@ -2846,11 +2846,11 @@ void UnloadTexture(Texture2D texture)
// Unload render texture from GPU memory (VRAM) // Unload render texture from GPU memory (VRAM)
void UnloadRenderTexture(RenderTexture2D target) void UnloadRenderTexture(RenderTexture2D target)
{ {
if (target.id > 0) if (target.id > 0)
{ {
// Color texture attached to FBO is deleted // Color texture attached to FBO is deleted
rlUnloadTexture(target.texture.id); rlUnloadTexture(target.texture.id);
// NOTE: Depth texture/renderbuffer is automatically // NOTE: Depth texture/renderbuffer is automatically
// queried and deleted before deleting framebuffer // queried and deleted before deleting framebuffer
rlUnloadFramebuffer(target.id); rlUnloadFramebuffer(target.id);
@ -3072,40 +3072,44 @@ void DrawTextureQuad(Texture2D texture, Vector2 tiling, Vector2 offset, Rectangl
// NOTE: For tilling a whole texture DrawTextureQuad() is better // NOTE: For tilling a whole texture DrawTextureQuad() is better
void DrawTextureTiled(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, float scale, Color tint) void DrawTextureTiled(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, float scale, Color tint)
{ {
if(texture.id <= 0 || scale <= 0.0f) return; // Wanna see a infinite loop?!...just delete this line! if (texture.id <= 0 || scale <= 0.0f) return; // Wanna see a infinite loop?!...just delete this line!
int tileWidth = sourceRec.width*scale, tileHeight = sourceRec.height*scale; int tileWidth = sourceRec.width*scale, tileHeight = sourceRec.height*scale;
if(destRec.width < tileWidth && destRec.height < tileHeight) if (destRec.width < tileWidth && destRec.height < tileHeight)
{ {
// Can fit only one tile // Can fit only one tile
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)destRec.width/tileWidth)*sourceRec.width, ((float)destRec.height/tileHeight)*sourceRec.height}, DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)destRec.width/tileWidth)*sourceRec.width, ((float)destRec.height/tileHeight)*sourceRec.height},
(Rectangle){destRec.x, destRec.y, destRec.width, destRec.height}, origin, rotation, tint); (Rectangle){destRec.x, destRec.y, destRec.width, destRec.height}, origin, rotation, tint);
} }
else if(destRec.width <= tileWidth) else if (destRec.width <= tileWidth)
{ {
// Tiled vertically (one column) // Tiled vertically (one column)
int dy = 0; int dy = 0;
for(;dy+tileHeight < destRec.height; dy += tileHeight) { for (;dy+tileHeight < destRec.height; dy += tileHeight)
{
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)destRec.width/tileWidth)*sourceRec.width, sourceRec.height}, (Rectangle){destRec.x, destRec.y + dy, destRec.width, tileHeight}, origin, rotation, tint); DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)destRec.width/tileWidth)*sourceRec.width, sourceRec.height}, (Rectangle){destRec.x, destRec.y + dy, destRec.width, tileHeight}, origin, rotation, tint);
} }
// Fit last tile // Fit last tile
if(dy < destRec.height) { if (dy < destRec.height)
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)destRec.width/tileWidth)*sourceRec.width, ((float)(destRec.height - dy)/tileHeight)*sourceRec.height}, {
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)destRec.width/tileWidth)*sourceRec.width, ((float)(destRec.height - dy)/tileHeight)*sourceRec.height},
(Rectangle){destRec.x, destRec.y + dy, destRec.width, destRec.height - dy}, origin, rotation, tint); (Rectangle){destRec.x, destRec.y + dy, destRec.width, destRec.height - dy}, origin, rotation, tint);
} }
} }
else if(destRec.height <= tileHeight) else if (destRec.height <= tileHeight)
{ {
// Tiled horizontally (one row) // Tiled horizontally (one row)
int dx = 0; int dx = 0;
for(;dx+tileWidth < destRec.width; dx += tileWidth) { for (;dx+tileWidth < destRec.width; dx += tileWidth)
{
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, sourceRec.width, ((float)destRec.height/tileHeight)*sourceRec.height}, (Rectangle){destRec.x + dx, destRec.y, tileWidth, destRec.height}, origin, rotation, tint); DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, sourceRec.width, ((float)destRec.height/tileHeight)*sourceRec.height}, (Rectangle){destRec.x + dx, destRec.y, tileWidth, destRec.height}, origin, rotation, tint);
} }
// Fit last tile // Fit last tile
if(dx < destRec.width) { if (dx < destRec.width)
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)(destRec.width - dx)/tileWidth)*sourceRec.width, ((float)destRec.height/tileHeight)*sourceRec.height}, {
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)(destRec.width - dx)/tileWidth)*sourceRec.width, ((float)destRec.height/tileHeight)*sourceRec.height},
(Rectangle){destRec.x + dx, destRec.y, destRec.width - dx, destRec.height}, origin, rotation, tint); (Rectangle){destRec.x + dx, destRec.y, destRec.width - dx, destRec.height}, origin, rotation, tint);
} }
} }
@ -3113,29 +3117,35 @@ void DrawTextureTiled(Texture2D texture, Rectangle sourceRec, Rectangle destRec,
{ {
// Tiled both horizontally and vertically (rows and columns) // Tiled both horizontally and vertically (rows and columns)
int dx = 0; int dx = 0;
for(;dx+tileWidth < destRec.width; dx += tileWidth) { for (;dx+tileWidth < destRec.width; dx += tileWidth)
{
int dy = 0; int dy = 0;
for(;dy+tileHeight < destRec.height; dy += tileHeight) { for (;dy+tileHeight < destRec.height; dy += tileHeight)
{
DrawTexturePro(texture, sourceRec, (Rectangle){destRec.x + dx, destRec.y + dy, tileWidth, tileHeight}, origin, rotation, tint); DrawTexturePro(texture, sourceRec, (Rectangle){destRec.x + dx, destRec.y + dy, tileWidth, tileHeight}, origin, rotation, tint);
} }
if (dy < destRec.height)
if(dy < destRec.height) { {
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, sourceRec.width, ((float)(destRec.height - dy)/tileHeight)*sourceRec.height}, DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, sourceRec.width, ((float)(destRec.height - dy)/tileHeight)*sourceRec.height},
(Rectangle){destRec.x + dx, destRec.y + dy, tileWidth, destRec.height - dy}, origin, rotation, tint); (Rectangle){destRec.x + dx, destRec.y + dy, tileWidth, destRec.height - dy}, origin, rotation, tint);
} }
} }
// Fit last column of tiles // Fit last column of tiles
if(dx < destRec.width) { if (dx < destRec.width)
{
int dy = 0; int dy = 0;
for(;dy+tileHeight < destRec.height; dy += tileHeight) { for (;dy+tileHeight < destRec.height; dy += tileHeight)
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)(destRec.width - dx)/tileWidth)*sourceRec.width, sourceRec.height}, {
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)(destRec.width - dx)/tileWidth)*sourceRec.width, sourceRec.height},
(Rectangle){destRec.x + dx, destRec.y + dy, destRec.width - dx, tileHeight}, origin, rotation, tint); (Rectangle){destRec.x + dx, destRec.y + dy, destRec.width - dx, tileHeight}, origin, rotation, tint);
} }
// Draw final tile in the bottom right corner // Draw final tile in the bottom right corner
if(dy < destRec.height) { if (dy < destRec.height)
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)(destRec.width - dx)/tileWidth)*sourceRec.width, ((float)(destRec.height - dy)/tileHeight)*sourceRec.height}, {
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)(destRec.width - dx)/tileWidth)*sourceRec.width, ((float)(destRec.height - dy)/tileHeight)*sourceRec.height},
(Rectangle){destRec.x + dx, destRec.y + dy, destRec.width - dx, destRec.height - dy}, origin, rotation, tint); (Rectangle){destRec.x + dx, destRec.y + dy, destRec.width - dx, destRec.height - dy}, origin, rotation, tint);
} }
} }
@ -3532,7 +3542,7 @@ Color ColorAlpha(Color color, float alpha)
Color ColorAlphaBlend(Color dst, Color src, Color tint) Color ColorAlphaBlend(Color dst, Color src, Color tint)
{ {
Color out = WHITE; Color out = WHITE;
// Apply color tint to source color // Apply color tint to source color
src.r = (unsigned char)(((unsigned int)src.r*(unsigned int)tint.r) >> 8); src.r = (unsigned char)(((unsigned int)src.r*(unsigned int)tint.r) >> 8);
src.g = (unsigned char)(((unsigned int)src.g*(unsigned int)tint.g) >> 8); src.g = (unsigned char)(((unsigned int)src.g*(unsigned int)tint.g) >> 8);
@ -3575,7 +3585,7 @@ Color ColorAlphaBlend(Color dst, Color src, Color tint)
fout.y = (fsrc.y*fsrc.w + fdst.y*fdst.w*(1 - fsrc.w))/fout.w; fout.y = (fsrc.y*fsrc.w + fdst.y*fdst.w*(1 - fsrc.w))/fout.w;
fout.z = (fsrc.z*fsrc.w + fdst.z*fdst.w*(1 - fsrc.w))/fout.w; fout.z = (fsrc.z*fsrc.w + fdst.z*fdst.w*(1 - fsrc.w))/fout.w;
} }
out = (Color){ (unsigned char)(fout.x*255.0f), (unsigned char)(fout.y*255.0f), (unsigned char)(fout.z*255.0f), (unsigned char)(fout.w*255.0f) }; out = (Color){ (unsigned char)(fout.x*255.0f), (unsigned char)(fout.y*255.0f), (unsigned char)(fout.z*255.0f), (unsigned char)(fout.w*255.0f) };
} }
#endif #endif
@ -3600,7 +3610,7 @@ Color GetColor(int hexValue)
Color GetPixelColor(void *srcPtr, int format) Color GetPixelColor(void *srcPtr, int format)
{ {
Color col = { 0 }; Color col = { 0 };
switch (format) switch (format)
{ {
case UNCOMPRESSED_GRAYSCALE: col = (Color){ ((unsigned char *)srcPtr)[0], ((unsigned char *)srcPtr)[0], ((unsigned char *)srcPtr)[0], 255 }; break; case UNCOMPRESSED_GRAYSCALE: col = (Color){ ((unsigned char *)srcPtr)[0], ((unsigned char *)srcPtr)[0], ((unsigned char *)srcPtr)[0], 255 }; break;
@ -3611,7 +3621,7 @@ Color GetPixelColor(void *srcPtr, int format)
col.g = (unsigned char)(((((unsigned short *)srcPtr)[0] >> 5) & 0b0000000000111111)*255/63); col.g = (unsigned char)(((((unsigned short *)srcPtr)[0] >> 5) & 0b0000000000111111)*255/63);
col.b = (unsigned char)((((unsigned short *)srcPtr)[0] & 0b0000000000011111)*255/31); col.b = (unsigned char)((((unsigned short *)srcPtr)[0] & 0b0000000000011111)*255/31);
col.a = 255; col.a = 255;
} break; } break;
case UNCOMPRESSED_R5G5B5A1: case UNCOMPRESSED_R5G5B5A1:
{ {
@ -3627,7 +3637,7 @@ Color GetPixelColor(void *srcPtr, int format)
col.g = (unsigned char)(((((unsigned short *)srcPtr)[0] >> 8) & 0b0000000000001111)*255/15); col.g = (unsigned char)(((((unsigned short *)srcPtr)[0] >> 8) & 0b0000000000001111)*255/15);
col.b = (unsigned char)(((((unsigned short *)srcPtr)[0] >> 4) & 0b0000000000001111)*255/15); col.b = (unsigned char)(((((unsigned short *)srcPtr)[0] >> 4) & 0b0000000000001111)*255/15);
col.a = (unsigned char)((((unsigned short *)srcPtr)[0] & 0b0000000000001111)*255/15); col.a = (unsigned char)((((unsigned short *)srcPtr)[0] & 0b0000000000001111)*255/15);
} break; } break;
case UNCOMPRESSED_R8G8B8A8: col = (Color){ ((unsigned char *)srcPtr)[0], ((unsigned char *)srcPtr)[1], ((unsigned char *)srcPtr)[2], ((unsigned char *)srcPtr)[3] }; break; case UNCOMPRESSED_R8G8B8A8: col = (Color){ ((unsigned char *)srcPtr)[0], ((unsigned char *)srcPtr)[1], ((unsigned char *)srcPtr)[2], ((unsigned char *)srcPtr)[3] }; break;
case UNCOMPRESSED_R8G8B8: col = (Color){ ((unsigned char *)srcPtr)[0], ((unsigned char *)srcPtr)[1], ((unsigned char *)srcPtr)[2], 255 }; break; case UNCOMPRESSED_R8G8B8: col = (Color){ ((unsigned char *)srcPtr)[0], ((unsigned char *)srcPtr)[1], ((unsigned char *)srcPtr)[2], 255 }; break;
@ -3636,7 +3646,7 @@ Color GetPixelColor(void *srcPtr, int format)
// TODO: case UNCOMPRESSED_R32G32B32A32: break; // TODO: case UNCOMPRESSED_R32G32B32A32: break;
default: break; default: break;
} }
return col; return col;
} }
@ -3645,21 +3655,21 @@ void SetPixelColor(void *dstPtr, Color color, int format)
{ {
switch (format) switch (format)
{ {
case UNCOMPRESSED_GRAYSCALE: case UNCOMPRESSED_GRAYSCALE:
{ {
// NOTE: Calculate grayscale equivalent color // NOTE: Calculate grayscale equivalent color
Vector3 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f }; Vector3 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f };
unsigned char gray = (unsigned char)((coln.x*0.299f + coln.y*0.587f + coln.z*0.114f)*255.0f); unsigned char gray = (unsigned char)((coln.x*0.299f + coln.y*0.587f + coln.z*0.114f)*255.0f);
((unsigned char *)dstPtr)[0] = gray; ((unsigned char *)dstPtr)[0] = gray;
} break; } break;
case UNCOMPRESSED_GRAY_ALPHA: case UNCOMPRESSED_GRAY_ALPHA:
{ {
// NOTE: Calculate grayscale equivalent color // NOTE: Calculate grayscale equivalent color
Vector3 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f }; Vector3 coln = { (float)color.r/255.0f, (float)color.g/255.0f, (float)color.b/255.0f };
unsigned char gray = (unsigned char)((coln.x*0.299f + coln.y*0.587f + coln.z*0.114f)*255.0f); unsigned char gray = (unsigned char)((coln.x*0.299f + coln.y*0.587f + coln.z*0.114f)*255.0f);
((unsigned char *)dstPtr)[0] = gray; ((unsigned char *)dstPtr)[0] = gray;
((unsigned char *)dstPtr)[1] = color.a; ((unsigned char *)dstPtr)[1] = color.a;
@ -3674,7 +3684,7 @@ void SetPixelColor(void *dstPtr, Color color, int format)
unsigned char b = (unsigned char)(round(coln.z*31.0f)); unsigned char b = (unsigned char)(round(coln.z*31.0f));
((unsigned short *)dstPtr)[0] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b; ((unsigned short *)dstPtr)[0] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b;
} break; } break;
case UNCOMPRESSED_R5G5B5A1: case UNCOMPRESSED_R5G5B5A1:
{ {
@ -3700,14 +3710,14 @@ void SetPixelColor(void *dstPtr, Color color, int format)
unsigned char a = (unsigned char)(round(coln.w*15.0f)); unsigned char a = (unsigned char)(round(coln.w*15.0f));
((unsigned short *)dstPtr)[0] = (unsigned short)r << 12 | (unsigned short)g << 8 | (unsigned short)b << 4 | (unsigned short)a; ((unsigned short *)dstPtr)[0] = (unsigned short)r << 12 | (unsigned short)g << 8 | (unsigned short)b << 4 | (unsigned short)a;
} break; } break;
case UNCOMPRESSED_R8G8B8: case UNCOMPRESSED_R8G8B8:
{ {
((unsigned char *)dstPtr)[0] = color.r; ((unsigned char *)dstPtr)[0] = color.r;
((unsigned char *)dstPtr)[1] = color.g; ((unsigned char *)dstPtr)[1] = color.g;
((unsigned char *)dstPtr)[2] = color.b; ((unsigned char *)dstPtr)[2] = color.b;
} break; } break;
case UNCOMPRESSED_R8G8B8A8: case UNCOMPRESSED_R8G8B8A8:
{ {
@ -3715,7 +3725,7 @@ void SetPixelColor(void *dstPtr, Color color, int format)
((unsigned char *)dstPtr)[1] = color.g; ((unsigned char *)dstPtr)[1] = color.g;
((unsigned char *)dstPtr)[2] = color.b; ((unsigned char *)dstPtr)[2] = color.b;
((unsigned char *)dstPtr)[3] = color.a; ((unsigned char *)dstPtr)[3] = color.a;
} break; } break;
default: break; default: break;
} }
@ -3755,7 +3765,7 @@ int GetPixelDataSize(int width, int height, int format)
} }
dataSize = width*height*bpp/8; // Total data size in bytes dataSize = width*height*bpp/8; // Total data size in bytes
// Most compressed formats works on 4x4 blocks, // Most compressed formats works on 4x4 blocks,
// if texture is smaller, minimum dataSize is 8 or 16 // if texture is smaller, minimum dataSize is 8 or 16
if ((width < 4) && (height < 4)) if ((width < 4) && (height < 4))
@ -3775,7 +3785,7 @@ int GetPixelDataSize(int width, int height, int format)
static Image LoadDDS(const unsigned char *fileData, unsigned int fileSize) static Image LoadDDS(const unsigned char *fileData, unsigned int fileSize)
{ {
unsigned char *fileDataPtr = (unsigned char *)fileData; unsigned char *fileDataPtr = (unsigned char *)fileData;
// Required extension: // Required extension:
// GL_EXT_texture_compression_s3tc // GL_EXT_texture_compression_s3tc
@ -3841,7 +3851,7 @@ static Image LoadDDS(const unsigned char *fileData, unsigned int fileSize)
TRACELOGD(" > Pixel format flags: 0x%x", ddsHeader->ddspf.flags); TRACELOGD(" > Pixel format flags: 0x%x", ddsHeader->ddspf.flags);
TRACELOGD(" > File format: 0x%x", ddsHeader->ddspf.fourCC); TRACELOGD(" > File format: 0x%x", ddsHeader->ddspf.fourCC);
TRACELOGD(" > File bit count: 0x%x", ddsHeader->ddspf.rgbBitCount); TRACELOGD(" > File bit count: 0x%x", ddsHeader->ddspf.rgbBitCount);
fileDataPtr += sizeof(DDSHeader); // Skip header fileDataPtr += sizeof(DDSHeader); // Skip header
image.width = ddsHeader->width; image.width = ddsHeader->width;
@ -3971,7 +3981,7 @@ static Image LoadDDS(const unsigned char *fileData, unsigned int fileSize)
static Image LoadPKM(const unsigned char *fileData, unsigned int fileSize) static Image LoadPKM(const unsigned char *fileData, unsigned int fileSize)
{ {
unsigned char *fileDataPtr = (unsigned char *)fileData; unsigned char *fileDataPtr = (unsigned char *)fileData;
// Required extensions: // Required extensions:
// GL_OES_compressed_ETC1_RGB8_texture (ETC1) (OpenGL ES 2.0) // GL_OES_compressed_ETC1_RGB8_texture (ETC1) (OpenGL ES 2.0)
// GL_ARB_ES3_compatibility (ETC2/EAC) (OpenGL ES 3.0) // GL_ARB_ES3_compatibility (ETC2/EAC) (OpenGL ES 3.0)
@ -4012,7 +4022,7 @@ static Image LoadPKM(const unsigned char *fileData, unsigned int fileSize)
else else
{ {
fileDataPtr += sizeof(PKMHeader); // Skip header fileDataPtr += sizeof(PKMHeader); // Skip header
// NOTE: format, width and height come as big-endian, data must be swapped to little-endian // NOTE: format, width and height come as big-endian, data must be swapped to little-endian
pkmHeader->format = ((pkmHeader->format & 0x00FF) << 8) | ((pkmHeader->format & 0xFF00) >> 8); pkmHeader->format = ((pkmHeader->format & 0x00FF) << 8) | ((pkmHeader->format & 0xFF00) >> 8);
pkmHeader->width = ((pkmHeader->width & 0x00FF) << 8) | ((pkmHeader->width & 0xFF00) >> 8); pkmHeader->width = ((pkmHeader->width & 0x00FF) << 8) | ((pkmHeader->width & 0xFF00) >> 8);
@ -4051,7 +4061,7 @@ static Image LoadPKM(const unsigned char *fileData, unsigned int fileSize)
static Image LoadKTX(const unsigned char *fileData, unsigned int fileSize) static Image LoadKTX(const unsigned char *fileData, unsigned int fileSize)
{ {
unsigned char *fileDataPtr = (unsigned char *)fileData; unsigned char *fileDataPtr = (unsigned char *)fileData;
// Required extensions: // Required extensions:
// GL_OES_compressed_ETC1_RGB8_texture (ETC1) // GL_OES_compressed_ETC1_RGB8_texture (ETC1)
// GL_ARB_ES3_compatibility (ETC2/EAC) // GL_ARB_ES3_compatibility (ETC2/EAC)
@ -4100,7 +4110,7 @@ static Image LoadKTX(const unsigned char *fileData, unsigned int fileSize)
else else
{ {
fileDataPtr += sizeof(KTXHeader); // Move file data pointer fileDataPtr += sizeof(KTXHeader); // Move file data pointer
image.width = ktxHeader->width; image.width = ktxHeader->width;
image.height = ktxHeader->height; image.height = ktxHeader->height;
image.mipmaps = ktxHeader->mipmapLevels; image.mipmaps = ktxHeader->mipmapLevels;
@ -4114,7 +4124,7 @@ static Image LoadKTX(const unsigned char *fileData, unsigned int fileSize)
int dataSize = ((int *)fileDataPtr)[0]; int dataSize = ((int *)fileDataPtr)[0];
fileDataPtr += sizeof(int); fileDataPtr += sizeof(int);
image.data = (unsigned char *)RL_MALLOC(dataSize*sizeof(unsigned char)); image.data = (unsigned char *)RL_MALLOC(dataSize*sizeof(unsigned char));
memcpy(image.data, fileDataPtr, dataSize); memcpy(image.data, fileDataPtr, dataSize);
@ -4156,7 +4166,7 @@ static int SaveKTX(Image image, const char *fileName)
// Calculate file dataSize required // Calculate file dataSize required
int dataSize = sizeof(KTXHeader); int dataSize = sizeof(KTXHeader);
for (int i = 0, width = image.width, height = image.height; i < image.mipmaps; i++) for (int i = 0, width = image.width, height = image.height; i < image.mipmaps; i++)
{ {
dataSize += GetPixelDataSize(width, height, image.format); dataSize += GetPixelDataSize(width, height, image.format);
@ -4200,7 +4210,7 @@ static int SaveKTX(Image image, const char *fileName)
{ {
memcpy(fileDataPtr, &ktxHeader, sizeof(KTXHeader)); memcpy(fileDataPtr, &ktxHeader, sizeof(KTXHeader));
fileDataPtr += sizeof(KTXHeader); fileDataPtr += sizeof(KTXHeader);
int width = image.width; int width = image.width;
int height = image.height; int height = image.height;
int dataOffset = 0; int dataOffset = 0;
@ -4209,10 +4219,10 @@ static int SaveKTX(Image image, const char *fileName)
for (int i = 0; i < image.mipmaps; i++) for (int i = 0; i < image.mipmaps; i++)
{ {
unsigned int dataSize = GetPixelDataSize(width, height, image.format); unsigned int dataSize = GetPixelDataSize(width, height, image.format);
memcpy(fileDataPtr, &dataSize, sizeof(unsigned int)); memcpy(fileDataPtr, &dataSize, sizeof(unsigned int));
memcpy(fileDataPtr + 4, (unsigned char *)image.data + dataOffset, dataSize); memcpy(fileDataPtr + 4, (unsigned char *)image.data + dataOffset, dataSize);
width /= 2; width /= 2;
height /= 2; height /= 2;
dataOffset += dataSize; dataOffset += dataSize;
@ -4235,7 +4245,7 @@ static int SaveKTX(Image image, const char *fileName)
static Image LoadPVR(const unsigned char *fileData, unsigned int fileSize) static Image LoadPVR(const unsigned char *fileData, unsigned int fileSize)
{ {
unsigned char *fileDataPtr = (unsigned char *)fileData; unsigned char *fileDataPtr = (unsigned char *)fileData;
// Required extension: // Required extension:
// GL_IMG_texture_compression_pvrtc // GL_IMG_texture_compression_pvrtc
@ -4309,7 +4319,7 @@ static Image LoadPVR(const unsigned char *fileData, unsigned int fileSize)
else else
{ {
fileDataPtr += sizeof(PVRHeaderV3); // Skip header fileDataPtr += sizeof(PVRHeaderV3); // Skip header
image.width = pvrHeader->width; image.width = pvrHeader->width;
image.height = pvrHeader->height; image.height = pvrHeader->height;
image.mipmaps = pvrHeader->numMipmaps; image.mipmaps = pvrHeader->numMipmaps;
@ -4370,7 +4380,7 @@ static Image LoadPVR(const unsigned char *fileData, unsigned int fileSize)
static Image LoadASTC(const unsigned char *fileData, unsigned int fileSize) static Image LoadASTC(const unsigned char *fileData, unsigned int fileSize)
{ {
unsigned char *fileDataPtr = (unsigned char *)fileData; unsigned char *fileDataPtr = (unsigned char *)fileData;
// Required extensions: // Required extensions:
// GL_KHR_texture_compression_astc_hdr // GL_KHR_texture_compression_astc_hdr
// GL_KHR_texture_compression_astc_ldr // GL_KHR_texture_compression_astc_ldr
@ -4403,7 +4413,7 @@ static Image LoadASTC(const unsigned char *fileData, unsigned int fileSize)
else else
{ {
fileDataPtr += sizeof(ASTCHeader); // Skip header fileDataPtr += sizeof(ASTCHeader); // Skip header
// NOTE: Assuming Little Endian (could it be wrong?) // NOTE: Assuming Little Endian (could it be wrong?)
image.width = 0x00000000 | ((int)astcHeader->width[2] << 16) | ((int)astcHeader->width[1] << 8) | ((int)astcHeader->width[0]); image.width = 0x00000000 | ((int)astcHeader->width[2] << 16) | ((int)astcHeader->width[1] << 8) | ((int)astcHeader->width[0]);
image.height = 0x00000000 | ((int)astcHeader->height[2] << 16) | ((int)astcHeader->height[1] << 8) | ((int)astcHeader->height[0]); image.height = 0x00000000 | ((int)astcHeader->height[2] << 16) | ((int)astcHeader->height[1] << 8) | ((int)astcHeader->height[0]);
@ -4424,7 +4434,7 @@ static Image LoadASTC(const unsigned char *fileData, unsigned int fileSize)
int dataSize = image.width*image.height*bpp/8; // Data size in bytes int dataSize = image.width*image.height*bpp/8; // Data size in bytes
image.data = (unsigned char *)RL_MALLOC(dataSize*sizeof(unsigned char)); image.data = (unsigned char *)RL_MALLOC(dataSize*sizeof(unsigned char));
memcpy(image.data, fileDataPtr, dataSize); memcpy(image.data, fileDataPtr, dataSize);
if (bpp == 8) image.format = COMPRESSED_ASTC_4x4_RGBA; if (bpp == 8) image.format = COMPRESSED_ASTC_4x4_RGBA;

+ 1
- 1
src/utils.c View File

@ -317,7 +317,7 @@ FILE *android_fopen(const char *fileName, const char *mode)
// NOTE: AAsset provides access to read-only asset // NOTE: AAsset provides access to read-only asset
AAsset *asset = AAssetManager_open(assetManager, fileName, AASSET_MODE_UNKNOWN); AAsset *asset = AAssetManager_open(assetManager, fileName, AASSET_MODE_UNKNOWN);
if (asset != NULL) if (asset != NULL)
{ {
// Return pointer to file in the assets // Return pointer to file in the assets
return funopen(asset, android_read, android_write, android_seek, android_close); return funopen(asset, android_read, android_write, android_seek, android_close);

||||||
x
 
000:0
Loading…
Cancel
Save