浏览代码

Remove trailing spaces

pull/1428/head
Ray 4 年前
父节点
当前提交
3e1cd487df
共有 11 个文件被更改,包括 337 次插入325 次删除
  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 查看文件

@ -319,7 +319,7 @@ void UpdateCamera(Camera *camera)
CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
if (CAMERA.targetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) CAMERA.targetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP;
}
// Camera looking down
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.y = camera->position.y - transform.m13;
camera->target.z = camera->position.z - transform.m14;
// If movement detected (some key pressed), increase swinging
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...
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;
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;
} break;

+ 31
- 31
src/core.c 查看文件

@ -229,12 +229,12 @@
#include <termios.h> // POSIX terminal control definitions - tcgetattr(), tcsetattr()
#include <pthread.h> // POSIX threads management (inputs reading)
#include <dirent.h> // POSIX directory browsing
#include <sys/ioctl.h> // UNIX System call for device-specific input/output operations - ioctl()
#include <linux/kd.h> // Linux: KDSKBMODE, K_MEDIUMRAM constants definition
#include <linux/input.h> // Linux: Keycodes constants definition (KEY_A, ...)
#include <linux/joystick.h> // Linux: Joystick support library
#if defined(PLATFORM_RPI)
#include "bcm_host.h" // Raspberry Pi VideoCore IV access functions
#endif
@ -244,7 +244,7 @@
#include <xf86drm.h> // Direct Rendering Manager user-level library interface
#include <xf86drmMode.h> // Direct Rendering Manager modesetting interface
#endif
#include "EGL/egl.h" // EGL library - Native platform display device control functions
#include "EGL/eglext.h" // EGL library - Extensions
#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.cursor = MOUSE_CURSOR_ARROW;
CORE.Input.Gamepad.lastButtonPressed = -1;
#if defined(PLATFORM_UWP)
// The axis count is 6 (2 thumbsticks and left and right trigger)
CORE.Input.Gamepad.axisCount = 6;
@ -834,7 +834,7 @@ void CloseWindow(void)
CORE.Window.gbmDevice = NULL;
}
if(CORE.Window.crtc)
if (CORE.Window.crtc)
{
if (CORE.Window.connector)
{
@ -925,7 +925,7 @@ bool WindowShouldClose(void)
while (!CORE.Window.alwaysRun && CORE.Window.minimized) glfwWaitEvents();
CORE.Window.shouldClose = glfwWindowShouldClose(CORE.Window.handle);
// Reset close status for next frame
glfwSetWindowShouldClose(CORE.Window.handle, GLFW_FALSE);
@ -1029,7 +1029,7 @@ void ToggleFullscreen(void)
else Module.requestFullscreen(true, true);
);
*/
//EM_ASM(Module.requestFullscreen(false, false););
/*
@ -1043,13 +1043,13 @@ void ToggleFullscreen(void)
.canvasResizedCallback = EmscriptenWindowResizedCallback, //on_canvassize_changed,
.canvasResizedCallbackUserData = NULL
};
emscripten_request_fullscreen("#canvas", false);
//emscripten_request_fullscreen_strategy("#canvas", EM_FALSE, &strategy);
//emscripten_enter_soft_fullscreen("canvas", &strategy);
TRACELOG(LOG_INFO, "emscripten_request_fullscreen_strategy");
}
else
else
{
TRACELOG(LOG_INFO, "emscripten_exit_fullscreen");
emscripten_exit_fullscreen();
@ -1350,12 +1350,12 @@ Vector2 GetWindowPosition(void)
Vector2 GetWindowScaleDPI(void)
{
Vector2 scale = { 1.0f, 1.0f };
#if defined(PLATFORM_DESKTOP)
float xdpi = 1.0;
float ydpi = 1.0;
Vector2 windowPos = GetWindowPosition();
int monitorCount = 0;
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
@ -1363,12 +1363,12 @@ Vector2 GetWindowScaleDPI(void)
for (int i = 0; i < monitorCount; i++)
{
glfwGetMonitorContentScale(monitors[i], &xdpi, &ydpi);
int xpos, ypos, width, height;
glfwGetMonitorWorkarea(monitors[i], &xpos, &ypos, &width, &height);
if ((windowPos.x >= xpos) && (windowPos.x < xpos + width) &&
(windowPos.y >= ypos) && (windowPos.y < ypos + height))
if ((windowPos.x >= xpos) && (windowPos.x < xpos + width) &&
(windowPos.y >= ypos) && (windowPos.y < ypos + height))
{
scale.x = xdpi;
scale.y = ydpi;
@ -2146,7 +2146,7 @@ const char *GetPrevDirectoryPath(const char *dirPath)
{
// Check for root: "C:\" or "/"
if (((i == 2) && (dirPath[1] ==':')) || (i == 0)) i++;
strncpy(prevDirPath, dirPath, i);
break;
}
@ -2221,9 +2221,9 @@ void ClearDirectoryFiles(void)
bool ChangeDirectory(const char *dir)
{
bool result = CHDIR(dir);
if (result != 0) TRACELOG(LOG_WARNING, "SYSTEM: Failed to change to directory: %s", dir);
return (result == 0);
}
@ -2330,13 +2330,13 @@ void SaveStorageValue(unsigned int position, int value)
{
// RL_REALLOC succeded
int *dataPtr = (int *)newFileData;
dataPtr[position] = value;
dataPtr[position] = value;
}
else
{
// 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
newFileData = fileData;
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);
// 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.render.width/CORE.Window.render.height
// -> CORE.Window.screenScale
@ -3570,16 +3570,16 @@ static bool InitGraphicsDevice(int width, int height)
#if defined(PLATFORM_RPI)
graphics_get_display_size(0, &CORE.Window.display.width, &CORE.Window.display.height);
// Screen size security check
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;
// 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.render.width/CORE.Window.render.height
// -> CORE.Window.screenScale
// -> CORE.Window.screenScale
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
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
// 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.render.width/CORE.Window.render.height
// -> CORE.Window.screenScale
// -> CORE.Window.screenScale
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
#endif // PLATFORM_DRM
@ -4008,7 +4008,7 @@ static void PollInputEvents(void)
// Get remapped buttons
GLFWgamepadstate state = { 0 };
glfwGetGamepadState(i, &state); // This remapps all gamepads so they have their buttons mapped like an xbox controller
const unsigned char *buttons = state.buttons;
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 (((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK) ||
if (((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK) ||
((source & AINPUT_SOURCE_GAMEPAD) == AINPUT_SOURCE_GAMEPAD))
{
// 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)
{
// WARNING: Not executed when pressing Esc to exit fullscreen, it seems document has priority over #canvas
emscripten_exit_pointerlock();
CORE.Window.fullscreen = 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)
{
// 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
if (event.type == EV_REL)

+ 43
- 43
src/models.c 查看文件

@ -828,9 +828,9 @@ void ExportMesh(Mesh mesh, const char *fileName)
if (IsFileExtension(fileName, ".obj"))
{
// Estimated data size, it should be enough...
int dataSize = mesh.vertexCount/3*strlen("v 0000.00f 0000.00f 0000.00f") +
mesh.vertexCount/2*strlen("vt 0.000f 0.00f") +
mesh.vertexCount/3*strlen("vn 0.000f 0.00f 0.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/3*strlen("vn 0.000f 0.00f 0.00f") +
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
@ -879,7 +879,7 @@ void ExportMesh(Mesh mesh, const char *fileName)
RL_FREE(txtData);
}
else if (IsFileExtension(fileName, ".raw"))
else if (IsFileExtension(fileName, ".raw"))
{
// 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"))
{
tinyobj_material_t *mats = NULL;
int result = tinyobj_parse_mtl_file(&mats, &count, fileName);
if (result != TINYOBJ_SUCCESS) {
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_VERSION 2 // only IQM version 2 supported
unsigned int fileSize = 0;
unsigned char *fileData = LoadFileData(fileName, &fileSize);
unsigned char *fileDataPtr = fileData;
@ -1036,7 +1036,7 @@ ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount)
//fseek(iqmFile, iqmHeader->ofs_anims, SEEK_SET);
//fread(anim, iqmHeader->num_anims*sizeof(IQMAnim), 1, iqmFile);
memcpy(anim, fileDataPtr + iqmHeader->ofs_anims, iqmHeader->num_anims*sizeof(IQMAnim));
ModelAnimation *animations = RL_MALLOC(iqmHeader->num_anims*sizeof(ModelAnimation));
// frameposes
@ -1166,7 +1166,7 @@ ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount)
}
}
}
RL_FREE(fileData);
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++)
{
// TODO: Review color + tint premultiplication mechanism
// (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 ?
// would you prefer an extra model.tint, that rlDrawMesh uses ?
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);
else TRACELOG(LOG_INFO, "MODEL: [%s] OBJ data loaded successfully: %i meshes / %i materials", fileName, meshCount, materialCount);
model.meshCount = materialCount;
// Init model materials array
if (materialCount > 0)
{
@ -2989,16 +2989,16 @@ static Model LoadOBJ(const char *fileName)
model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material));
TraceLog(LOG_INFO, "MODEL: model has %i material meshes", materialCount);
} else {
model.meshCount = 1;
TraceLog(LOG_INFO, "MODEL: No materials, putting all meshes in a default material");
model.meshCount = 1;
TraceLog(LOG_INFO, "MODEL: No materials, putting all meshes in a default material");
}
model.meshes = (Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh));
model.meshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int));
// count the faces for each material
int* matFaces = RL_CALLOC(meshCount, sizeof(int));
for (int mi=0; mi<meshCount; mi++) {
for (int fi=0; fi<meshes[mi].length; fi++) {
int idx = attrib.material_ids[meshes[mi].face_offset + fi];
@ -3006,19 +3006,19 @@ static Model LoadOBJ(const char *fileName)
matFaces[idx]++;
}
}
//--------------------------------------
// create the material meshes
// running counts / indexes for each material mesh as we are
// building them at the same time
// running counts / indexes for each material mesh as we are
// building them at the same time
int* vCount = RL_CALLOC(model.meshCount, sizeof(int));
int* vtCount = RL_CALLOC(model.meshCount, sizeof(int));
int* vnCount = RL_CALLOC(model.meshCount, sizeof(int));
int* faceCount = RL_CALLOC(model.meshCount, sizeof(int));
// 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].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.meshMaterial[mi] = mi;
}
// 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
if (mm == -1) { mm = 0; } // no material object..
// Get indices for the face
tinyobj_vertex_index_t idx0 = attrib.faces[3 * af + 0];
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
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[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)
{
// 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...
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;
@ -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] + 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;
}
}
if (attrib.num_normals > 0)
{
// 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[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;
}
}
}
// Init model materials
for (unsigned int m = 0; m < materialCount; m++)
{
{
// Init material to default
// NOTE: Uses default shader, which only supports MAP_DIFFUSE
// (codifies) TODO my lighting shader should support at least
// diffuse AND specular ...
model.materials[m] = LoadMaterialDefault();
@ -3083,7 +3083,7 @@ static Model LoadOBJ(const char *fileName)
} else {
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].value = 0.0f;
@ -3103,9 +3103,9 @@ static Model LoadOBJ(const char *fileName)
tinyobj_attrib_free(&attrib);
tinyobj_shapes_free(meshes, meshCount);
tinyobj_materials_free(materials, materialCount);
RL_FREE(fileData);
RL_FREE(vCount);
RL_FREE(vtCount);
RL_FREE(vnCount);
@ -3128,7 +3128,7 @@ static Model LoadIQM(const char *fileName)
#define BONE_NAME_LENGTH 32 // BoneInfo name string length
#define MESH_NAME_LENGTH 32 // Mesh name string length
#define MATERIAL_NAME_LENGTH 32 // Material name string length
unsigned int fileSize = 0;
unsigned char *fileData = LoadFileData(fileName, &fileSize);
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);
return model;
}
//fileDataPtr += sizeof(IQMHeader); // Move file data pointer
// 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++)
{
// 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
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;
@ -3467,7 +3467,7 @@ static Model LoadIQM(const char *fileName)
}
RL_FREE(fileData);
RL_FREE(imesh);
RL_FREE(tri);
RL_FREE(va);

+ 16
- 16
src/raudio.c 查看文件

@ -175,7 +175,7 @@ typedef struct tagBITMAPINFOHEADER {
#if !defined(TRACELOG)
#define TRACELOG(level, ...) (void)0
#endif
// Allow custom memory allocators
#ifndef RL_MALLOC
#define RL_MALLOC(sz) malloc(sz)
@ -689,7 +689,7 @@ void UntrackAudioBuffer(AudioBuffer *buffer)
Wave LoadWave(const char *fileName)
{
Wave wave = { 0 };
// Loading file to memory
unsigned int fileSize = 0;
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 wave = { 0 };
char fileExtLower[16] = { 0 };
strcpy(fileExtLower, TextToLower(fileType));
if (false) { }
#if defined(SUPPORT_FILEFORMAT_WAV)
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);
#endif
else TRACELOG(LOG_WARNING, "WAVE: File format not supported");
return wave;
}
@ -1116,7 +1116,7 @@ Music LoadMusicStream(const char *fileName)
{
music.ctxType = MUSIC_AUDIO_WAV;
music.ctxData = ctxWav;
int sampleSize = ctxWav->bitsPerSample;
if (ctxWav->bitsPerSample == 24) sampleSize = 16; // Forcing conversion to s16 on UpdateMusicStream()
@ -1228,7 +1228,7 @@ Music LoadMusicStream(const char *fileName)
}
#endif
else TRACELOG(LOG_WARNING, "STREAM: [%s] Fileformat not supported", fileName);
if (!musicLoaded)
{
if (false) { }
@ -1900,7 +1900,7 @@ static void InitAudioBufferPool(void)
// 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);
}
// TODO: Verification required for log
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 };
drwav wav = { 0 };
bool success = drwav_init_memory(&wav, fileData, fileSize, NULL);
if (success)
{
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);
}
else TRACELOG(LOG_WARNING, "WAVE: Failed to load WAV data");
drwav_uninit(&wav);
return wave;
@ -1948,16 +1948,16 @@ static int SaveWAV(Wave wave, const char *fileName)
format.channels = wave.channels;
format.sampleRate = wave.sampleRate;
format.bitsPerSample = wave.sampleSize;
unsigned char *fileData = NULL;
unsigned int fileDataSize = 0;
drwav_init_memory_write(&wav, &fileData, &fileDataSize, &format, NULL);
drwav_write_pcm_frames(&wav, wave.sampleCount/wave.channels, wave.data);
drwav_uninit(&wav);
SaveFileData(fileName, fileData, fileDataSize);
drwav_free(fileData, NULL);
return true;
}
#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");
}
else TRACELOG(LOG_WARNING, "WAVE: Failed to load FLAC data");
return wave;
}
#endif
@ -2028,7 +2028,7 @@ static Wave LoadMP3(const unsigned char *fileData, unsigned int fileSize)
{
Wave wave = { 0 };
drmp3_config config = { 0 };
// Decode the entire MP3 file in one go
unsigned long long int totalFrameCount = 0;
wave.data = drmp3_open_memory_and_read_f32(fileData, fileSize, &config, &totalFrameCount);

+ 1
- 1
src/raylib.h 查看文件

@ -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 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 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 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)

+ 16
- 16
src/raymath.h 查看文件

@ -164,7 +164,7 @@ RMDEF float Normalize(float value, float start, float end)
}
// 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;
}
@ -325,14 +325,14 @@ RMDEF Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDistance)
float dx = target.x - v.x;
float dy = target.y - v.y;
float value = (dx*dx) + (dy*dy);
if ((value == 0) || ((maxDistance >= 0) && (value <= maxDistance*maxDistance))) result = target;
float dist = sqrtf(value);
result.x = v.x + dx/dist*maxDistance;
result.y = v.y + dy/dist*maxDistance;
return result;
}
@ -970,14 +970,14 @@ RMDEF Matrix MatrixRotateXYZ(Vector3 ang)
}
// 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
RMDEF Matrix MatrixRotateZYX(Vector3 ang)
{
Matrix result = MatrixRotateZ(ang.z);
result = MatrixMultiply(result, MatrixRotateY(ang.y));
result = MatrixMultiply(result, MatrixRotateX(ang.x));
return result;
}
@ -1329,16 +1329,16 @@ RMDEF Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to)
RMDEF Quaternion QuaternionFromMatrix(Matrix mat)
{
Quaternion result = { 0 };
if ((mat.m0 > mat.m5) && (mat.m0 > mat.m10))
{
float s = sqrtf(1.0f + mat.m0 - mat.m5 - mat.m10)*2;
result.x = 0.25f*s;
result.y = (mat.m4 + mat.m1)/s;
result.z = (mat.m2 + mat.m8)/s;
result.w = (mat.m9 - mat.m6)/s;
}
}
else if (mat.m5 > mat.m10)
{
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.z = (mat.m9 + mat.m6)/s;
result.w = (mat.m2 - mat.m8)/s;
}
}
else
{
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.w = (mat.m4 - mat.m1)/s;
}
return result;
}
@ -1363,20 +1363,20 @@ RMDEF Quaternion QuaternionFromMatrix(Matrix mat)
RMDEF Matrix QuaternionToMatrix(Quaternion q)
{
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 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);
result.m0 = 1 - b2 - c2;
result.m1 = ab - cd;
result.m2 = ac + bd;
result.m4 = ab + cd;
result.m5 = 1 - a2 - c2;
result.m6 = bc - ad;
result.m8 = ac - bd;
result.m9 = bc + ad;
result.m10 = 1 - a2 - b2;

+ 56
- 56
src/rlgl.h 查看文件

@ -138,7 +138,7 @@
#define DEFAULT_BATCH_BUFFER_ELEMENTS 8192
#elif defined(GRAPHICS_API_OPENGL_ES2)
// 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...
#define DEFAULT_BATCH_BUFFER_ELEMENTS 2048
#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)
typedef struct VertexBuffer {
int elementsCount; // Number of elements in the buffer (QUADS)
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 cCounter; // Vertex color counter to process (and draw) from full buffer
@ -808,7 +808,7 @@ typedef struct VertexBuffer {
} VertexBuffer;
// 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
// of those state-change happens (this is done in core module)
typedef struct DrawCall {
@ -868,7 +868,7 @@ typedef struct rlglData {
unsigned int defaultFShaderId; // Default fragment shader Id (used by default shader program)
Shader defaultShader; // Basic shader, support vertex color and diffuse texture
Shader currentShader; // Shader to be used on rendering (by default, defaultShader)
int currentBlendMode; // Blending mode active
int glBlendSrcFactor; // Blending source factor
int glBlendDstFactor; // Blending destination factor
@ -1477,7 +1477,7 @@ void rlDisableWireMode(void)
void rlUnloadFramebuffer(unsigned int id)
{
#if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)) && defined(SUPPORT_RENDER_TEXTURES_HINT)
// Query depth attachment to automatically delete texture/renderbuffer
int depthType = 0, depthId = 0;
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);
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.
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -1755,7 +1755,7 @@ void rlglInit(int width, int height)
glCullFace(GL_BACK); // Cull the back face (default)
glFrontFace(GL_CCW); // Front face are defined counter clockwise (default)
glEnable(GL_CULL_FACE); // Enable backface culling
// Init state: Cubemap seamless
#if defined(GRAPHICS_API_OPENGL_33)
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");
#endif
// Init state: Color/Depth buffers clear
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set clear color (black)
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);
glBindTexture(GL_TEXTURE_2D, 0);
TRACELOG(LOG_INFO, "TEXTURE: Depth texture loaded successfully");
}
else
@ -2110,7 +2110,7 @@ unsigned int rlLoadTextureDepth(int width, int height, bool useRenderBuffer)
glRenderbufferStorage(GL_RENDERBUFFER, glInternalFormat, width, height);
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);
}
#endif
@ -2141,7 +2141,7 @@ unsigned int rlLoadTextureCubemap(void *data, int size, int format)
{
if (data == NULL)
{
if (format < COMPRESSED_DXT1_RGB)
if (format < COMPRESSED_DXT1_RGB)
{
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_CHANNEL1:
case RL_ATTACHMENT_COLOR_CHANNEL2:
case RL_ATTACHMENT_COLOR_CHANNEL3:
case RL_ATTACHMENT_COLOR_CHANNEL4:
case RL_ATTACHMENT_COLOR_CHANNEL5:
case RL_ATTACHMENT_COLOR_CHANNEL6:
case RL_ATTACHMENT_COLOR_CHANNEL7:
case RL_ATTACHMENT_COLOR_CHANNEL2:
case RL_ATTACHMENT_COLOR_CHANNEL3:
case RL_ATTACHMENT_COLOR_CHANNEL4:
case RL_ATTACHMENT_COLOR_CHANNEL5:
case RL_ATTACHMENT_COLOR_CHANNEL6:
case RL_ATTACHMENT_COLOR_CHANNEL7:
{
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);
@ -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);
else if (texType == RL_ATTACHMENT_RENDERBUFFER) glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, texId);
} break;
case RL_ATTACHMENT_STENCIL:
{
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);
} 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);
else if (index + count >= mesh.vertexCount) break;
else glBufferSubData(GL_ARRAY_BUFFER, index*4*sizeof(float), count*4*sizeof(float), mesh.tangents);
} break;
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);
else if (index + count >= mesh.vertexCount) break;
else glBufferSubData(GL_ARRAY_BUFFER, index*2*sizeof(float), count*2*sizeof(float), mesh.texcoords2);
} break;
case 6: // Update indices (triangle index buffer)
{
// the * 3 is because each triangle has 3 indices
unsigned short *indices = mesh.indices;
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);
else if (index + count >= mesh.triangleCount) break;
else glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, index*3*sizeof(*indices), count*3*sizeof(*indices), indices);
} 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)
// 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)));
float16* instances = RL_MALLOC(count*sizeof(float16));
@ -3189,13 +3189,13 @@ Shader LoadShaderCode(const char *vsCode, const char *fsCode)
{
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
glDetachShader(shader.id, vertexShaderId);
glDeleteShader(vertexShaderId);
}
if (fragmentShaderId != RLGL.State.defaultFShaderId)
if (fragmentShaderId != RLGL.State.defaultFShaderId)
{
// Detach shader before deletion to make sure memory is freed
glDetachShader(shader.id, fragmentShaderId);
@ -3245,7 +3245,7 @@ void UnloadShader(Shader shader)
{
glDeleteProgram(shader.id);
RL_FREE(shader.locs);
TRACELOG(LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", shader.id);
}
#endif
@ -3345,13 +3345,13 @@ void SetShaderValueTexture(Shader shader, int uniformLoc, Texture2D texture)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
glUseProgram(shader.id);
// Check if texture is already active
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
// 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)
{
@ -3426,11 +3426,11 @@ TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, in
//------------------------------------------------------------------------------------------
unsigned int rbo = rlLoadTextureDepth(size, size, true);
cubemap.id = rlLoadTextureCubemap(NULL, size, format);
unsigned int fbo = rlLoadFramebuffer(size, size);
rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER);
rlFramebufferAttach(fbo, cubemap.id, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_CUBEMAP_POSITIVE_X);
// Check if framebuffer is complete with attachments (valid)
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
Matrix fboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_PROJECTION], fboProjection);
// Define view matrix for every side of the cubemap
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 }),
@ -3472,7 +3472,7 @@ TextureCubemap GenTextureCubemap(Shader shader, Texture2D panorama, int size, in
#endif
rlClearScreenBuffers();
GenDrawCube();
#if defined(GENTEXTURECUBEMAP_USE_BATCH_SYSTEM)
// 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!
@ -3514,7 +3514,7 @@ TextureCubemap GenTextureIrradiance(Shader shader, TextureCubemap cubemap, int s
//------------------------------------------------------------------------------------------
unsigned int rbo = rlLoadTextureDepth(size, size, true);
irradiance.id = rlLoadTextureCubemap(NULL, size, UNCOMPRESSED_R32G32B32);
unsigned int fbo = rlLoadFramebuffer(size, size);
rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER);
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
Matrix fboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_PROJECTION], fboProjection);
// Define view matrix for every side of the cubemap
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 }),
@ -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 })
};
rlEnableShader(shader.id);
glActiveTexture(GL_TEXTURE0);
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);
prefilter.id = rlLoadTextureCubemap(NULL, size, UNCOMPRESSED_R32G32B32);
rlTextureParameters(prefilter.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_LINEAR);
unsigned int fbo = rlLoadFramebuffer(size, size);
rlFramebufferAttach(fbo, rbo, RL_ATTACHMENT_DEPTH, RL_ATTACHMENT_RENDERBUFFER);
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
Matrix fboProjection = MatrixPerspective(90.0*DEG2RAD, 1.0, RL_CULL_DISTANCE_NEAR, RL_CULL_DISTANCE_FAR);
SetShaderValueMatrix(shader, shader.locs[LOC_MATRIX_PROJECTION], fboProjection);
// Define view matrix for every side of the cubemap
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 }),
@ -3632,12 +3632,12 @@ TextureCubemap GenTexturePrefilter(Shader shader, TextureCubemap cubemap, int si
// Resize framebuffer according to mip-level size.
unsigned int mipWidth = size*(int)powf(0.5f, (float)mip);
unsigned int mipHeight = size*(int)powf(0.5f, (float)mip);
rlViewport(0, 0, mipWidth, mipHeight);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, mipWidth, mipHeight);
float roughness = (float)mip/(float)(MAX_MIPMAP_LEVELS - 1);
glUniform1f(roughnessLoc, roughness);
@ -3697,7 +3697,7 @@ Texture2D GenTextureBRDF(Shader shader, int size)
rlEnableShader(shader.id);
rlViewport(0, 0, size, size);
rlEnableFramebuffer(fbo);
rlClearScreenBuffers();
GenDrawQuad();
@ -3733,15 +3733,15 @@ void BeginBlendMode(int mode)
switch (mode)
{
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_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_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_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;
default: break;
}
RLGL.State.currentBlendMode = mode;
}
#endif
@ -3788,7 +3788,7 @@ void UpdateVrTracking(Camera *camera)
void CloseVrSimulator(void)
{
#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
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)
{
RenderBatch batch = { 0 };
// Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes)
//--------------------------------------------------------------------------------------------
batch.vertexBuffer = (VertexBuffer *)RL_MALLOC(sizeof(VertexBuffer)*numBuffers);
for (int i = 0; i < numBuffers; i++)
{
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].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
@ -4338,7 +4338,7 @@ static RenderBatch LoadRenderBatch(int numBuffers, int bufferElements)
// Unbind the current VAO
if (RLGL.ExtSupported.vao) glBindVertexArray(0);
//--------------------------------------------------------------------------------------------
// Init draw calls tracking system
//--------------------------------------------------------------------------------------------
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.currentDepth = -1.0f; // Reset depth value
//--------------------------------------------------------------------------------------------
return batch;
}
@ -4410,7 +4410,7 @@ static void DrawRenderBatch(RenderBatch *batch)
if (RLGL.ExtSupported.vao) glBindVertexArray(0);
}
//------------------------------------------------------------------------------------------------------------
// Draw batch vertex buffers (considering VR stereo if required)
//------------------------------------------------------------------------------------------------------------
Matrix matProjection = RLGL.State.projection;
@ -4460,12 +4460,12 @@ static void DrawRenderBatch(RenderBatch *batch)
// Setup some default shader values
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
// Activate additional sampler textures
// Those additional textures will be common for all draw calls of the batch
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);
glBindTexture(GL_TEXTURE_2D, RLGL.State.activeTextureId[i]);
@ -4511,7 +4511,7 @@ static void DrawRenderBatch(RenderBatch *batch)
glUseProgram(0); // Unbind shader program
}
//------------------------------------------------------------------------------------------------------------
// Reset batch buffers
//------------------------------------------------------------------------------------------------------------
// Reset vertex counters for next frame
@ -4533,7 +4533,7 @@ static void DrawRenderBatch(RenderBatch *batch)
batch->draws[i].vertexCount = 0;
batch->draws[i].textureId = RLGL.State.defaultTextureId;
}
// Reset active texture units for next batch
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
glGenVertexArrays(1, &cubeVAO);
glBindVertexArray(cubeVAO);
// Gen and fill vertex buffer (VBO)
glGenBuffers(1, &cubeVBO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);

+ 4
- 2
src/shapes.c 查看文件

@ -619,7 +619,7 @@ void DrawRectangleRec(Rectangle rec, Color color)
void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color)
{
if (rlCheckBufferLimit(4)) rlglDraw();
rlEnableTexture(GetShapesTexture().id);
rlPushMatrix();
@ -1178,13 +1178,15 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int
angle += stepLength;
}
}
// 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);
rlVertex2f(point[i].x, point[i].y);
rlVertex2f(point[i + 1].x, point[i + 1].y);
}
rlEnd();
}
}

+ 13
- 13
src/text.c 查看文件

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

+ 152
- 142
src/textures.c 查看文件

@ -210,7 +210,7 @@ Image LoadImage(const char *fileName)
// Loading file to memory
unsigned int fileSize = 0;
unsigned char *fileData = LoadFileData(fileName, &fileSize);
if (fileData != NULL)
{
// 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);
else TRACELOG(LOG_WARNING, "IMAGE: [%s] Failed to load data", fileName);
RL_FREE(fileData);
}
@ -262,7 +262,7 @@ Image LoadImageAnim(const char *fileName, int *frames)
{
Image image = { 0 };
int framesCount = 1;
#if defined(SUPPORT_FILEFORMAT_GIF)
if (IsFileExtension(fileName, ".gif"))
{
@ -286,7 +286,7 @@ Image LoadImageAnim(const char *fileName, int *frames)
if (false) { }
#endif
else image = LoadImage(fileName);
// TODO: Support APNG animated images?
*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 image = { 0 };
char fileExtLower[16] = { 0 };
strcpy(fileExtLower, TextToLower(fileType));
@ -313,7 +313,7 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
|| (TextIsEqual(fileExtLower, "tga"))
#endif
#if defined(SUPPORT_FILEFORMAT_JPG)
|| (TextIsEqual(fileExtLower, "jpg") ||
|| (TextIsEqual(fileExtLower, "jpg") ||
TextIsEqual(fileExtLower, "jpeg"))
#endif
#if defined(SUPPORT_FILEFORMAT_GIF)
@ -329,7 +329,7 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
{
#if defined(STBI_REQUIRED)
// NOTE: Using stb_image to load images (Supports multiple image formats)
if (fileData != NULL)
{
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);
#endif
else TRACELOG(LOG_WARNING, "IMAGE: File format not supported");
return image;
}
@ -403,7 +403,7 @@ void ExportImage(Image image, const char *fileName)
int channels = 4;
bool allocatedData = false;
unsigned char *imgData = (unsigned char *)image.data;
if (image.format == UNCOMPRESSED_GRAYSCALE) channels = 1;
else if (image.format == UNCOMPRESSED_GRAY_ALPHA) channels = 2;
else if (image.format == UNCOMPRESSED_R8G8B8) channels = 3;
@ -414,7 +414,7 @@ void ExportImage(Image image, const char *fileName)
imgData = (unsigned char *)GetImageData(image);
allocatedData = true;
}
#if defined(SUPPORT_FILEFORMAT_PNG)
if (IsFileExtension(fileName, ".png")) success = stbi_write_png(fileName, image.width, image.height, channels, imgData, image.width*channels);
#else
@ -439,7 +439,7 @@ void ExportImage(Image image, const char *fileName)
SaveFileData(fileName, image.data, GetPixelDataSize(image.width, image.height, image.format));
success = true;
}
if (allocatedData) RL_FREE(imgData);
#endif // SUPPORT_IMAGE_EXPORT
@ -455,7 +455,7 @@ void ExportImageAsCode(Image image, const char *fileName)
#endif
int dataSize = GetPixelDataSize(image.width, image.height, image.format);
// NOTE: Text data buffer size is estimated considering image data size in bytes
// and requiring 6 char bytes for every byte: "0x00, "
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 result = { 0 };
int bytesPerPixel = GetPixelDataSize(1, 1, image.format);
// TODO: Check rec is valid?
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.format = image.format;
result.mipmaps = 1;
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);
@ -832,7 +832,7 @@ void ImageCrop(Image *image, Rectangle crop)
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.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");
return;
@ -843,16 +843,16 @@ void ImageCrop(Image *image, Rectangle crop)
else
{
int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *croppedData = (unsigned char *)RL_MALLOC(crop.width*crop.height*bytesPerPixel);
// OPTION 1: Move cropped data line-by-line
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);
offsetSize += ((int)crop.width*bytesPerPixel);
}
/*
// 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++)
@ -1157,7 +1157,7 @@ void ImageAlphaClear(Image *image, Color color, float threshold)
{
// Security check to avoid program crash
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->format >= COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Image manipulation not supported for compressed formats");
else
@ -1167,7 +1167,7 @@ void ImageAlphaClear(Image *image, Color color, float threshold)
case UNCOMPRESSED_GRAY_ALPHA:
{
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)
{
@ -1179,7 +1179,7 @@ void ImageAlphaClear(Image *image, Color color, float threshold)
case UNCOMPRESSED_R5G5B5A1:
{
unsigned char thresholdValue = ((threshold < 0.5f)? 0 : 1);
unsigned char r = (unsigned char)(round((float)color.r*31.0f));
unsigned char g = (unsigned char)(round((float)color.g*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:
{
unsigned char thresholdValue = (unsigned char)(threshold*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 b = (unsigned char)(round((float)color.b*15.0f));
@ -1213,7 +1213,7 @@ void ImageAlphaClear(Image *image, Color color, float threshold)
case UNCOMPRESSED_R8G8B8A8:
{
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)
{
@ -1226,7 +1226,7 @@ void ImageAlphaClear(Image *image, Color color, float threshold)
} break;
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)
{
@ -1324,7 +1324,7 @@ void ImageAlphaPremultiply(Image *image)
int format = image->format;
image->data = pixels;
image->format = UNCOMPRESSED_R8G8B8A8;
ImageFormat(image, format);
}
@ -1336,15 +1336,15 @@ void ImageResize(Image *image, int newWidth, int newHeight)
{
// Security check to avoid program crash
if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return;
bool fastPath = true;
if ((image->format != UNCOMPRESSED_GRAYSCALE) && (image->format != UNCOMPRESSED_GRAY_ALPHA) && (image->format != UNCOMPRESSED_R8G8B8) && (image->format != UNCOMPRESSED_R8G8B8A8)) fastPath = true;
if (fastPath)
{
int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *output = RL_MALLOC(newWidth*newHeight*bytesPerPixel);
switch (image->format)
{
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);
int format = image->format;
RL_FREE(pixels);
RL_FREE(image->data);
@ -1410,7 +1410,7 @@ void ImageResizeNN(Image *image,int newWidth,int newHeight)
int format = image->format;
RL_FREE(image->data);
image->data = output;
image->width = newWidth;
image->height = newHeight;
@ -1427,14 +1427,14 @@ void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, i
{
// Security check to avoid program crash
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->format >= COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Image manipulation not supported for compressed formats");
else if ((newWidth != image->width) || (newHeight != image->height))
{
Rectangle srcRec = { 0, 0, image->width, image->height };
Vector2 dstPos = { offsetX, offsetY };
Vector2 dstPos = { offsetX, offsetY };
if (offsetX < 0)
{
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);
unsigned char *resizedData = (unsigned char *)RL_CALLOC(newWidth*newHeight*bytesPerPixel, 1);
// TODO: Fill resizedData with fill color (must be formatted to image->format)
int dstOffsetSize = ((int)dstPos.y*newWidth + (int)dstPos.x)*bytesPerPixel;
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);
dstOffsetSize += (newWidth*bytesPerPixel);
}
RL_FREE(image->data);
image->data = resizedData;
image->width = newWidth;
@ -1668,13 +1668,13 @@ void ImageFlipVertical(Image *image)
{
int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *flippedData = (unsigned char *)RL_MALLOC(image->width*image->height*bytesPerPixel);
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);
offsetSize += image->width*bytesPerPixel;
}
RL_FREE(image->data);
image->data = flippedData;
}
@ -1692,19 +1692,19 @@ void ImageFlipHorizontal(Image *image)
{
int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *flippedData = (unsigned char *)RL_MALLOC(image->width*image->height*bytesPerPixel);
for (int y = 0; y < image->height; y++)
{
for (int x = 0; x < image->width; x++)
{
// 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);
// 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];
}
}
RL_FREE(image->data);
image->data = flippedData;
@ -1737,7 +1737,7 @@ void ImageRotateCW(Image *image)
{
int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *rotatedData = (unsigned char *)RL_MALLOC(image->width*image->height*bytesPerPixel);
for (int y = 0; y < image->height; y++)
{
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];
}
}
RL_FREE(image->data);
image->data = rotatedData;
int width = image->width;
int height = image-> height;
image->width = height;
image->height = width;
}
@ -1769,7 +1769,7 @@ void ImageRotateCCW(Image *image)
{
int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
unsigned char *rotatedData = (unsigned char *)RL_MALLOC(image->width*image->height*bytesPerPixel);
for (int y = 0; y < image->height; y++)
{
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];
}
}
RL_FREE(image->data);
image->data = rotatedData;
int width = image->width;
int height = image-> height;
image->width = height;
image->height = width;
}
@ -1821,10 +1821,10 @@ void ImageColorTint(Image *image, Color color)
int format = image->format;
RL_FREE(image->data);
image->data = pixels;
image->format = UNCOMPRESSED_R8G8B8A8;
ImageFormat(image, format);
}
@ -1848,10 +1848,10 @@ void ImageColorInvert(Image *image)
int format = image->format;
RL_FREE(image->data);
image->data = pixels;
image->format = UNCOMPRESSED_R8G8B8A8;
ImageFormat(image, format);
}
@ -1912,10 +1912,10 @@ void ImageColorContrast(Image *image, float contrast)
int format = image->format;
RL_FREE(image->data);
image->data = pixels;
image->format = UNCOMPRESSED_R8G8B8A8;
ImageFormat(image, format);
}
@ -1956,10 +1956,10 @@ void ImageColorBrightness(Image *image, int brightness)
int format = image->format;
RL_FREE(image->data);
image->data = pixels;
image->format = UNCOMPRESSED_R8G8B8A8;
ImageFormat(image, format);
}
@ -1990,10 +1990,10 @@ void ImageColorReplace(Image *image, Color color, Color replace)
int format = image->format;
RL_FREE(image->data);
image->data = pixels;
image->format = UNCOMPRESSED_R8G8B8A8;
ImageFormat(image, format);
}
#endif // SUPPORT_IMAGE_MANIPULATION
@ -2333,24 +2333,24 @@ void ImageDrawPixel(Image *dst, int x, int y, Color color)
{
// Security check to avoid program crash
if ((dst->data == NULL) || (x < 0) || (x >= dst->width) || (y < 0) || (y >= dst->height)) return;
switch (dst->format)
{
case UNCOMPRESSED_GRAYSCALE:
case UNCOMPRESSED_GRAYSCALE:
{
// NOTE: Calculate grayscale equivalent color
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 *)dst->data)[y*dst->width + x] = gray;
((unsigned char *)dst->data)[y*dst->width + x] = gray;
} break;
case UNCOMPRESSED_GRAY_ALPHA:
case UNCOMPRESSED_GRAY_ALPHA:
{
// NOTE: Calculate grayscale equivalent color
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 *)dst->data)[(y*dst->width + x)*2] = gray;
((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 short *)dst->data)[y*dst->width + x] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b;
} break;
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 short *)dst->data)[y*dst->width + x] = (unsigned short)r << 12 | (unsigned short)g << 8 | (unsigned short)b << 4 | (unsigned short)a;
} break;
case UNCOMPRESSED_R8G8B8:
{
((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 + 2] = color.b;
} break;
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)
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;
case UNCOMPRESSED_R32G32B32:
{
// 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 };
((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 + 2] = coln.z;
((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 + 2] = coln.z;
} break;
case UNCOMPRESSED_R32G32B32A32:
{
// 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 };
((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] = coln.x;
((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 + 3] = coln.w;
@ -2603,9 +2603,9 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
Color colSrc, colDst, blend;
bool blendRequired = true;
// 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 bytesPerPixelDst = strideDst/(dst->width);
@ -2629,7 +2629,7 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
{
colSrc = GetPixelColor(pSrc, srcPtr->format);
colDst = GetPixelColor(pDst, dst->format);
// Fast path: Avoid blend if source has no alpha to blend
if (blendRequired) blend = ColorAlphaBlend(colDst, colSrc, tint);
else blend = colSrc;
@ -2797,13 +2797,13 @@ TextureCubemap LoadTextureCubemap(Image image, int layoutType)
RenderTexture2D LoadRenderTexture(int width, int height)
{
RenderTexture2D target = { 0 };
target.id = rlLoadFramebuffer(width, height); // Load an empty framebuffer
if (target.id > 0)
{
rlEnableFramebuffer(target.id);
// Create color texture (default to RGBA)
target.texture.id = rlLoadTexture(NULL, width, height, UNCOMPRESSED_R8G8B8A8, 1);
target.texture.width = width;
@ -2846,11 +2846,11 @@ void UnloadTexture(Texture2D texture)
// Unload render texture from GPU memory (VRAM)
void UnloadRenderTexture(RenderTexture2D target)
{
if (target.id > 0)
if (target.id > 0)
{
// Color texture attached to FBO is deleted
rlUnloadTexture(target.texture.id);
// NOTE: Depth texture/renderbuffer is automatically
// queried and deleted before deleting framebuffer
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
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;
if(destRec.width < tileWidth && destRec.height < tileHeight)
if (destRec.width < tileWidth && destRec.height < tileHeight)
{
// 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);
}
else if(destRec.width <= tileWidth)
else if (destRec.width <= tileWidth)
{
// Tiled vertically (one column)
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);
}
// Fit last tile
if(dy < destRec.height) {
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)destRec.width/tileWidth)*sourceRec.width, ((float)(destRec.height - dy)/tileHeight)*sourceRec.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},
(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)
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);
}
// Fit last tile
if(dx < destRec.width) {
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)(destRec.width - dx)/tileWidth)*sourceRec.width, ((float)destRec.height/tileHeight)*sourceRec.height},
if (dx < destRec.width)
{
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);
}
}
@ -3113,29 +3117,35 @@ void DrawTextureTiled(Texture2D texture, Rectangle sourceRec, Rectangle destRec,
{
// Tiled both horizontally and vertically (rows and columns)
int dx = 0;
for(;dx+tileWidth < destRec.width; dx += tileWidth) {
for (;dx+tileWidth < destRec.width; dx += tileWidth)
{
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);
}
if(dy < destRec.height) {
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, sourceRec.width, ((float)(destRec.height - dy)/tileHeight)*sourceRec.height},
if (dy < destRec.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);
}
}
// Fit last column of tiles
if(dx < destRec.width) {
if (dx < destRec.width)
{
int dy = 0;
for(;dy+tileHeight < destRec.height; dy += tileHeight) {
DrawTexturePro(texture, (Rectangle){sourceRec.x, sourceRec.y, ((float)(destRec.width - dx)/tileWidth)*sourceRec.width, sourceRec.height},
for (;dy+tileHeight < destRec.height; dy += tileHeight)
{
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);
}
// Draw final tile in the bottom right corner
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},
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},
(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 out = WHITE;
// Apply color tint to source color
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);
@ -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.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) };
}
#endif
@ -3600,7 +3610,7 @@ Color GetColor(int hexValue)
Color GetPixelColor(void *srcPtr, int format)
{
Color col = { 0 };
switch (format)
{
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.b = (unsigned char)((((unsigned short *)srcPtr)[0] & 0b0000000000011111)*255/31);
col.a = 255;
} break;
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.b = (unsigned char)(((((unsigned short *)srcPtr)[0] >> 4) & 0b0000000000001111)*255/15);
col.a = (unsigned char)((((unsigned short *)srcPtr)[0] & 0b0000000000001111)*255/15);
} 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;
@ -3636,7 +3646,7 @@ Color GetPixelColor(void *srcPtr, int format)
// TODO: case UNCOMPRESSED_R32G32B32A32: break;
default: break;
}
return col;
}
@ -3645,21 +3655,21 @@ void SetPixelColor(void *dstPtr, Color color, int format)
{
switch (format)
{
case UNCOMPRESSED_GRAYSCALE:
case UNCOMPRESSED_GRAYSCALE:
{
// NOTE: Calculate grayscale equivalent color
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 *)dstPtr)[0] = gray;
} break;
case UNCOMPRESSED_GRAY_ALPHA:
case UNCOMPRESSED_GRAY_ALPHA:
{
// NOTE: Calculate grayscale equivalent color
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 *)dstPtr)[0] = gray;
((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 short *)dstPtr)[0] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b;
} break;
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 short *)dstPtr)[0] = (unsigned short)r << 12 | (unsigned short)g << 8 | (unsigned short)b << 4 | (unsigned short)a;
} break;
case UNCOMPRESSED_R8G8B8:
{
((unsigned char *)dstPtr)[0] = color.r;
((unsigned char *)dstPtr)[1] = color.g;
((unsigned char *)dstPtr)[2] = color.b;
} break;
case UNCOMPRESSED_R8G8B8A8:
{
@ -3715,7 +3725,7 @@ void SetPixelColor(void *dstPtr, Color color, int format)
((unsigned char *)dstPtr)[1] = color.g;
((unsigned char *)dstPtr)[2] = color.b;
((unsigned char *)dstPtr)[3] = color.a;
} 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
// Most compressed formats works on 4x4 blocks,
// if texture is smaller, minimum dataSize is 8 or 16
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)
{
unsigned char *fileDataPtr = (unsigned char *)fileData;
// Required extension:
// 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(" > File format: 0x%x", ddsHeader->ddspf.fourCC);
TRACELOGD(" > File bit count: 0x%x", ddsHeader->ddspf.rgbBitCount);
fileDataPtr += sizeof(DDSHeader); // Skip header
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)
{
unsigned char *fileDataPtr = (unsigned char *)fileData;
// Required extensions:
// GL_OES_compressed_ETC1_RGB8_texture (ETC1) (OpenGL ES 2.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
{
fileDataPtr += sizeof(PKMHeader); // Skip header
// 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->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)
{
unsigned char *fileDataPtr = (unsigned char *)fileData;
// Required extensions:
// GL_OES_compressed_ETC1_RGB8_texture (ETC1)
// GL_ARB_ES3_compatibility (ETC2/EAC)
@ -4100,7 +4110,7 @@ static Image LoadKTX(const unsigned char *fileData, unsigned int fileSize)
else
{
fileDataPtr += sizeof(KTXHeader); // Move file data pointer
image.width = ktxHeader->width;
image.height = ktxHeader->height;
image.mipmaps = ktxHeader->mipmapLevels;
@ -4114,7 +4124,7 @@ static Image LoadKTX(const unsigned char *fileData, unsigned int fileSize)
int dataSize = ((int *)fileDataPtr)[0];
fileDataPtr += sizeof(int);
image.data = (unsigned char *)RL_MALLOC(dataSize*sizeof(unsigned char));
memcpy(image.data, fileDataPtr, dataSize);
@ -4156,7 +4166,7 @@ static int SaveKTX(Image image, const char *fileName)
// Calculate file dataSize required
int dataSize = sizeof(KTXHeader);
for (int i = 0, width = image.width, height = image.height; i < image.mipmaps; i++)
{
dataSize += GetPixelDataSize(width, height, image.format);
@ -4200,7 +4210,7 @@ static int SaveKTX(Image image, const char *fileName)
{
memcpy(fileDataPtr, &ktxHeader, sizeof(KTXHeader));
fileDataPtr += sizeof(KTXHeader);
int width = image.width;
int height = image.height;
int dataOffset = 0;
@ -4209,10 +4219,10 @@ static int SaveKTX(Image image, const char *fileName)
for (int i = 0; i < image.mipmaps; i++)
{
unsigned int dataSize = GetPixelDataSize(width, height, image.format);
memcpy(fileDataPtr, &dataSize, sizeof(unsigned int));
memcpy(fileDataPtr + 4, (unsigned char *)image.data + dataOffset, dataSize);
width /= 2;
height /= 2;
dataOffset += dataSize;
@ -4235,7 +4245,7 @@ static int SaveKTX(Image image, const char *fileName)
static Image LoadPVR(const unsigned char *fileData, unsigned int fileSize)
{
unsigned char *fileDataPtr = (unsigned char *)fileData;
// Required extension:
// GL_IMG_texture_compression_pvrtc
@ -4309,7 +4319,7 @@ static Image LoadPVR(const unsigned char *fileData, unsigned int fileSize)
else
{
fileDataPtr += sizeof(PVRHeaderV3); // Skip header
image.width = pvrHeader->width;
image.height = pvrHeader->height;
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)
{
unsigned char *fileDataPtr = (unsigned char *)fileData;
// Required extensions:
// GL_KHR_texture_compression_astc_hdr
// GL_KHR_texture_compression_astc_ldr
@ -4403,7 +4413,7 @@ static Image LoadASTC(const unsigned char *fileData, unsigned int fileSize)
else
{
fileDataPtr += sizeof(ASTCHeader); // Skip header
// 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.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
image.data = (unsigned char *)RL_MALLOC(dataSize*sizeof(unsigned char));
memcpy(image.data, fileDataPtr, dataSize);
if (bpp == 8) image.format = COMPRESSED_ASTC_4x4_RGBA;

+ 1
- 1
src/utils.c 查看文件

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

正在加载...
取消
保存