Merge branch 'raysan5:master' into master

This commit is contained in:
Luiz Pestana 2021-09-06 11:03:41 -03:00 committed by GitHub
commit df985ab830
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 2928 additions and 1307 deletions

View File

@ -45,9 +45,10 @@ Some people ported raylib to other languages in form of bindings or wrappers to
| raylib-ruby-ffi | 2.0 | [Ruby](https://www.ruby-lang.org/en/) | https://github.com/D3nX/raylib-ruby-ffi |
| raylib-ruby | 2.6 | [Ruby](https://www.ruby-lang.org/en/) | https://github.com/a0/raylib-ruby |
| raylib-mruby | 2.5-dev | [mruby](https://github.com/mruby/mruby) | https://github.com/lihaochen910/raylib-mruby |
| pyraylib | 3.7 | [Python](https://www.python.org/) | https://github.com/Ho011/pyraylib |
| raylib-py | 2.0 | [Python](https://www.python.org/) | https://github.com/overdev/raylib-py |
| raylib-python-cffi | 3.7 | [Python](https://www.python.org/) | https://github.com/electronstudio/raylib-python-cffi |
| raylib-py-ctbg | 2.6 | [Python](https://www.python.org/) | https://github.com/overdev/raylib-py-ctbg |
| raylib-py-ctbg | 2.6 | [Python](https://www.python.org/) | https://github.com/overdev/raylib-py-ctbg |
| jaylib | 3.7 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | https://github.com/electronstudio/jaylib/ |
| raylib-java | 2.0 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | https://github.com/XoanaIO/raylib-java |
| raylib-j | 3.5 | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | https://github.com/CreedVI/Raylib-J |
@ -82,6 +83,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
| jaylib | 3.0 | [Janet](https://janet-lang.org/) | https://github.com/janet-lang/jaylib |
| raykit | ? | [Kit](https://www.kitlang.org/) | https://github.com/Gamerfiend/raykit |
| vraylib | 3.5 | [V](https://vlang.io/) | https://github.com/waotzi/vraylib |
| raylib.v | 3.7 | [V](https://vlang.io/) | https://github.com/irishgreencitrus/raylib.v |
| ray.mod | 3.0 | [BlitzMax](https://blitzmax.org/) | https://github.com/bmx-ng/ray.mod |
| raylib-ocaml | 3.7 | [OCaml](https://ocaml.org/) | https://github.com/tjammer/raylib-ocaml |
| raylib-mosaic | 3.0 | [Mosaic](https://github.com/sal55/langs/tree/master/Mosaic) | https://github.com/pluckyporcupine/raylib-mosaic |

View File

@ -86,6 +86,8 @@ if (${PLATFORM} MATCHES "Android")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_obj_viewer.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_animation.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_first_person_maze.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/models/models_magicavoxel_loading.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_custom_uniform.c)
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_model_shader.c)

View File

@ -501,7 +501,8 @@ MODELS = \
models/models_skybox \
models/models_yaw_pitch_roll \
models/models_heightmap \
models/models_waving_cubes
models/models_waving_cubes \
models/models_magicavoxel_loading
SHADERS = \
shaders/shaders_model_shader \

View File

@ -43,7 +43,7 @@ int main(void)
// Render texture initialization, used to hold the rendering result so we can easily resize it
RenderTexture2D target = LoadRenderTexture(gameScreenWidth, gameScreenHeight);
SetTextureFilter(target.texture, FILTER_BILINEAR); // Texture scale filter to use
SetTextureFilter(target.texture, TEXTURE_FILTER_BILINEAR); // Texture scale filter to use
Color colors[10] = { 0 };
for (int i = 0; i < 10; i++) colors[i] = (Color){ GetRandomValue(100, 250), GetRandomValue(50, 150), GetRandomValue(10, 100), 255 };

View File

@ -41,7 +41,7 @@ int main(void)
Model model = LoadModel("resources/guy/guy.iqm"); // Load the animated model mesh and basic data
Texture2D texture = LoadTexture("resources/guy/guytex.png"); // Load model texture and set material
SetMaterialTexture(&model.materials[0], MAP_DIFFUSE, texture); // Set model material map texture
SetMaterialTexture(&model.materials[0], MATERIAL_MAP_DIFFUSE, texture); // Set model material map texture
Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position

View File

@ -0,0 +1,153 @@
/*******************************************************************************************
*
* raylib [models] example - magicavoxel loader and viewer
*
* This example has been created using raylib 3.8 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Example contributed by Johann Nadalutti
*
* Copyright (c) 2021 Johann Nadalutti
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
#include <string.h>
// VOX Files to load and view
#define NUM_VOX_FILES 3
const char* szVoxFiles[] = {
"resources/vox/chr_knight.vox",
"resources/vox/chr_sword.vox",
"resources/vox/monu9.vox"
};
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [models] example - magicavoxel loading");
// Load MagicaVoxel files
Model models[NUM_VOX_FILES] = { 0 };
for (int i = 0; i < NUM_VOX_FILES; i++)
{
// Load MagicaVoxel File and build model
double t0, t1;
t0 = GetTime() * 1000.0;
models[i] = LoadModel(szVoxFiles[i]);
t1 = GetTime() * 1000.0;
TraceLog(LOG_INFO, TextFormat("Vox <%s> loaded in %f ms", GetFileName(szVoxFiles[i]), t1 - t0));
//Compute model matrix
BoundingBox bb = GetModelBoundingBox(models[i]);
Vector3 center;
center.x = -(((bb.max.x - bb.min.x) / 2));
center.y = -(((bb.max.y - bb.min.y) / 2));
center.z = -(((bb.max.z - bb.min.z) / 2));
Matrix matP = MatrixTranslate(center.x, center.z, 0);
Matrix matR = MatrixRotateX(90 * DEG2RAD);
models[i].transform = MatrixMultiply(matP, matR);
}
// Define the camera to look into our 3d world
Camera camera = { { 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 };
// Model drawing position
Vector3 position = { 0.0f, 0.0f, 0.0f };
int currentModel = 0;
SetCameraMode(camera, CAMERA_ORBITAL); // Set a orbital camera mode
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
//--------------------------------------------------------------------------------------
while (!WindowShouldClose()) // Detect window close button or ESC key
{
//--------------------------------------------------------------------------------------
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera); // Update internal camera and our camera
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
{
currentModel = (currentModel + 1) % NUM_VOX_FILES; // Cycle between models
}
if (IsKeyPressed(KEY_RIGHT))
{
currentModel++;
if (currentModel >= NUM_VOX_FILES) currentModel = 0;
}
else if (IsKeyPressed(KEY_LEFT))
{
currentModel--;
if (currentModel < 0) currentModel = NUM_VOX_FILES - 1;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
//Display model
BeginMode3D(camera);
Vector3 rotAxis = { 1,0,0 };
Vector3 scale = { 1,1,1 };
DrawModelEx(models[currentModel], position, rotAxis, 0, scale, WHITE);
//DrawModelWiresEx(models[currentModel], position, rotAxis, -90.0f, scale, BLACK);
DrawGrid(10, 1.0);
EndMode3D();
//Display debug infos
DrawRectangle(30, 400, 310, 30, Fade(SKYBLUE, 0.5f));
DrawRectangleLines(30, 400, 310, 30, Fade(DARKBLUE, 0.5f));
DrawText("MOUSE LEFT BUTTON to CYCLE VOX MODELS", 40, 410, 10, BLUE);
DrawText(GetFileName(szVoxFiles[currentModel]), 100, 10, 20, DARKBLUE);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload models data (GPU VRAM)
for (int i = 0; i < NUM_VOX_FILES; i++) UnloadModel(models[i]);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -162,11 +162,11 @@ static Material LoadMaterialPBR(Color albedo, float metalness, float roughness)
mat.maps[MATERIAL_MAP_OCCLUSION].texture = LoadTexture("resources/pbr/trooper_ao.png");
// Set textures filtering for better quality
SetTextureFilter(mat.maps[MATERIAL_MAP_ALBEDO].texture, FILTER_BILINEAR);
SetTextureFilter(mat.maps[MATERIAL_MAP_NORMAL].texture, FILTER_BILINEAR);
SetTextureFilter(mat.maps[MATERIAL_MAP_METALNESS].texture, FILTER_BILINEAR);
SetTextureFilter(mat.maps[MATERIAL_MAP_ROUGHNESS].texture, FILTER_BILINEAR);
SetTextureFilter(mat.maps[MATERIAL_MAP_OCCLUSION].texture, FILTER_BILINEAR);
SetTextureFilter(mat.maps[MATERIAL_MAP_ALBEDO].texture, TEXTURE_FILTER_BILINEAR);
SetTextureFilter(mat.maps[MATERIAL_MAP_NORMAL].texture, TEXTURE_FILTER_BILINEAR);
SetTextureFilter(mat.maps[MATERIAL_MAP_METALNESS].texture, TEXTURE_FILTER_BILINEAR);
SetTextureFilter(mat.maps[MATERIAL_MAP_ROUGHNESS].texture, TEXTURE_FILTER_BILINEAR);
SetTextureFilter(mat.maps[MATERIAL_MAP_OCCLUSION].texture, TEXTURE_FILTER_BILINEAR);
// Enable sample usage in shader for assigned textures
SetShaderValue(mat.shader, GetShaderLocation(mat.shader, "albedo.useSampler"), (int[1]){ 1 }, SHADER_UNIFORM_INT);

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -31,7 +31,7 @@ int main(void)
// Same as: Wave wave = LoadWave("sound.wav");
Wave wave = {
.data = AUDIO_DATA,
.sampleCount = AUDIO_SAMPLE_COUNT,
.frameCount = AUDIO_FRAME_COUNT,
.sampleRate = AUDIO_SAMPLE_RATE,
.sampleSize = AUDIO_SAMPLE_SIZE,
.channels = AUDIO_CHANNELS

View File

@ -11,7 +11,7 @@
//////////////////////////////////////////////////////////////////////////////////
// Wave data information
#define AUDIO_SAMPLE_COUNT 24367
#define AUDIO_FRAME_COUNT 24367
#define AUDIO_SAMPLE_RATE 44100
#define AUDIO_SAMPLE_SIZE 32
#define AUDIO_CHANNELS 1

View File

@ -63,7 +63,7 @@ int main(void)
DrawTextureEx(torus, (Vector2){ 544, 230 }, 0.0, outlineScale, WHITE);
EndShaderMode();
DrawText("Shader-based shdrOutlines for textures", 190, 200, 20, LIGHTGRAY);
DrawText("Shader-based outlines for textures", 190, 200, 20, LIGHTGRAY);
DrawFPS(710, 10);

View File

@ -454,16 +454,16 @@ void DrawTextCodepoint3D(Font font, int codepoint, Vector3 position, float fontS
// Character destination rectangle on screen
// NOTE: We consider charsPadding on drawing
position.x += (float)(font.chars[index].offsetX - font.charsPadding)/(float)font.baseSize*scale;
position.z += (float)(font.chars[index].offsetY - font.charsPadding)/(float)font.baseSize*scale;
position.x += (float)(font.glyphs[index].offsetX - font.glyphPadding)/(float)font.baseSize*scale;
position.z += (float)(font.glyphs[index].offsetY - font.glyphPadding)/(float)font.baseSize*scale;
// Character source rectangle from font texture atlas
// NOTE: We consider chars padding when drawing, it could be required for outline/glow shader effects
Rectangle srcRec = { font.recs[index].x - (float)font.charsPadding, font.recs[index].y - (float)font.charsPadding,
font.recs[index].width + 2.0f*font.charsPadding, font.recs[index].height + 2.0f*font.charsPadding };
Rectangle srcRec = { font.recs[index].x - (float)font.glyphPadding, font.recs[index].y - (float)font.glyphPadding,
font.recs[index].width + 2.0f*font.glyphPadding, font.recs[index].height + 2.0f*font.glyphPadding };
float width = (float)(font.recs[index].width + 2.0f*font.charsPadding)/(float)font.baseSize*scale;
float height = (float)(font.recs[index].height + 2.0f*font.charsPadding)/(float)font.baseSize*scale;
float width = (float)(font.recs[index].width + 2.0f*font.glyphPadding)/(float)font.baseSize*scale;
float height = (float)(font.recs[index].height + 2.0f*font.glyphPadding)/(float)font.baseSize*scale;
if (font.texture.id > 0)
{
@ -477,16 +477,11 @@ void DrawTextCodepoint3D(Font font, int codepoint, Vector3 position, float fontS
const float tw = (srcRec.x+srcRec.width)/font.texture.width;
const float th = (srcRec.y+srcRec.height)/font.texture.height;
if (SHOW_LETTER_BOUNDRY)
DrawCubeWiresV((Vector3){ position.x + width/2, position.y, position.z + height/2}, (Vector3){ width, LETTER_BOUNDRY_SIZE, height }, LETTER_BOUNDRY_COLOR);
if (SHOW_LETTER_BOUNDRY) DrawCubeWiresV((Vector3){ position.x + width/2, position.y, position.z + height/2}, (Vector3){ width, LETTER_BOUNDRY_SIZE, height }, LETTER_BOUNDRY_COLOR);
#if defined(RAYLIB_NEW_RLGL)
rlCheckRenderBatchLimit(4 + 4*backface);
rlSetTexture(font.texture.id);
#else
if (rlCheckBufferLimit(4 + 4*backface)) rlglDraw();
rlEnableTexture(font.texture.id);
#endif
rlPushMatrix();
rlTranslatef(position.x, position.y, position.z);
@ -512,11 +507,7 @@ void DrawTextCodepoint3D(Font font, int codepoint, Vector3 position, float fontS
rlEnd();
rlPopMatrix();
#if defined(RAYLIB_NEW_RLGL)
rlSetTexture(0);
#else
rlDisableTexture();
#endif
}
}
@ -554,8 +545,8 @@ void DrawText3D(Font font, const char *text, Vector3 position, float fontSize, f
DrawTextCodepoint3D(font, codepoint, (Vector3){ position.x + textOffsetX, position.y, position.z + textOffsetY }, fontSize, backface, tint);
}
if (font.chars[index].advanceX == 0) textOffsetX += (float)(font.recs[index].width + fontSpacing)/(float)font.baseSize*scale;
else textOffsetX += (float)(font.chars[index].advanceX + fontSpacing)/(float)font.baseSize*scale;
if (font.glyphs[index].advanceX == 0) textOffsetX += (float)(font.recs[index].width + fontSpacing)/(float)font.baseSize*scale;
else textOffsetX += (float)(font.glyphs[index].advanceX + fontSpacing)/(float)font.baseSize*scale;
}
i += codepointByteCount; // Move text bytes counter to next codepoint
@ -592,8 +583,8 @@ Vector3 MeasureText3D(Font font, const char* text, float fontSize, float fontSpa
if (letter != '\n')
{
if (font.chars[index].advanceX != 0) textWidth += (font.chars[index].advanceX+fontSpacing)/(float)font.baseSize*scale;
else textWidth += (font.recs[index].width + font.chars[index].offsetX)/(float)font.baseSize*scale;
if (font.glyphs[index].advanceX != 0) textWidth += (font.glyphs[index].advanceX+fontSpacing)/(float)font.baseSize*scale;
else textWidth += (font.recs[index].width + font.glyphs[index].offsetX)/(float)font.baseSize*scale;
}
else
{
@ -670,8 +661,8 @@ void DrawTextWave3D(Font font, const char *text, Vector3 position, float fontSiz
DrawTextCodepoint3D(font, codepoint, (Vector3){ pos.x + textOffsetX, pos.y, pos.z + textOffsetY }, fontSize, backface, tint);
}
if (font.chars[index].advanceX == 0) textOffsetX += (float)(font.recs[index].width + fontSpacing)/(float)font.baseSize*scale;
else textOffsetX += (float)(font.chars[index].advanceX + fontSpacing)/(float)font.baseSize*scale;
if (font.glyphs[index].advanceX == 0) textOffsetX += (float)(font.recs[index].width + fontSpacing)/(float)font.baseSize*scale;
else textOffsetX += (float)(font.glyphs[index].advanceX + fontSpacing)/(float)font.baseSize*scale;
}
i += codepointByteCount; // Move text bytes counter to next codepoint
@ -714,8 +705,8 @@ Vector3 MeasureTextWave3D(Font font, const char* text, float fontSize, float fon
}
else
{
if (font.chars[index].advanceX != 0) textWidth += (font.chars[index].advanceX+fontSpacing)/(float)font.baseSize*scale;
else textWidth += (font.recs[index].width + font.chars[index].offsetX)/(float)font.baseSize*scale;
if (font.glyphs[index].advanceX != 0) textWidth += (font.glyphs[index].advanceX+fontSpacing)/(float)font.baseSize*scale;
else textWidth += (font.recs[index].width + font.glyphs[index].offsetX)/(float)font.baseSize*scale;
}
}
else

View File

@ -39,24 +39,24 @@ int main(void)
// Default font generation from TTF font
Font fontDefault = { 0 };
fontDefault.baseSize = 16;
fontDefault.charsCount = 95;
fontDefault.glyphCount = 95;
// Loading font data from memory data
// Parameters > font size: 16, no chars array provided (0), chars count: 95 (autogenerate chars array)
fontDefault.chars = LoadFontData(fileData, fileSize, 16, 0, 95, FONT_DEFAULT);
// Parameters > chars count: 95, font size: 16, chars padding in image: 4 px, pack method: 0 (default)
Image atlas = GenImageFontAtlas(fontDefault.chars, &fontDefault.recs, 95, 16, 4, 0);
// Parameters > font size: 16, no glyphs array provided (0), glyphs count: 95 (autogenerate chars array)
fontDefault.glyphs = LoadFontData(fileData, fileSize, 16, 0, 95, FONT_DEFAULT);
// Parameters > glyphs count: 95, font size: 16, glyphs padding in image: 4 px, pack method: 0 (default)
Image atlas = GenImageFontAtlas(fontDefault.glyphs, &fontDefault.recs, 95, 16, 4, 0);
fontDefault.texture = LoadTextureFromImage(atlas);
UnloadImage(atlas);
// SDF font generation from TTF font
Font fontSDF = { 0 };
fontSDF.baseSize = 16;
fontSDF.charsCount = 95;
// Parameters > font size: 16, no chars array provided (0), chars count: 0 (defaults to 95)
fontSDF.chars = LoadFontData(fileData, fileSize, 16, 0, 0, FONT_SDF);
// Parameters > chars count: 95, font size: 16, chars padding in image: 0 px, pack method: 1 (Skyline algorythm)
atlas = GenImageFontAtlas(fontSDF.chars, &fontSDF.recs, 95, 16, 0, 1);
fontSDF.glyphCount = 95;
// Parameters > font size: 16, no glyphs array provided (0), glyphs count: 0 (defaults to 95)
fontSDF.glyphs = LoadFontData(fileData, fileSize, 16, 0, 0, FONT_SDF);
// Parameters > glyphs count: 95, font size: 16, glyphs padding in image: 0 px, pack method: 1 (Skyline algorythm)
atlas = GenImageFontAtlas(fontSDF.glyphs, &fontSDF.recs, 95, 16, 0, 1);
fontSDF.texture = LoadTextureFromImage(atlas);
UnloadImage(atlas);
@ -64,7 +64,7 @@ int main(void)
// Load SDF required shader (we use default vertex shader)
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/sdf.fs", GLSL_VERSION));
SetTextureFilter(fontSDF.texture, FILTER_BILINEAR); // Required for SDF font
SetTextureFilter(fontSDF.texture, TEXTURE_FILTER_BILINEAR); // Required for SDF font
Vector2 fontPosition = { 40, screenHeight/2.0f - 50 };
Vector2 textSize = { 0.0f, 0.0f };

View File

@ -13,8 +13,8 @@
#include "raylib.h"
static void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); // Draw text using font inside rectangle limits
static void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint); // Draw text using font inside rectangle limits with support for text selection
static void DrawTextBoxed(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); // Draw text using font inside rectangle limits
static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint); // Draw text using font inside rectangle limits with support for text selection
// Main entry point
int main(void)
@ -92,14 +92,12 @@ tempor incididunt ut labore et dolore magna aliqua. Nec ullamcorper sit amet ris
ClearBackground(RAYWHITE);
DrawRectangleLinesEx(container, 3, borderColor); // Draw container border
DrawRectangleLinesEx(container, 3, borderColor); // Draw container border
// Draw text in container (add some padding)
DrawTextRec(font, text,
(Rectangle){ container.x + 4, container.y + 4, container.width - 4, container.height - 4 },
20.0f, 2.0f, wordWrap, GRAY);
DrawTextBoxed(font, text, (Rectangle){ container.x + 4, container.y + 4, container.width - 4, container.height - 4 }, 20.0f, 2.0f, wordWrap, GRAY);
DrawRectangleRec(resizer, borderColor); // Draw the resize box
DrawRectangleRec(resizer, borderColor); // Draw the resize box
// Draw bottom info
DrawRectangle(0, screenHeight - 54, screenWidth, 54, GRAY);
@ -130,13 +128,13 @@ tempor incididunt ut labore et dolore magna aliqua. Nec ullamcorper sit amet ris
//--------------------------------------------------------------------------------------
// Draw text using font inside rectangle limits
static void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint)
static void DrawTextBoxed(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint)
{
DrawTextRecEx(font, text, rec, fontSize, spacing, wordWrap, tint, 0, 0, WHITE, WHITE);
DrawTextBoxedSelectable(font, text, rec, fontSize, spacing, wordWrap, tint, 0, 0, WHITE, WHITE);
}
// Draw text using font inside rectangle limits with support for text selection
static void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint)
static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint)
{
int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop
@ -168,7 +166,7 @@ static void DrawTextRecEx(Font font, const char *text, Rectangle rec, float font
float glyphWidth = 0;
if (codepoint != '\n')
{
glyphWidth = (font.chars[index].advanceX == 0) ? font.recs[index].width*scaleFactor : font.chars[index].advanceX*scaleFactor;
glyphWidth = (font.glyphs[index].advanceX == 0) ? font.recs[index].width*scaleFactor : font.glyphs[index].advanceX*scaleFactor;
if (i + 1 < length) glyphWidth = glyphWidth + spacing;
}

View File

@ -133,8 +133,8 @@ struct {
//--------------------------------------------------------------------------------------
static void RandomizeEmoji(void); // Fills the emoji array with random emojis
static void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); // Draw text using font inside rectangle limits
static void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint); // Draw text using font inside rectangle limits with support for text selection
static void DrawTextBoxed(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); // Draw text using font inside rectangle limits
static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint); // Draw text using font inside rectangle limits with support for text selection
//--------------------------------------------------------------------------------------
// Global variables
@ -273,12 +273,12 @@ int main(int argc, char **argv)
// Draw the main text message
Rectangle textRect = { msgRect.x + horizontalPadding/2, msgRect.y + verticalPadding/2, msgRect.width - horizontalPadding, msgRect.height };
DrawTextRec(*font, messages[message].text, textRect, (float)font->baseSize, 1.0f, true, WHITE);
DrawTextBoxed(*font, messages[message].text, textRect, (float)font->baseSize, 1.0f, true, WHITE);
// Draw the info text below the main message
int size = (int)strlen(messages[message].text);
int len = GetCodepointsCount(messages[message].text);
const char *info = TextFormat("%s %u characters %i bytes", messages[message].language, len, size);
int length = GetCodepointCount(messages[message].text);
const char *info = TextFormat("%s %u characters %i bytes", messages[message].language, length, size);
sz = MeasureTextEx(GetFontDefault(), info, 10, 1.0f);
Vector2 pos = { textRect.x + textRect.width - sz.x, msgRect.y + msgRect.height - sz.y - 2 };
DrawText(info, (int)pos.x, (int)pos.y, 10, RAYWHITE);
@ -329,13 +329,13 @@ static void RandomizeEmoji(void)
//--------------------------------------------------------------------------------------
// Draw text using font inside rectangle limits
static void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint)
static void DrawTextBoxed(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint)
{
DrawTextRecEx(font, text, rec, fontSize, spacing, wordWrap, tint, 0, 0, WHITE, WHITE);
DrawTextBoxedSelectable(font, text, rec, fontSize, spacing, wordWrap, tint, 0, 0, WHITE, WHITE);
}
// Draw text using font inside rectangle limits with support for text selection
static void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint)
static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint)
{
int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop
@ -367,7 +367,7 @@ static void DrawTextRecEx(Font font, const char *text, Rectangle rec, float font
float glyphWidth = 0;
if (codepoint != '\n')
{
glyphWidth = (font.chars[index].advanceX == 0) ? font.recs[index].width*scaleFactor : font.chars[index].advanceX*scaleFactor;
glyphWidth = (font.glyphs[index].advanceX == 0) ? font.recs[index].width*scaleFactor : font.glyphs[index].advanceX*scaleFactor;
if (i + 1 < length) glyphWidth = glyphWidth + spacing;
}

View File

@ -26,8 +26,8 @@ int main(void)
Image image = LoadImage("resources/raylib_logo.png"); // Loaded in CPU memory (RAM)
Texture2D texture = LoadTextureFromImage(image); // Image converted to texture, GPU memory (VRAM)
UnloadImage(image); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//---------------------------------------------------------------------------------------

View File

@ -2505,7 +2505,7 @@ Function 308: GetColor() (1 input parameters)
Name: GetColor
Return type: Color
Description: Get Color structure from hexadecimal value
Param[1]: hexValue (type: int)
Param[1]: hexValue (type: unsigned int)
Function 309: GetPixelColor() (2 input parameters)
Name: GetPixelColor
Return type: Color

View File

@ -389,7 +389,7 @@ RLAPI Vector3 ColorToHSV(Color color); // R
RLAPI Color ColorFromHSV(float hue, float saturation, float value); // Returns a Color from HSV values
RLAPI Color ColorAlpha(Color color, float alpha); // Returns color with alpha applied, alpha goes from 0.0f to 1.0f
RLAPI Color ColorAlphaBlend(Color dst, Color src, Color tint); // Returns src alpha-blended into dst color with tint
RLAPI Color GetColor(int hexValue); // Get Color structure from hexadecimal value
RLAPI Color GetColor(unsigned int hexValue); // Get Color structure from hexadecimal value
RLAPI Color GetPixelColor(void *srcPtr, int format); // Get Color from a source pixel pointer of certain format
RLAPI void SetPixelColor(void *dstPtr, Color color, int format); // Set color formatted into destination pixel pointer
RLAPI int GetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes for certain format

View File

@ -0,0 +1,387 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug.DLL|Win32">
<Configuration>Debug.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug.DLL|x64">
<Configuration>Debug.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|Win32">
<Configuration>Release.DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release.DLL|x64">
<Configuration>Release.DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{2F1B955B-275E-4D8E-8864-06FEC44D7912}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>models_mesh_magicavoxel_loading</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>models_mesh_magicavoxel_loading</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
<Message>Copy Debug DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
<RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command>
</PostBuildEvent>
<PostBuildEvent>
<Message>Copy Release DLL to output directory</Message>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\raylib\raylib.vcxproj">
<Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\examples\models\models_magicavoxel_loading.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -275,6 +275,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rlgl_standalone", "examples
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_split_screen", "examples\core_split_screen.vcxproj", "{946A1700-C7AA-46F0-AEF2-67C98B5722AC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "models_mesh_magicavoxel_loading", "examples\models_mesh_magicavoxel_loading.vcxproj", "{2F1B955B-275E-4D8E-8864-06FEC44D7912}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug.DLL|x64 = Debug.DLL|x64
@ -2283,6 +2285,22 @@ Global
{946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x64.Build.0 = Release|x64
{946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x86.ActiveCfg = Release|Win32
{946A1700-C7AA-46F0-AEF2-67C98B5722AC}.Release|x86.Build.0 = Release|Win32
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|x64.ActiveCfg = Debug|x64
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|x64.Build.0 = Debug|x64
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|x86.ActiveCfg = Debug|Win32
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Debug|x86.Build.0 = Debug|Win32
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|x64.Build.0 = Release.DLL|x64
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release.DLL|x86.Build.0 = Release.DLL|Win32
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|x64.ActiveCfg = Release|x64
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|x64.Build.0 = Release|x64
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|x86.ActiveCfg = Release|Win32
{2F1B955B-275E-4D8E-8864-06FEC44D7912}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -2422,6 +2440,7 @@ Global
{6237BEDE-BAAA-4A06-9C5E-8089BAA14C8B} = {E9D708A5-9C1F-4B84-A795-C5F191801762}
{C8765523-58F8-4C8E-9914-693396F6F0FF} = {E9D708A5-9C1F-4B84-A795-C5F191801762}
{946A1700-C7AA-46F0-AEF2-67C98B5722AC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
{2F1B955B-275E-4D8E-8864-06FEC44D7912} = {AF5BEC5C-1F2B-4DA8-B12D-D09FE569237C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}

View File

@ -195,16 +195,16 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
ANDROID_SYSROOT ?= $(ANDROID_TOOLCHAIN)/sysroot
ifeq ($(ANDROID_ARCH),arm)
ANDROID_ARCH_NAME = armeabi-v7a
ANDROID_COMPILER_ARCH = armv7a
endif
ifeq ($(ANDROID_ARCH),arm64)
ANDROID_ARCH_NAME = arm64-v8a
ANDROID_COMPILER_ARCH = aarch64
endif
ifeq ($(ANDROID_ARCH),x86)
ANDROID_ARCH_NAME = i686
ANDROID_COMPILER_ARCH = i686
endif
ifeq ($(ANDROID_ARCH),x86_64)
ANDROID_ARCH_NAME = x86_64
ANDROID_COMPILER_ARCH = x86_64
endif
endif
@ -266,22 +266,9 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
endif
ifeq ($(PLATFORM),PLATFORM_ANDROID)
# Android toolchain (must be provided for desired architecture and compiler)
ifeq ($(ANDROID_ARCH),arm)
CC = $(ANDROID_TOOLCHAIN)/bin/armv7a-linux-androideabi$(ANDROID_API_VERSION)-clang
AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
endif
ifeq ($(ANDROID_ARCH),arm64)
CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android$(ANDROID_API_VERSION)-clang
AR = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-ar
endif
ifeq ($(ANDROID_ARCH),x86)
CC = $(ANDROID_TOOLCHAIN)/bin/i686-linux-android$(ANDROID_API_VERSION)-clang
AR = $(ANDROID_TOOLCHAIN)/bin/i686-linux-android-ar
endif
ifeq ($(ANDROID_ARCH),x86_64)
CC = $(ANDROID_TOOLCHAIN)/bin/x86_64-linux-android$(ANDROID_API_VERSION)-clang
AR = $(ANDROID_TOOLCHAIN)/bin/x86_64-linux-android-ar
endif
CC = $(ANDROID_TOOLCHAIN)/bin/$(ANDROID_COMPILER_ARCH)-linux-androideabi$(ANDROID_API_VERSION)-clang
# It seems from Android NDK r22 onwards we need to use llvm-ar
AR = $(ANDROID_TOOLCHAIN)/bin/llvm-ar
endif
ifeq ($(PLATFORM),PLATFORM_NX)
ifeq ($(strip $(DEVKITPRO)),)
@ -365,10 +352,10 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
ifeq ($(ANDROID_ARCH),arm64)
CFLAGS += -target aarch64 -mfix-cortex-a53-835769
endif
ifeq ($(ANDROID_ARCH), x86)
ifeq ($(ANDROID_ARCH),x86)
CFLAGS += -march=i686
endif
ifeq ($(ANDROID_ARCH), x86_64)
ifeq ($(ANDROID_ARCH),x86_64)
CFLAGS += -march=x86-64
endif
# Compilation functions attributes options

View File

@ -186,6 +186,7 @@
#define SUPPORT_FILEFORMAT_MTL 1
#define SUPPORT_FILEFORMAT_IQM 1
#define SUPPORT_FILEFORMAT_GLTF 1
#define SUPPORT_FILEFORMAT_VOX 1
// Support procedural mesh generation functions, uses external par_shapes.h library
// NOTE: Some generated meshes DO NOT include generated texture coordinates
#define SUPPORT_MESH_GENERATION 1

View File

@ -403,7 +403,7 @@ typedef struct CoreData {
Matrix screenScale; // Matrix to scale screen (framebuffer rendering)
char **dropFilesPath; // Store dropped files paths as strings
int dropFilesCount; // Count dropped files strings
int dropFileCount; // Count dropped files strings
} Window;
#if defined(PLATFORM_ANDROID)
@ -429,7 +429,7 @@ typedef struct CoreData {
int keyPressedQueue[MAX_KEY_PRESSED_QUEUE]; // Input keys queue
int keyPressedQueueCount; // Input keys queue count
int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue
int charPressedQueue[MAX_CHAR_PRESSED_QUEUE]; // Input characters queue (unicode)
int charPressedQueueCount; // Input characters queue count
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
@ -502,14 +502,14 @@ typedef struct CoreData {
static CoreData CORE = { 0 }; // Global CORE state context
static char **dirFilesPath = NULL; // Store directory files paths as strings
static int dirFilesCount = 0; // Count directory files strings
static int dirFileCount = 0; // Count directory files strings
#if defined(SUPPORT_SCREEN_CAPTURE)
static int screenshotCounter = 0; // Screenshots counter
#endif
#if defined(SUPPORT_GIF_RECORDING)
static int gifFramesCounter = 0; // GIF frames counter
static int gifFrameCounter = 0; // GIF frames counter
static bool gifRecording = false; // GIF recording state
static MsfGifState gifState = { 0 }; // MSGIF context state
#endif
@ -1963,10 +1963,10 @@ void EndDrawing(void)
if (gifRecording)
{
#define GIF_RECORD_FRAMERATE 10
gifFramesCounter++;
gifFrameCounter++;
// NOTE: We record one gif frame every 10 game frames
if ((gifFramesCounter%GIF_RECORD_FRAMERATE) == 0)
if ((gifFrameCounter%GIF_RECORD_FRAMERATE) == 0)
{
// Get image data for the current frame (from backbuffer)
// NOTE: This process is quite slow... :(
@ -1976,7 +1976,7 @@ void EndDrawing(void)
RL_FREE(screenData); // Free image data
}
if (((gifFramesCounter/15)%2) == 1)
if (((gifFrameCounter/15)%2) == 1)
{
DrawCircle(30, CORE.Window.screen.height - 20, 10, MAROON);
DrawText("GIF RECORDING", 50, CORE.Window.screen.height - 25, 10, RED);
@ -1990,9 +1990,9 @@ void EndDrawing(void)
// Draw record/play indicator
if (eventsRecording)
{
gifFramesCounter++;
gifFrameCounter++;
if (((gifFramesCounter/15)%2) == 1)
if (((gifFrameCounter/15)%2) == 1)
{
DrawCircle(30, CORE.Window.screen.height - 20, 10, MAROON);
DrawText("EVENTS RECORDING", 50, CORE.Window.screen.height - 25, 10, RED);
@ -2002,9 +2002,9 @@ void EndDrawing(void)
}
else if (eventsPlaying)
{
gifFramesCounter++;
gifFrameCounter++;
if (((gifFramesCounter/15)%2) == 1)
if (((gifFrameCounter/15)%2) == 1)
{
DrawCircle(30, CORE.Window.screen.height - 20, 10, LIME);
DrawText("EVENTS PLAYING", 50, CORE.Window.screen.height - 25, 10, GREEN);
@ -2804,9 +2804,9 @@ const char *GetFileNameWithoutExt(const char *filePath)
if (filePath != NULL) strcpy(fileName, GetFileName(filePath)); // Get filename with extension
int len = (int)strlen(fileName);
int size = (int)strlen(fileName); // Get size in bytes
for (int i = 0; (i < len) && (i < MAX_FILENAMEWITHOUTEXT_LENGTH); i++)
for (int i = 0; (i < size) && (i < MAX_FILENAMEWITHOUTEXT_LENGTH); i++)
{
if (fileName[i] == '.')
{
@ -2932,8 +2932,8 @@ char **GetDirectoryFiles(const char *dirPath, int *fileCount)
}
else TRACELOG(LOG_WARNING, "FILEIO: Failed to open requested directory"); // Maybe it's a file...
dirFilesCount = counter;
*fileCount = dirFilesCount;
dirFileCount = counter;
*fileCount = dirFileCount;
return dirFilesPath;
}
@ -2941,14 +2941,14 @@ char **GetDirectoryFiles(const char *dirPath, int *fileCount)
// Clear directory files paths buffers
void ClearDirectoryFiles(void)
{
if (dirFilesCount > 0)
if (dirFileCount > 0)
{
for (int i = 0; i < MAX_DIRECTORY_FILES; i++) RL_FREE(dirFilesPath[i]);
RL_FREE(dirFilesPath);
}
dirFilesCount = 0;
dirFileCount = 0;
}
// Change working directory, returns true on success
@ -2964,27 +2964,27 @@ bool ChangeDirectory(const char *dir)
// Check if a file has been dropped into window
bool IsFileDropped(void)
{
if (CORE.Window.dropFilesCount > 0) return true;
if (CORE.Window.dropFileCount > 0) return true;
else return false;
}
// Get dropped files names
char **GetDroppedFiles(int *count)
{
*count = CORE.Window.dropFilesCount;
*count = CORE.Window.dropFileCount;
return CORE.Window.dropFilesPath;
}
// Clear dropped files paths buffer
void ClearDroppedFiles(void)
{
if (CORE.Window.dropFilesCount > 0)
if (CORE.Window.dropFileCount > 0)
{
for (int i = 0; i < CORE.Window.dropFilesCount; i++) RL_FREE(CORE.Window.dropFilesPath[i]);
for (int i = 0; i < CORE.Window.dropFileCount; i++) RL_FREE(CORE.Window.dropFilesPath[i]);
RL_FREE(CORE.Window.dropFilesPath);
CORE.Window.dropFilesCount = 0;
CORE.Window.dropFileCount = 0;
}
}
@ -5175,7 +5175,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
else
{
gifRecording = true;
gifFramesCounter = 0;
gifFrameCounter = 0;
msf_gif_begin(&gifState, CORE.Window.screen.width, CORE.Window.screen.height);
screenshotCounter++;
@ -5312,7 +5312,8 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
// GLFW3 Srolling Callback, runs on mouse wheel
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset)
{
CORE.Input.Mouse.currentWheelMove = (float)yoffset;
if (xoffset != 0.0) CORE.Input.Mouse.currentWheelMove = (float)xoffset;
else CORE.Input.Mouse.currentWheelMove = (float)yoffset;
}
// GLFW3 CursorEnter Callback, when cursor enters the window
@ -5337,7 +5338,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
strcpy(CORE.Window.dropFilesPath[i], paths[i]);
}
CORE.Window.dropFilesCount = count;
CORE.Window.dropFileCount = count;
}
#endif
@ -5397,7 +5398,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
/*
if (assetsReloadRequired)
{
for (int i = 0; i < assetsCount; i++)
for (int i = 0; i < assetCount; i++)
{
// TODO: Unload old asset if required

768
src/external/vox_loader.h vendored Normal file
View File

@ -0,0 +1,768 @@
/*
The MIT License (MIT)
Copyright (c) 2021 Johann Nadalutti.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
vox_loader - v1.00
no warranty implied; use at your own risk
Do this:
#define VOX_LOADER_INCLUDE__H
before you include this file in* one* C or C++ file to create the implementation.
// i.e. it should look like this:
#include ...
#include ...
#include ...
#define VOX_LOADER_INCLUDE__H
#include "magicavoxel_loader.h"
revision history:
1.00 (2021-09-03) first released version
*/
#ifndef VOX_LOADER_H
#define VOX_LOADER_H
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
#define VOX_SUCCESS (0)
#define VOX_ERROR_FILE_NOT_FOUND (-1)
#define VOX_ERROR_INVALID_FORMAT (-2)
#define VOX_ERROR_FILE_VERSION_TOO_OLD (-3)
typedef struct
{
int* array;
int used, size;
} ArrayInt;
typedef struct
{
Vector3* array;
int used, size;
} ArrayVector3;
typedef struct
{
Color* array;
int used, size;
} ArrayColor;
typedef struct
{
unsigned short* array;
int used, size;
} ArrayUShort;
// A chunk that contain voxels
typedef struct
{
unsigned char* m_array; //If Sparse != null
int arraySize; //Size for m_array in bytes (DEBUG ONLY)
} CubeChunk3D;
// Array for voxels
// Array is divised into chunks of CHUNKSIZE*CHUNKSIZE*CHUNKSIZE voxels size
typedef struct
{
//Array size in voxels
int sizeX;
int sizeY;
int sizeZ;
//Chunks size into array (array is divised into chunks)
int chunksSizeX;
int chunksSizeY;
int chunksSizeZ;
//Chunks array
CubeChunk3D* m_arrayChunks;
int arrayChunksSize; //Size for m_arrayChunks in bytes (DEBUG ONLY)
int ChunkFlattenOffset;
int chunksAllocated;
int chunksTotal;
//Arrays for mesh build
ArrayVector3 vertices;
ArrayUShort indices;
ArrayColor colors;
//Palette for voxels
Color palette[256];
} VoxArray3D;
// Functions
extern int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray);
extern void Vox_FreeArrays(VoxArray3D* voxarray);
#ifdef __cplusplus
}
#endif
//// end header file /////////////////////////////////////////////////////
#endif // VOX_LOADER_H
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
// Implementation
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
#ifdef VOX_LOADER_IMPLEMENTATION
/////////////////////////////////////////////////////////////////////////////////////////////
// ArrayInt helper
/////////////////////////////////////////////////////////////////////////////////////////////
void initArrayInt(ArrayInt* a, int initialSize)
{
a->array = MemAlloc(initialSize * sizeof(int));
a->used = 0;
a->size = initialSize;
}
void insertArrayInt(ArrayInt* a, int element)
{
if (a->used == a->size)
{
a->size *= 2;
a->array = MemRealloc(a->array, a->size * sizeof(int));
}
a->array[a->used++] = element;
}
void freeArrayInt(ArrayInt* a)
{
MemFree(a->array);
a->array = NULL;
a->used = a->size = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// ArrayUShort helper
/////////////////////////////////////////////////////////////////////////////////////////////
void initArrayUShort(ArrayUShort* a, int initialSize)
{
a->array = MemAlloc(initialSize * sizeof(unsigned short));
a->used = 0;
a->size = initialSize;
}
void insertArrayUShort(ArrayUShort* a, unsigned short element)
{
if (a->used == a->size)
{
a->size *= 2;
a->array = MemRealloc(a->array, a->size * sizeof(unsigned short));
}
a->array[a->used++] = element;
}
void freeArrayUShort(ArrayUShort* a)
{
MemFree(a->array);
a->array = NULL;
a->used = a->size = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// ArrayVector3 helper
/////////////////////////////////////////////////////////////////////////////////////////////
void initArrayVector3(ArrayVector3* a, int initialSize)
{
a->array = MemAlloc(initialSize * sizeof(Vector3));
a->used = 0;
a->size = initialSize;
}
void insertArrayVector3(ArrayVector3* a, Vector3 element)
{
if (a->used == a->size)
{
a->size *= 2;
a->array = MemRealloc(a->array, a->size * sizeof(Vector3));
}
a->array[a->used++] = element;
}
void freeArrayVector3(ArrayVector3* a)
{
MemFree(a->array);
a->array = NULL;
a->used = a->size = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// ArrayColor helper
/////////////////////////////////////////////////////////////////////////////////////////////
void initArrayColor(ArrayColor* a, int initialSize)
{
a->array = MemAlloc(initialSize * sizeof(Color));
a->used = 0;
a->size = initialSize;
}
void insertArrayColor(ArrayColor* a, Color element)
{
if (a->used == a->size)
{
a->size *= 2;
a->array = MemRealloc(a->array, a->size * sizeof(Color));
}
a->array[a->used++] = element;
}
void freeArrayColor(ArrayColor* a)
{
MemFree(a->array);
a->array = NULL;
a->used = a->size = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// Vox Loader
/////////////////////////////////////////////////////////////////////////////////////////////
#define CHUNKSIZE 16 // chunk size (CHUNKSIZE*CHUNKSIZE*CHUNKSIZE) in voxels
#define CHUNKSIZE_OPSHIFT 4 // 1<<4=16 -> Warning depend of CHUNKSIZE
#define CHUNK_FLATTENOFFSET_OPSHIFT 8 //Warning depend of CHUNKSIZE
//
// used right handed system and CCW face
//
// indexes for voxelcoords, per face orientation
//
//# Y
//# |
//# o----X
//# /
//# Z 2------------3
//# /| /|
//# 6------------7 |
//# | | | |
//# |0 ----------|- 1
//# |/ |/
//# 4------------5
//
// CCW
const int fv[6][4] = {
{0, 2, 6, 4 }, //-X
{5, 7, 3, 1 }, //+X
{0, 4, 5, 1 }, //-y
{6, 2, 3, 7 }, //+y
{1, 3, 2, 0 }, //-Z
{4, 6, 7, 5 } };//+Z
const Vector3 SolidVertex[] = {
{0, 0, 0}, //0
{1, 0, 0}, //1
{0, 1, 0}, //2
{1, 1, 0}, //3
{0, 0, 1}, //4
{1, 0, 1}, //5
{0, 1, 1}, //6
{1, 1, 1} }; //7
// Allocated VoxArray3D size
void Vox_AllocArray(VoxArray3D* voxarray, int _sx, int _sy, int _sz)
{
int sx = _sx + ((CHUNKSIZE - (_sx % CHUNKSIZE)) % CHUNKSIZE);
int sy = _sy + ((CHUNKSIZE - (_sy % CHUNKSIZE)) % CHUNKSIZE);
int sz = _sz + ((CHUNKSIZE - (_sz % CHUNKSIZE)) % CHUNKSIZE);
int chx = sx >> CHUNKSIZE_OPSHIFT; //Chunks Count in X
int chy = sy >> CHUNKSIZE_OPSHIFT; //Chunks Count in Y
int chz = sz >> CHUNKSIZE_OPSHIFT; //Chunks Count in Z
//VoxArray3D* parray = (VoxArray3D*)MemAlloc(sizeof(VoxArray3D));
voxarray->sizeX = sx;
voxarray->sizeY = sy;
voxarray->sizeZ = sz;
voxarray->chunksSizeX = chx;
voxarray->chunksSizeY = chy;
voxarray->chunksSizeZ = chz;
voxarray->ChunkFlattenOffset = (chy * chz); //m_arrayChunks[(x * (sy*sz)) + (z * sy) + y]
//Alloc chunks array
int size = sizeof(CubeChunk3D) * chx * chy * chz;
voxarray->m_arrayChunks = MemAlloc(size);
voxarray->arrayChunksSize = size;
//Init chunks array
size = chx * chy * chz;
voxarray->chunksTotal = size;
voxarray->chunksAllocated = 0;
for (int i = 0; i < size; i++)
{
voxarray->m_arrayChunks[i].m_array = 0;
voxarray->m_arrayChunks[i].arraySize = 0;
}
}
// Set voxel ID from its position into VoxArray3D
void Vox_SetVoxel(VoxArray3D* voxarray, int x, int y, int z, unsigned char id)
{
//Get chunk from array pos
int chX = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE;
int chY = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE;
int chZ = z >> CHUNKSIZE_OPSHIFT; //z / CHUNKSIZE;
int offset = (chX * voxarray->ChunkFlattenOffset) + (chZ * voxarray->chunksSizeY) + chY;
//if (offset > voxarray->arrayChunksSize)
//{
// TraceLog(LOG_ERROR, "Out of array");
//}
CubeChunk3D* chunk = &voxarray->m_arrayChunks[offset];
//Set Chunk
chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE);
chY = y - (chY << CHUNKSIZE_OPSHIFT); //y - (by * CHUNKSIZE);
chZ = z - (chZ << CHUNKSIZE_OPSHIFT); //z - (bz * CHUNKSIZE);
if (chunk->m_array == 0)
{
int size = CHUNKSIZE * CHUNKSIZE * CHUNKSIZE;
chunk->m_array = MemAlloc(size);
chunk->arraySize = size;
//memset(chunk->m_array, 0, size);
voxarray->chunksAllocated++;
}
offset = (chX << CHUNK_FLATTENOFFSET_OPSHIFT) + (chZ << CHUNKSIZE_OPSHIFT) + chY;
//if (offset > chunk->arraySize)
//{
// TraceLog(LOG_ERROR, "Out of array");
//}
chunk->m_array[offset] = id;
}
// Get voxel ID from its position into VoxArray3D
unsigned char Vox_GetVoxel(VoxArray3D* voxarray, int x, int y, int z)
{
if (x < 0 || y < 0 || z < 0)
return 0;
if (x >= voxarray->sizeX || y >= voxarray->sizeY || z >= voxarray->sizeZ)
return 0;
//Get chunk from array pos
int chX = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE;
int chY = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE;
int chZ = z >> CHUNKSIZE_OPSHIFT; //z / CHUNKSIZE;
int offset = (chX * voxarray->ChunkFlattenOffset) + (chZ * voxarray->chunksSizeY) + chY;
//if (offset > voxarray->arrayChunksSize)
//{
// TraceLog(LOG_ERROR, "Out of array");
//}
CubeChunk3D* chunk = &voxarray->m_arrayChunks[offset];
//Set Chunk
chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE);
chY = y - (chY << CHUNKSIZE_OPSHIFT); //y - (by * CHUNKSIZE);
chZ = z - (chZ << CHUNKSIZE_OPSHIFT); //z - (bz * CHUNKSIZE);
if (chunk->m_array == 0)
{
return 0;
}
offset = (chX << CHUNK_FLATTENOFFSET_OPSHIFT) + (chZ << CHUNKSIZE_OPSHIFT) + chY;
//if (offset > chunk->arraySize)
//{
// TraceLog(LOG_ERROR, "Out of array");
//}
return chunk->m_array[offset];
}
// Calc visibles faces from a voxel position
unsigned char Vox_CalcFacesVisible(VoxArray3D* pvoxArray, int cx, int cy, int cz)
{
unsigned char idXm1 = Vox_GetVoxel(pvoxArray, cx - 1, cy, cz);
unsigned char idXp1 = Vox_GetVoxel(pvoxArray, cx + 1, cy, cz);
unsigned char idYm1 = Vox_GetVoxel(pvoxArray, cx, cy - 1, cz);
unsigned char idYp1 = Vox_GetVoxel(pvoxArray, cx, cy + 1, cz);
unsigned char idZm1 = Vox_GetVoxel(pvoxArray, cx, cy, cz - 1);
unsigned char idZp1 = Vox_GetVoxel(pvoxArray, cx, cy, cz + 1);
unsigned char byVFMask = 0;
//#-x
if (idXm1 == 0)
byVFMask |= (1 << 0);
//#+x
if (idXp1 == 0)
byVFMask |= (1 << 1);
//#-y
if (idYm1 == 0)
byVFMask |= (1 << 2);
//#+y
if (idYp1 == 0)
byVFMask |= (1 << 3);
//#-z
if (idZm1 == 0)
byVFMask |= (1 << 4);
//#+z
if (idZp1 == 0)
byVFMask |= (1 << 5);
return byVFMask;
}
// Get a vertex position from a voxel's corner
Vector3 Vox_GetVertexPosition(int _wcx, int _wcy, int _wcz, int _nNumVertex)
{
float scale = 0.25;
Vector3 vtx = SolidVertex[_nNumVertex];
vtx.x = (vtx.x + _wcx) * scale;
vtx.y = (vtx.y + _wcy) * scale;
vtx.z = (vtx.z + _wcz) * scale;
return vtx;
}
// Build a voxel vertices/colors/indices
void Vox_Build_Voxel(VoxArray3D* pvoxArray, int x, int y, int z, int matID)
{
unsigned char byVFMask = Vox_CalcFacesVisible(pvoxArray, x, y, z);
if (byVFMask == 0)
return;
int i, j;
Vector3 vertComputed[8];
int bVertexComputed[8];
memset(vertComputed, 0, sizeof(vertComputed));
memset(bVertexComputed, 0, sizeof(bVertexComputed));
//For each Cube's faces
for (i = 0; i < 6; i++) // 6 faces
{
if ((byVFMask & (1 << i)) != 0) //If face is visible
{
for (j = 0; j < 4; j++) // 4 corners
{
int nNumVertex = fv[i][j]; //Face,Corner
if (bVertexComputed[nNumVertex] == 0) //if never calc
{
bVertexComputed[nNumVertex] = 1;
vertComputed[nNumVertex] = Vox_GetVertexPosition(x, y, z, nNumVertex);
}
}
}
}
//Add face
for (i = 0; i < 6; i++)// 6 faces
{
if ((byVFMask & (1 << i)) == 0)
continue; //Face invisible
int v0 = fv[i][0]; //Face, Corner
int v1 = fv[i][1]; //Face, Corner
int v2 = fv[i][2]; //Face, Corner
int v3 = fv[i][3]; //Face, Corner
//Arrays
int idx = pvoxArray->vertices.used;
insertArrayVector3(&pvoxArray->vertices, vertComputed[v0]);
insertArrayVector3(&pvoxArray->vertices, vertComputed[v1]);
insertArrayVector3(&pvoxArray->vertices, vertComputed[v2]);
insertArrayVector3(&pvoxArray->vertices, vertComputed[v3]);
Color col = pvoxArray->palette[matID];
insertArrayColor(&pvoxArray->colors, col);
insertArrayColor(&pvoxArray->colors, col);
insertArrayColor(&pvoxArray->colors, col);
insertArrayColor(&pvoxArray->colors, col);
//v0 - v1 - v2, v0 - v2 - v3
insertArrayUShort(&pvoxArray->indices, idx + 0);
insertArrayUShort(&pvoxArray->indices, idx + 2);
insertArrayUShort(&pvoxArray->indices, idx + 1);
insertArrayUShort(&pvoxArray->indices, idx + 0);
insertArrayUShort(&pvoxArray->indices, idx + 3);
insertArrayUShort(&pvoxArray->indices, idx + 2);
}
}
// MagicaVoxel *.vox file format Loader
int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray)
{
//////////////////////////////////////////////////
//Read VOX file
//4 bytes: magic number ('V' 'O' 'X' 'space' )
//4 bytes: version number (current version is 150 )
unsigned long signature;
unsigned int readed = 0;
unsigned char* fileData;
fileData = LoadFileData(pszfileName, &readed);
if (fileData == 0)
{
return VOX_ERROR_FILE_NOT_FOUND;
}
unsigned char* fileDataPtr = fileData;
unsigned char* endfileDataPtr = fileData + readed;
signature = *((unsigned long *)fileDataPtr);
fileDataPtr += sizeof(unsigned long);
if (signature != 0x20584F56) //56 4F 58 20
{
//TraceLog(LOG_ERROR, "Not an MagicaVoxel File format");
return VOX_ERROR_INVALID_FORMAT;
}
unsigned long version;
version = *((unsigned long*)fileDataPtr);
fileDataPtr += sizeof(unsigned long);
if (version < 150)
{
//TraceLog(LOG_ERROR, "MagicaVoxel version too old");
return VOX_ERROR_FILE_VERSION_TOO_OLD;
}
// header
//4 bytes: chunk id
//4 bytes: size of chunk contents (n)
//4 bytes: total size of children chunks(m)
//// chunk content
//n bytes: chunk contents
//// children chunks : m bytes
//{ child chunk 0 }
//{ child chunk 1 }
unsigned long sizeX, sizeY, sizeZ;
sizeX = sizeY = sizeZ = 0;
unsigned long numVoxels = 0;
int offsetX, offsetY, offsetZ;
offsetX = offsetY = offsetZ = 0;
while (fileDataPtr < endfileDataPtr)
{
char szChunkName[5];
memcpy(szChunkName, fileDataPtr, 4);
szChunkName[4] = 0;
fileDataPtr += 4;
unsigned long chunkSize = *((unsigned long*)fileDataPtr);
fileDataPtr += sizeof(unsigned long);
unsigned long chunkTotalChildSize = *((unsigned long*)fileDataPtr);
fileDataPtr += sizeof(unsigned long);
if (strcmp(szChunkName, "SIZE") == 0)
{
//(4 bytes x 3 : x, y, z )
sizeX = *((unsigned long*)fileDataPtr);
fileDataPtr += sizeof(unsigned long);
sizeY = *((unsigned long*)fileDataPtr);
fileDataPtr += sizeof(unsigned long);
sizeZ = *((unsigned long*)fileDataPtr);
fileDataPtr += sizeof(unsigned long);
//Alloc vox array
Vox_AllocArray(voxarray, sizeX, sizeY, sizeZ);
}
else if (strcmp(szChunkName, "XYZI") == 0)
{
unsigned char vx, vy, vz, vi;
//(numVoxels : 4 bytes )
//(each voxel: 1 byte x 4 : x, y, z, colorIndex ) x numVoxels
numVoxels = *((unsigned long*)fileDataPtr);
fileDataPtr += sizeof(unsigned long);
while (numVoxels > 0)
{
vx = *((unsigned char*)fileDataPtr++);
vy = *((unsigned char*)fileDataPtr++);
vz = *((unsigned char*)fileDataPtr++);
vi = *((unsigned char*)fileDataPtr++);
Vox_SetVoxel(voxarray, vx, vy, vz, vi);
numVoxels--;
}
}
else if (strcmp(szChunkName, "RGBA") == 0)
{
Color col;
//(each pixel: 1 byte x 4 : r, g, b, a ) x 256
for (int i = 0; i < 256 - 1; i++)
{
col.r = *((unsigned char*)fileDataPtr++);
col.g = *((unsigned char*)fileDataPtr++);
col.b = *((unsigned char*)fileDataPtr++);
col.a = *((unsigned char*)fileDataPtr++);
voxarray->palette[i + 1] = col;
}
}
else
{
fileDataPtr += chunkSize;
}
}
//TraceLog(LOG_INFO, TextFormat("Vox Size : %dx%dx%d", sizeX, sizeY, sizeZ));
//TraceLog(LOG_INFO, TextFormat("Vox Chunks Count : %d/%d", pvoxArray->chunksAllocated, pvoxArray->chunksTotal));
//////////////////////////////////////////////////////////
// Building Mesh
// TODO compute globals indices array
//TraceLog(LOG_INFO, TextFormat("Building VOX Mesh : %s", pszfileName));
// Init Arrays
initArrayVector3(&voxarray->vertices, 3 * 1024);
initArrayUShort(&voxarray->indices, 3 * 1024);
initArrayColor(&voxarray->colors, 3 * 1024);
// Create vertices and indices buffers
int x, y, z;
for (x = 0; x <= voxarray->sizeX; x++)
{
for (z = 0; z <= voxarray->sizeZ; z++)
{
for (y = 0; y <= voxarray->sizeY; y++)
{
unsigned char matID = Vox_GetVoxel(voxarray, x, y, z);
if (matID != 0)
Vox_Build_Voxel(voxarray, x, y, z, matID);
}
}
}
return VOX_SUCCESS;
}
void Vox_FreeArrays(VoxArray3D* voxarray)
{
//Free chunks
if (voxarray->m_arrayChunks != 0)
{
for (int i = 0; i < voxarray->chunksTotal; i++)
{
CubeChunk3D* chunk = &voxarray->m_arrayChunks[i];
if (chunk->m_array != 0)
{
chunk->arraySize = 0;
MemFree(chunk->m_array);
}
}
MemFree(voxarray->m_arrayChunks);
voxarray->m_arrayChunks = 0;
voxarray->arrayChunksSize = 0;
voxarray->chunksSizeX = voxarray->chunksSizeY = voxarray->chunksSizeZ = 0;
voxarray->chunksTotal = 0;
voxarray->chunksAllocated = 0;
voxarray->ChunkFlattenOffset = 0;
voxarray->sizeX = voxarray->sizeY = voxarray->sizeZ = 0;
}
//Free arrays
freeArrayVector3(&voxarray->vertices);
freeArrayUShort(&voxarray->indices);
freeArrayColor(&voxarray->colors);
}
#endif //VOX_LOADER_IMPLEMENTATION

File diff suppressed because it is too large Load Diff

View File

@ -1,556 +0,0 @@
/**********************************************************************************************
*
* rIcons - Icons pack intended for tools development with raygui
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2019-2020 Ramon Santamaria (@raysan5)
*
**********************************************************************************************/
#ifndef RICONS_H
#define RICONS_H
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
#define RICON_MAX_ICONS 256 // Maximum number of icons
#define RICON_SIZE 16 // Size of icons (squared)
#define RICON_MAX_NAME_LENGTH 32 // Maximum length of icon name id
// Icons data is defined by bit array (every bit represents one pixel)
// Those arrays are stored as unsigned int data arrays, so every array
// element defines 32 pixels (bits) of information
// Number of elemens depend on RICON_SIZE (by default 16x16 pixels)
#define RICON_DATA_ELEMENTS (RICON_SIZE*RICON_SIZE/32)
//----------------------------------------------------------------------------------
// Icons enumeration
//----------------------------------------------------------------------------------
typedef enum {
RICON_NONE = 0,
RICON_FOLDER_FILE_OPEN = 1,
RICON_FILE_SAVE_CLASSIC = 2,
RICON_FOLDER_OPEN = 3,
RICON_FOLDER_SAVE = 4,
RICON_FILE_OPEN = 5,
RICON_FILE_SAVE = 6,
RICON_FILE_EXPORT = 7,
RICON_FILE_NEW = 8,
RICON_FILE_DELETE = 9,
RICON_FILETYPE_TEXT = 10,
RICON_FILETYPE_AUDIO = 11,
RICON_FILETYPE_IMAGE = 12,
RICON_FILETYPE_PLAY = 13,
RICON_FILETYPE_VIDEO = 14,
RICON_FILETYPE_INFO = 15,
RICON_FILE_COPY = 16,
RICON_FILE_CUT = 17,
RICON_FILE_PASTE = 18,
RICON_CURSOR_HAND = 19,
RICON_CURSOR_POINTER = 20,
RICON_CURSOR_CLASSIC = 21,
RICON_PENCIL = 22,
RICON_PENCIL_BIG = 23,
RICON_BRUSH_CLASSIC = 24,
RICON_BRUSH_PAINTER = 25,
RICON_WATER_DROP = 26,
RICON_COLOR_PICKER = 27,
RICON_RUBBER = 28,
RICON_COLOR_BUCKET = 29,
RICON_TEXT_T = 30,
RICON_TEXT_A = 31,
RICON_SCALE = 32,
RICON_RESIZE = 33,
RICON_FILTER_POINT = 34,
RICON_FILTER_BILINEAR = 35,
RICON_CROP = 36,
RICON_CROP_ALPHA = 37,
RICON_SQUARE_TOGGLE = 38,
RICON_SYMMETRY = 39,
RICON_SYMMETRY_HORIZONTAL = 40,
RICON_SYMMETRY_VERTICAL = 41,
RICON_LENS = 42,
RICON_LENS_BIG = 43,
RICON_EYE_ON = 44,
RICON_EYE_OFF = 45,
RICON_FILTER_TOP = 46,
RICON_FILTER = 47,
RICON_TARGET_POINT = 48,
RICON_TARGET_SMALL = 49,
RICON_TARGET_BIG = 50,
RICON_TARGET_MOVE = 51,
RICON_CURSOR_MOVE = 52,
RICON_CURSOR_SCALE = 53,
RICON_CURSOR_SCALE_RIGHT = 54,
RICON_CURSOR_SCALE_LEFT = 55,
RICON_UNDO = 56,
RICON_REDO = 57,
RICON_REREDO = 58,
RICON_MUTATE = 59,
RICON_ROTATE = 60,
RICON_REPEAT = 61,
RICON_SHUFFLE = 62,
RICON_EMPTYBOX = 63,
RICON_TARGET = 64,
RICON_TARGET_SMALL_FILL = 65,
RICON_TARGET_BIG_FILL = 66,
RICON_TARGET_MOVE_FILL = 67,
RICON_CURSOR_MOVE_FILL = 68,
RICON_CURSOR_SCALE_FILL = 69,
RICON_CURSOR_SCALE_RIGHT_FILL = 70,
RICON_CURSOR_SCALE_LEFT_FILL = 71,
RICON_UNDO_FILL = 72,
RICON_REDO_FILL = 73,
RICON_REREDO_FILL = 74,
RICON_MUTATE_FILL = 75,
RICON_ROTATE_FILL = 76,
RICON_REPEAT_FILL = 77,
RICON_SHUFFLE_FILL = 78,
RICON_EMPTYBOX_SMALL = 79,
RICON_BOX = 80,
RICON_BOX_TOP = 81,
RICON_BOX_TOP_RIGHT = 82,
RICON_BOX_RIGHT = 83,
RICON_BOX_BOTTOM_RIGHT = 84,
RICON_BOX_BOTTOM = 85,
RICON_BOX_BOTTOM_LEFT = 86,
RICON_BOX_LEFT = 87,
RICON_BOX_TOP_LEFT = 88,
RICON_BOX_CENTER = 89,
RICON_BOX_CIRCLE_MASK = 90,
RICON_POT = 91,
RICON_ALPHA_MULTIPLY = 92,
RICON_ALPHA_CLEAR = 93,
RICON_DITHERING = 94,
RICON_MIPMAPS = 95,
RICON_BOX_GRID = 96,
RICON_GRID = 97,
RICON_BOX_CORNERS_SMALL = 98,
RICON_BOX_CORNERS_BIG = 99,
RICON_FOUR_BOXES = 100,
RICON_GRID_FILL = 101,
RICON_BOX_MULTISIZE = 102,
RICON_ZOOM_SMALL = 103,
RICON_ZOOM_MEDIUM = 104,
RICON_ZOOM_BIG = 105,
RICON_ZOOM_ALL = 106,
RICON_ZOOM_CENTER = 107,
RICON_BOX_DOTS_SMALL = 108,
RICON_BOX_DOTS_BIG = 109,
RICON_BOX_CONCENTRIC = 110,
RICON_BOX_GRID_BIG = 111,
RICON_OK_TICK = 112,
RICON_CROSS = 113,
RICON_ARROW_LEFT = 114,
RICON_ARROW_RIGHT = 115,
RICON_ARROW_BOTTOM = 116,
RICON_ARROW_TOP = 117,
RICON_ARROW_LEFT_FILL = 118,
RICON_ARROW_RIGHT_FILL = 119,
RICON_ARROW_BOTTOM_FILL = 120,
RICON_ARROW_TOP_FILL = 121,
RICON_AUDIO = 122,
RICON_FX = 123,
RICON_WAVE = 124,
RICON_WAVE_SINUS = 125,
RICON_WAVE_SQUARE = 126,
RICON_WAVE_TRIANGULAR = 127,
RICON_CROSS_SMALL = 128,
RICON_PLAYER_PREVIOUS = 129,
RICON_PLAYER_PLAY_BACK = 130,
RICON_PLAYER_PLAY = 131,
RICON_PLAYER_PAUSE = 132,
RICON_PLAYER_STOP = 133,
RICON_PLAYER_NEXT = 134,
RICON_PLAYER_RECORD = 135,
RICON_MAGNET = 136,
RICON_LOCK_CLOSE = 137,
RICON_LOCK_OPEN = 138,
RICON_CLOCK = 139,
RICON_TOOLS = 140,
RICON_GEAR = 141,
RICON_GEAR_BIG = 142,
RICON_BIN = 143,
RICON_HAND_POINTER = 144,
RICON_LASER = 145,
RICON_COIN = 146,
RICON_EXPLOSION = 147,
RICON_1UP = 148,
RICON_PLAYER = 149,
RICON_PLAYER_JUMP = 150,
RICON_KEY = 151,
RICON_DEMON = 152,
RICON_TEXT_POPUP = 153,
RICON_GEAR_EX = 154,
RICON_CRACK = 155,
RICON_CRACK_POINTS = 156,
RICON_STAR = 157,
RICON_DOOR = 158,
RICON_EXIT = 159,
RICON_MODE_2D = 160,
RICON_MODE_3D = 161,
RICON_CUBE = 162,
RICON_CUBE_FACE_TOP = 163,
RICON_CUBE_FACE_LEFT = 164,
RICON_CUBE_FACE_FRONT = 165,
RICON_CUBE_FACE_BOTTOM = 166,
RICON_CUBE_FACE_RIGHT = 167,
RICON_CUBE_FACE_BACK = 168,
RICON_CAMERA = 169,
RICON_SPECIAL = 170,
RICON_LINK_NET = 171,
RICON_LINK_BOXES = 172,
RICON_LINK_MULTI = 173,
RICON_LINK = 174,
RICON_LINK_BROKE = 175,
RICON_TEXT_NOTES = 176,
RICON_NOTEBOOK = 177,
RICON_SUITCASE = 178,
RICON_SUITCASE_ZIP = 179,
RICON_MAILBOX = 180,
RICON_MONITOR = 181,
RICON_PRINTER = 182,
RICON_PHOTO_CAMERA = 183,
RICON_PHOTO_CAMERA_FLASH = 184,
RICON_HOUSE = 185,
RICON_HEART = 186,
RICON_CORNER = 187,
RICON_VERTICAL_BARS = 188,
RICON_VERTICAL_BARS_FILL = 189,
RICON_LIFE_BARS = 190,
RICON_INFO = 191,
RICON_CROSSLINE = 192,
RICON_HELP = 193,
RICON_FILETYPE_ALPHA = 194,
RICON_FILETYPE_HOME = 195,
RICON_LAYERS_VISIBLE = 196,
RICON_LAYERS = 197,
RICON_WINDOW = 198,
RICON_HIDPI = 199,
RICON_200 = 200,
RICON_201 = 201,
RICON_202 = 202,
RICON_203 = 203,
RICON_204 = 204,
RICON_205 = 205,
RICON_206 = 206,
RICON_207 = 207,
RICON_208 = 208,
RICON_209 = 209,
RICON_210 = 210,
RICON_211 = 211,
RICON_212 = 212,
RICON_213 = 213,
RICON_214 = 214,
RICON_215 = 215,
RICON_216 = 216,
RICON_217 = 217,
RICON_218 = 218,
RICON_219 = 219,
RICON_220 = 220,
RICON_221 = 221,
RICON_222 = 222,
RICON_223 = 223,
RICON_224 = 224,
RICON_225 = 225,
RICON_226 = 226,
RICON_227 = 227,
RICON_228 = 228,
RICON_229 = 229,
RICON_230 = 230,
RICON_231 = 231,
RICON_232 = 232,
RICON_233 = 233,
RICON_234 = 234,
RICON_235 = 235,
RICON_236 = 236,
RICON_237 = 237,
RICON_238 = 238,
RICON_239 = 239,
RICON_240 = 240,
RICON_241 = 241,
RICON_242 = 242,
RICON_243 = 243,
RICON_244 = 244,
RICON_245 = 245,
RICON_246 = 246,
RICON_247 = 247,
RICON_248 = 248,
RICON_249 = 249,
RICON_250 = 250,
RICON_251 = 251,
RICON_252 = 252,
RICON_253 = 253,
RICON_254 = 254,
RICON_255 = 255,
} guiIconName;
#endif // RICONS_H
#if defined(RICONS_IMPLEMENTATION)
//----------------------------------------------------------------------------------
// Icons data (allocated on memory data section by default)
// NOTE: A new icon set could be loaded over this array using GuiLoadIcons(),
// just note that loaded icons set must be same RICON_SIZE
//----------------------------------------------------------------------------------
static unsigned int guiIcons[RICON_MAX_ICONS*RICON_DATA_ELEMENTS] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_NONE
0x3ff80000, 0x2f082008, 0x2042207e, 0x40027fc2, 0x40024002, 0x40024002, 0x40024002, 0x00007ffe, // RICON_FOLDER_FILE_OPEN
0x3ffe0000, 0x44226422, 0x400247e2, 0x5ffa4002, 0x57ea500a, 0x500a500a, 0x40025ffa, 0x00007ffe, // RICON_FILE_SAVE_CLASSIC
0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024002, 0x44424282, 0x793e4102, 0x00000100, // RICON_FOLDER_OPEN
0x00000000, 0x0042007e, 0x40027fc2, 0x40024002, 0x41024102, 0x44424102, 0x793e4282, 0x00000000, // RICON_FOLDER_SAVE
0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x24442284, 0x21042104, 0x20042104, 0x00003ffc, // RICON_FILE_OPEN
0x3ff00000, 0x201c2010, 0x20042004, 0x21042004, 0x21042104, 0x22842444, 0x20042104, 0x00003ffc, // RICON_FILE_SAVE
0x3ff00000, 0x201c2010, 0x00042004, 0x20041004, 0x20844784, 0x00841384, 0x20042784, 0x00003ffc, // RICON_FILE_EXPORT
0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x22042204, 0x22042f84, 0x20042204, 0x00003ffc, // RICON_FILE_NEW
0x3ff00000, 0x201c2010, 0x20042004, 0x20042004, 0x25042884, 0x25042204, 0x20042884, 0x00003ffc, // RICON_FILE_DELETE
0x3ff00000, 0x201c2010, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc, // RICON_FILETYPE_TEXT
0x3ff00000, 0x201c2010, 0x27042004, 0x244424c4, 0x26442444, 0x20642664, 0x20042004, 0x00003ffc, // RICON_FILETYPE_AUDIO
0x3ff00000, 0x201c2010, 0x26042604, 0x20042004, 0x35442884, 0x2414222c, 0x20042004, 0x00003ffc, // RICON_FILETYPE_IMAGE
0x3ff00000, 0x201c2010, 0x20c42004, 0x22442144, 0x22442444, 0x20c42144, 0x20042004, 0x00003ffc, // RICON_FILETYPE_PLAY
0x3ff00000, 0x3ffc2ff0, 0x3f3c2ff4, 0x3dbc2eb4, 0x3dbc2bb4, 0x3f3c2eb4, 0x3ffc2ff4, 0x00002ff4, // RICON_FILETYPE_VIDEO
0x3ff00000, 0x201c2010, 0x21842184, 0x21842004, 0x21842184, 0x21842184, 0x20042184, 0x00003ffc, // RICON_FILETYPE_INFO
0x0ff00000, 0x381c0810, 0x28042804, 0x28042804, 0x28042804, 0x28042804, 0x20102ffc, 0x00003ff0, // RICON_FILE_COPY
0x00000000, 0x701c0000, 0x079c1e14, 0x55a000f0, 0x079c00f0, 0x701c1e14, 0x00000000, 0x00000000, // RICON_FILE_CUT
0x01c00000, 0x13e41bec, 0x3f841004, 0x204420c4, 0x20442044, 0x20442044, 0x207c2044, 0x00003fc0, // RICON_FILE_PASTE
0x00000000, 0x3aa00fe0, 0x2abc2aa0, 0x2aa42aa4, 0x20042aa4, 0x20042004, 0x3ffc2004, 0x00000000, // RICON_CURSOR_HAND
0x00000000, 0x003c000c, 0x030800c8, 0x30100c10, 0x10202020, 0x04400840, 0x01800280, 0x00000000, // RICON_CURSOR_POINTER
0x00000000, 0x00180000, 0x01f00078, 0x03e007f0, 0x07c003e0, 0x04000e40, 0x00000000, 0x00000000, // RICON_CURSOR_CLASSIC
0x00000000, 0x04000000, 0x11000a00, 0x04400a80, 0x01100220, 0x00580088, 0x00000038, 0x00000000, // RICON_PENCIL
0x04000000, 0x15000a00, 0x50402880, 0x14102820, 0x05040a08, 0x015c028c, 0x007c00bc, 0x00000000, // RICON_PENCIL_BIG
0x01c00000, 0x01400140, 0x01400140, 0x0ff80140, 0x0ff80808, 0x0aa80808, 0x0aa80aa8, 0x00000ff8, // RICON_BRUSH_CLASSIC
0x1ffc0000, 0x5ffc7ffe, 0x40004000, 0x00807f80, 0x01c001c0, 0x01c001c0, 0x01c001c0, 0x00000080, // RICON_BRUSH_PAINTER
0x00000000, 0x00800000, 0x01c00080, 0x03e001c0, 0x07f003e0, 0x036006f0, 0x000001c0, 0x00000000, // RICON_WATER_DROP
0x00000000, 0x3e003800, 0x1f803f80, 0x0c201e40, 0x02080c10, 0x00840104, 0x00380044, 0x00000000, // RICON_COLOR_PICKER
0x00000000, 0x07800300, 0x1fe00fc0, 0x3f883fd0, 0x0e021f04, 0x02040402, 0x00f00108, 0x00000000, // RICON_RUBBER
0x00c00000, 0x02800140, 0x08200440, 0x20081010, 0x2ffe3004, 0x03f807fc, 0x00e001f0, 0x00000040, // RICON_COLOR_BUCKET
0x00000000, 0x21843ffc, 0x01800180, 0x01800180, 0x01800180, 0x01800180, 0x03c00180, 0x00000000, // RICON_TEXT_T
0x00800000, 0x01400180, 0x06200340, 0x0c100620, 0x1ff80c10, 0x380c1808, 0x70067004, 0x0000f80f, // RICON_TEXT_A
0x78000000, 0x50004000, 0x00004800, 0x03c003c0, 0x03c003c0, 0x00100000, 0x0002000a, 0x0000000e, // RICON_SCALE
0x75560000, 0x5e004002, 0x54001002, 0x41001202, 0x408200fe, 0x40820082, 0x40820082, 0x00006afe, // RICON_RESIZE
0x00000000, 0x3f003f00, 0x3f003f00, 0x3f003f00, 0x00400080, 0x001c0020, 0x001c001c, 0x00000000, // RICON_FILTER_POINT
0x6d800000, 0x00004080, 0x40804080, 0x40800000, 0x00406d80, 0x001c0020, 0x001c001c, 0x00000000, // RICON_FILTER_BILINEAR
0x40080000, 0x1ffe2008, 0x14081008, 0x11081208, 0x10481088, 0x10081028, 0x10047ff8, 0x00001002, // RICON_CROP
0x00100000, 0x3ffc0010, 0x2ab03550, 0x22b02550, 0x20b02150, 0x20302050, 0x2000fff0, 0x00002000, // RICON_CROP_ALPHA
0x40000000, 0x1ff82000, 0x04082808, 0x01082208, 0x00482088, 0x00182028, 0x35542008, 0x00000002, // RICON_SQUARE_TOGGLE
0x00000000, 0x02800280, 0x06c006c0, 0x0ea00ee0, 0x1e901eb0, 0x3e883e98, 0x7efc7e8c, 0x00000000, // RICON_SIMMETRY
0x01000000, 0x05600100, 0x1d480d50, 0x7d423d44, 0x3d447d42, 0x0d501d48, 0x01000560, 0x00000100, // RICON_SIMMETRY_HORIZONTAL
0x01800000, 0x04200240, 0x10080810, 0x00001ff8, 0x00007ffe, 0x0ff01ff8, 0x03c007e0, 0x00000180, // RICON_SIMMETRY_VERTICAL
0x00000000, 0x010800f0, 0x02040204, 0x02040204, 0x07f00308, 0x1c000e00, 0x30003800, 0x00000000, // RICON_LENS
0x00000000, 0x061803f0, 0x08240c0c, 0x08040814, 0x0c0c0804, 0x23f01618, 0x18002400, 0x00000000, // RICON_LENS_BIG
0x00000000, 0x00000000, 0x1c7007c0, 0x638e3398, 0x1c703398, 0x000007c0, 0x00000000, 0x00000000, // RICON_EYE_ON
0x00000000, 0x10002000, 0x04700fc0, 0x610e3218, 0x1c703098, 0x001007a0, 0x00000008, 0x00000000, // RICON_EYE_OFF
0x00000000, 0x00007ffc, 0x40047ffc, 0x10102008, 0x04400820, 0x02800280, 0x02800280, 0x00000100, // RICON_FILTER_TOP
0x00000000, 0x40027ffe, 0x10082004, 0x04200810, 0x02400240, 0x02400240, 0x01400240, 0x000000c0, // RICON_FILTER
0x00800000, 0x00800080, 0x00000080, 0x3c9e0000, 0x00000000, 0x00800080, 0x00800080, 0x00000000, // RICON_TARGET_POINT
0x00800000, 0x00800080, 0x00800080, 0x3f7e01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000, // RICON_TARGET_SMALL
0x00800000, 0x00800080, 0x03e00080, 0x3e3e0220, 0x03e00220, 0x00800080, 0x00800080, 0x00000000, // RICON_TARGET_BIG
0x01000000, 0x04400280, 0x01000100, 0x43842008, 0x43849ab2, 0x01002008, 0x04400100, 0x01000280, // RICON_TARGET_MOVE
0x01000000, 0x04400280, 0x01000100, 0x41042108, 0x41049ff2, 0x01002108, 0x04400100, 0x01000280, // RICON_CURSOR_MOVE
0x781e0000, 0x500a4002, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x4002500a, 0x0000781e, // RICON_CURSOR_SCALE
0x00000000, 0x20003c00, 0x24002800, 0x01000200, 0x00400080, 0x00140024, 0x003c0004, 0x00000000, // RICON_CURSOR_SCALE_RIGHT
0x00000000, 0x0004003c, 0x00240014, 0x00800040, 0x02000100, 0x28002400, 0x3c002000, 0x00000000, // RICON_CURSOR_SCALE_LEFT
0x00000000, 0x00100020, 0x10101fc8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000, // RICON_UNDO
0x00000000, 0x08000400, 0x080813f8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000, // RICON_REDO
0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3f902020, 0x00400020, 0x00000000, // RICON_REREDO
0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3fc82010, 0x00200010, 0x00000000, // RICON_MUTATE
0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18101020, 0x00100fc8, 0x00000020, // RICON_ROTATE
0x00000000, 0x04000200, 0x240429fc, 0x20042204, 0x20442004, 0x3f942024, 0x00400020, 0x00000000, // RICON_REPEAT
0x00000000, 0x20001000, 0x22104c0e, 0x00801120, 0x11200040, 0x4c0e2210, 0x10002000, 0x00000000, // RICON_SHUFFLE
0x7ffe0000, 0x50024002, 0x44024802, 0x41024202, 0x40424082, 0x40124022, 0x4002400a, 0x00007ffe, // RICON_EMPTYBOX
0x00800000, 0x03e00080, 0x08080490, 0x3c9e0808, 0x08080808, 0x03e00490, 0x00800080, 0x00000000, // RICON_TARGET
0x00800000, 0x00800080, 0x00800080, 0x3ffe01c0, 0x008001c0, 0x00800080, 0x00800080, 0x00000000, // RICON_TARGET_SMALL_FILL
0x00800000, 0x00800080, 0x03e00080, 0x3ffe03e0, 0x03e003e0, 0x00800080, 0x00800080, 0x00000000, // RICON_TARGET_BIG_FILL
0x01000000, 0x07c00380, 0x01000100, 0x638c2008, 0x638cfbbe, 0x01002008, 0x07c00100, 0x01000380, // RICON_TARGET_MOVE_FILL
0x01000000, 0x07c00380, 0x01000100, 0x610c2108, 0x610cfffe, 0x01002108, 0x07c00100, 0x01000380, // RICON_CURSOR_MOVE_FILL
0x781e0000, 0x6006700e, 0x04204812, 0x00000240, 0x02400000, 0x48120420, 0x700e6006, 0x0000781e, // RICON_CURSOR_SCALE_FILL
0x00000000, 0x38003c00, 0x24003000, 0x01000200, 0x00400080, 0x000c0024, 0x003c001c, 0x00000000, // RICON_CURSOR_SCALE_RIGHT
0x00000000, 0x001c003c, 0x0024000c, 0x00800040, 0x02000100, 0x30002400, 0x3c003800, 0x00000000, // RICON_CURSOR_SCALE_LEFT
0x00000000, 0x00300020, 0x10301ff8, 0x10001020, 0x10001000, 0x10001000, 0x00001fc0, 0x00000000, // RICON_UNDO_FILL
0x00000000, 0x0c000400, 0x0c081ff8, 0x00080408, 0x00080008, 0x00080008, 0x000003f8, 0x00000000, // RICON_REDO_FILL
0x00000000, 0x3ffc0000, 0x20042004, 0x20002000, 0x20402000, 0x3ff02060, 0x00400060, 0x00000000, // RICON_REREDO_FILL
0x00000000, 0x3ffc0000, 0x20042004, 0x27fc2004, 0x20202000, 0x3ff82030, 0x00200030, 0x00000000, // RICON_MUTATE_FILL
0x00000000, 0x0ff00000, 0x10081818, 0x11801008, 0x10001180, 0x18301020, 0x00300ff8, 0x00000020, // RICON_ROTATE_FILL
0x00000000, 0x06000200, 0x26042ffc, 0x20042204, 0x20442004, 0x3ff42064, 0x00400060, 0x00000000, // RICON_REPEAT_FILL
0x00000000, 0x30001000, 0x32107c0e, 0x00801120, 0x11200040, 0x7c0e3210, 0x10003000, 0x00000000, // RICON_SHUFFLE_FILL
0x00000000, 0x30043ffc, 0x24042804, 0x21042204, 0x20442084, 0x20142024, 0x3ffc200c, 0x00000000, // RICON_EMPTYBOX_SMALL
0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // RICON_BOX
0x00000000, 0x23c43ffc, 0x23c423c4, 0x200423c4, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // RICON_BOX_TOP
0x00000000, 0x3e043ffc, 0x3e043e04, 0x20043e04, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // RICON_BOX_TOP_RIGHT
0x00000000, 0x20043ffc, 0x20042004, 0x3e043e04, 0x3e043e04, 0x20042004, 0x3ffc2004, 0x00000000, // RICON_BOX_RIGHT
0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x3e042004, 0x3e043e04, 0x3ffc3e04, 0x00000000, // RICON_BOX_BOTTOM_RIGHT
0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x23c42004, 0x23c423c4, 0x3ffc23c4, 0x00000000, // RICON_BOX_BOTTOM
0x00000000, 0x20043ffc, 0x20042004, 0x20042004, 0x207c2004, 0x207c207c, 0x3ffc207c, 0x00000000, // RICON_BOX_BOTTOM_LEFT
0x00000000, 0x20043ffc, 0x20042004, 0x207c207c, 0x207c207c, 0x20042004, 0x3ffc2004, 0x00000000, // RICON_BOX_LEFT
0x00000000, 0x207c3ffc, 0x207c207c, 0x2004207c, 0x20042004, 0x20042004, 0x3ffc2004, 0x00000000, // RICON_BOX_TOP_LEFT
0x00000000, 0x20043ffc, 0x20042004, 0x23c423c4, 0x23c423c4, 0x20042004, 0x3ffc2004, 0x00000000, // RICON_BOX_CIRCLE_MASK
0x7ffe0000, 0x40024002, 0x47e24182, 0x4ff247e2, 0x47e24ff2, 0x418247e2, 0x40024002, 0x00007ffe, // RICON_BOX_CENTER
0x7fff0000, 0x40014001, 0x40014001, 0x49555ddd, 0x4945495d, 0x400149c5, 0x40014001, 0x00007fff, // RICON_POT
0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x404e40ce, 0x48125432, 0x4006540e, 0x00007ffe, // RICON_ALPHA_MULTIPLY
0x7ffe0000, 0x53327332, 0x44ce4cce, 0x41324332, 0x5c4e40ce, 0x44124432, 0x40065c0e, 0x00007ffe, // RICON_ALPHA_CLEAR
0x7ffe0000, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x42fe417e, 0x00007ffe, // RICON_DITHERING
0x07fe0000, 0x1ffa0002, 0x7fea000a, 0x402a402a, 0x5b2a512a, 0x5128552a, 0x40205128, 0x00007fe0, // RICON_MIPMAPS
0x00000000, 0x1ff80000, 0x12481248, 0x12481ff8, 0x1ff81248, 0x12481248, 0x00001ff8, 0x00000000, // RICON_BOX_GRID
0x12480000, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x7ffe1248, 0x12481248, 0x12487ffe, 0x00001248, // RICON_GRID
0x00000000, 0x1c380000, 0x1c3817e8, 0x08100810, 0x08100810, 0x17e81c38, 0x00001c38, 0x00000000, // RICON_BOX_CORNERS_SMALL
0x700e0000, 0x700e5ffa, 0x20042004, 0x20042004, 0x20042004, 0x20042004, 0x5ffa700e, 0x0000700e, // RICON_BOX_CORNERS_BIG
0x3f7e0000, 0x21422142, 0x21422142, 0x00003f7e, 0x21423f7e, 0x21422142, 0x3f7e2142, 0x00000000, // RICON_FOUR_BOXES
0x00000000, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x3bb80000, 0x3bb83bb8, 0x00000000, // RICON_GRID_FILL
0x7ffe0000, 0x7ffe7ffe, 0x77fe7000, 0x77fe77fe, 0x777e7700, 0x777e777e, 0x777e777e, 0x0000777e, // RICON_BOX_MULTISIZE
0x781e0000, 0x40024002, 0x00004002, 0x01800000, 0x00000180, 0x40020000, 0x40024002, 0x0000781e, // RICON_ZOOM_SMALL
0x781e0000, 0x40024002, 0x00004002, 0x03c003c0, 0x03c003c0, 0x40020000, 0x40024002, 0x0000781e, // RICON_ZOOM_MEDIUM
0x781e0000, 0x40024002, 0x07e04002, 0x07e007e0, 0x07e007e0, 0x400207e0, 0x40024002, 0x0000781e, // RICON_ZOOM_BIG
0x781e0000, 0x5ffa4002, 0x1ff85ffa, 0x1ff81ff8, 0x1ff81ff8, 0x5ffa1ff8, 0x40025ffa, 0x0000781e, // RICON_ZOOM_ALL
0x00000000, 0x2004381c, 0x00002004, 0x00000000, 0x00000000, 0x20040000, 0x381c2004, 0x00000000, // RICON_ZOOM_CENTER
0x00000000, 0x1db80000, 0x10081008, 0x10080000, 0x00001008, 0x10081008, 0x00001db8, 0x00000000, // RICON_BOX_DOTS_SMALL
0x35560000, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x00002002, 0x35562002, 0x00000000, // RICON_BOX_DOTS_BIG
0x7ffe0000, 0x40024002, 0x48124ff2, 0x49924812, 0x48124992, 0x4ff24812, 0x40024002, 0x00007ffe, // RICON_BOX_CONCENTRIC
0x00000000, 0x10841ffc, 0x10841084, 0x1ffc1084, 0x10841084, 0x10841084, 0x00001ffc, 0x00000000, // RICON_BOX_GRID_BIG
0x00000000, 0x00000000, 0x10000000, 0x04000800, 0x01040200, 0x00500088, 0x00000020, 0x00000000, // RICON_OK_TICK
0x00000000, 0x10080000, 0x04200810, 0x01800240, 0x02400180, 0x08100420, 0x00001008, 0x00000000, // RICON_CROSS
0x00000000, 0x02000000, 0x00800100, 0x00200040, 0x00200010, 0x00800040, 0x02000100, 0x00000000, // RICON_ARROW_LEFT
0x00000000, 0x00400000, 0x01000080, 0x04000200, 0x04000800, 0x01000200, 0x00400080, 0x00000000, // RICON_ARROW_RIGHT
0x00000000, 0x00000000, 0x00000000, 0x08081004, 0x02200410, 0x00800140, 0x00000000, 0x00000000, // RICON_ARROW_BOTTOM
0x00000000, 0x00000000, 0x01400080, 0x04100220, 0x10040808, 0x00000000, 0x00000000, 0x00000000, // RICON_ARROW_TOP
0x00000000, 0x02000000, 0x03800300, 0x03e003c0, 0x03e003f0, 0x038003c0, 0x02000300, 0x00000000, // RICON_ARROW_LEFT_FILL
0x00000000, 0x00400000, 0x01c000c0, 0x07c003c0, 0x07c00fc0, 0x01c003c0, 0x004000c0, 0x00000000, // RICON_ARROW_RIGHT_FILL
0x00000000, 0x00000000, 0x00000000, 0x0ff81ffc, 0x03e007f0, 0x008001c0, 0x00000000, 0x00000000, // RICON_ARROW_BOTTOM_FILL
0x00000000, 0x00000000, 0x01c00080, 0x07f003e0, 0x1ffc0ff8, 0x00000000, 0x00000000, 0x00000000, // RICON_ARROW_TOP_FILL
0x00000000, 0x18a008c0, 0x32881290, 0x24822686, 0x26862482, 0x12903288, 0x08c018a0, 0x00000000, // RICON_AUDIO
0x00000000, 0x04800780, 0x004000c0, 0x662000f0, 0x08103c30, 0x130a0e18, 0x0000318e, 0x00000000, // RICON_FX
0x00000000, 0x00800000, 0x08880888, 0x2aaa0a8a, 0x0a8a2aaa, 0x08880888, 0x00000080, 0x00000000, // RICON_WAVE
0x00000000, 0x00600000, 0x01080090, 0x02040108, 0x42044204, 0x24022402, 0x00001800, 0x00000000, // RICON_WAVE_SINUS
0x00000000, 0x07f80000, 0x04080408, 0x04080408, 0x04080408, 0x7c0e0408, 0x00000000, 0x00000000, // RICON_WAVE_SQUARE
0x00000000, 0x00000000, 0x00a00040, 0x22084110, 0x08021404, 0x00000000, 0x00000000, 0x00000000, // RICON_WAVE_TRIANGULAR
0x00000000, 0x00000000, 0x04200000, 0x01800240, 0x02400180, 0x00000420, 0x00000000, 0x00000000, // RICON_CROSS_SMALL
0x00000000, 0x18380000, 0x12281428, 0x10a81128, 0x112810a8, 0x14281228, 0x00001838, 0x00000000, // RICON_PLAYER_PREVIOUS
0x00000000, 0x18000000, 0x11801600, 0x10181060, 0x10601018, 0x16001180, 0x00001800, 0x00000000, // RICON_PLAYER_PLAY_BACK
0x00000000, 0x00180000, 0x01880068, 0x18080608, 0x06081808, 0x00680188, 0x00000018, 0x00000000, // RICON_PLAYER_PLAY
0x00000000, 0x1e780000, 0x12481248, 0x12481248, 0x12481248, 0x12481248, 0x00001e78, 0x00000000, // RICON_PLAYER_PAUSE
0x00000000, 0x1ff80000, 0x10081008, 0x10081008, 0x10081008, 0x10081008, 0x00001ff8, 0x00000000, // RICON_PLAYER_STOP
0x00000000, 0x1c180000, 0x14481428, 0x15081488, 0x14881508, 0x14281448, 0x00001c18, 0x00000000, // RICON_PLAYER_NEXT
0x00000000, 0x03c00000, 0x08100420, 0x10081008, 0x10081008, 0x04200810, 0x000003c0, 0x00000000, // RICON_PLAYER_RECORD
0x00000000, 0x0c3007e0, 0x13c81818, 0x14281668, 0x14281428, 0x1c381c38, 0x08102244, 0x00000000, // RICON_MAGNET
0x07c00000, 0x08200820, 0x3ff80820, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000, // RICON_LOCK_CLOSE
0x07c00000, 0x08000800, 0x3ff80800, 0x23882008, 0x21082388, 0x20082108, 0x1ff02008, 0x00000000, // RICON_LOCK_OPEN
0x01c00000, 0x0c180770, 0x3086188c, 0x60832082, 0x60034781, 0x30062002, 0x0c18180c, 0x01c00770, // RICON_CLOCK
0x0a200000, 0x1b201b20, 0x04200e20, 0x04200420, 0x04700420, 0x0e700e70, 0x0e700e70, 0x04200e70, // RICON_TOOLS
0x01800000, 0x3bdc318c, 0x0ff01ff8, 0x7c3e1e78, 0x1e787c3e, 0x1ff80ff0, 0x318c3bdc, 0x00000180, // RICON_GEAR
0x01800000, 0x3ffc318c, 0x1c381ff8, 0x781e1818, 0x1818781e, 0x1ff81c38, 0x318c3ffc, 0x00000180, // RICON_GEAR_BIG
0x00000000, 0x08080ff8, 0x08081ffc, 0x0aa80aa8, 0x0aa80aa8, 0x0aa80aa8, 0x08080aa8, 0x00000ff8, // RICON_BIN
0x00000000, 0x00000000, 0x20043ffc, 0x08043f84, 0x04040f84, 0x04040784, 0x000007fc, 0x00000000, // RICON_HAND_POINTER
0x00000000, 0x24400400, 0x00001480, 0x6efe0e00, 0x00000e00, 0x24401480, 0x00000400, 0x00000000, // RICON_LASER
0x00000000, 0x03c00000, 0x08300460, 0x11181118, 0x11181118, 0x04600830, 0x000003c0, 0x00000000, // RICON_COIN
0x00000000, 0x10880080, 0x06c00810, 0x366c07e0, 0x07e00240, 0x00001768, 0x04200240, 0x00000000, // RICON_EXPLOSION
0x00000000, 0x3d280000, 0x2528252c, 0x3d282528, 0x05280528, 0x05e80528, 0x00000000, 0x00000000, // RICON_1UP
0x01800000, 0x03c003c0, 0x018003c0, 0x0ff007e0, 0x0bd00bd0, 0x0a500bd0, 0x02400240, 0x02400240, // RICON_PLAYER
0x01800000, 0x03c003c0, 0x118013c0, 0x03c81ff8, 0x07c003c8, 0x04400440, 0x0c080478, 0x00000000, // RICON_PLAYER_JUMP
0x3ff80000, 0x30183ff8, 0x30183018, 0x3ff83ff8, 0x03000300, 0x03c003c0, 0x03e00300, 0x000003e0, // RICON_KEY
0x3ff80000, 0x3ff83ff8, 0x33983ff8, 0x3ff83398, 0x3ff83ff8, 0x00000540, 0x0fe00aa0, 0x00000fe0, // RICON_DEMON
0x00000000, 0x0ff00000, 0x20041008, 0x25442004, 0x10082004, 0x06000bf0, 0x00000300, 0x00000000, // RICON_TEXT_POPUP
0x00000000, 0x11440000, 0x07f00be8, 0x1c1c0e38, 0x1c1c0c18, 0x07f00e38, 0x11440be8, 0x00000000, // RICON_GEAR_EX
0x00000000, 0x20080000, 0x0c601010, 0x07c00fe0, 0x07c007c0, 0x0c600fe0, 0x20081010, 0x00000000, // RICON_CRACK
0x00000000, 0x20080000, 0x0c601010, 0x04400fe0, 0x04405554, 0x0c600fe0, 0x20081010, 0x00000000, // RICON_CRACK_POINTS
0x00000000, 0x00800080, 0x01c001c0, 0x1ffc3ffe, 0x03e007f0, 0x07f003e0, 0x0c180770, 0x00000808, // RICON_STAR
0x0ff00000, 0x08180810, 0x08100818, 0x0a100810, 0x08180810, 0x08100818, 0x08100810, 0x00001ff8, // RICON_DOOR
0x0ff00000, 0x08100810, 0x08100810, 0x10100010, 0x4f902010, 0x10102010, 0x08100010, 0x00000ff0, // RICON_EXIT
0x00040000, 0x001f000e, 0x0ef40004, 0x12f41284, 0x0ef41214, 0x10040004, 0x7ffc3004, 0x10003000, // RICON_MODE_2D
0x78040000, 0x501f600e, 0x0ef44004, 0x12f41284, 0x0ef41284, 0x10140004, 0x7ffc300c, 0x10003000, // RICON_MODE_3D
0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe, // RICON_CUBE
0x7fe00000, 0x5ff87ff0, 0x47fe4ffc, 0x44224402, 0x44224422, 0x241275e2, 0x0c06140a, 0x000007fe, // RICON_CUBE_FACE_TOP
0x7fe00000, 0x50386030, 0x47fe483c, 0x443e443e, 0x443e443e, 0x241e75fe, 0x0c06140e, 0x000007fe, // RICON_CUBE_FACE_LEFT
0x7fe00000, 0x50286030, 0x47fe4804, 0x47fe47fe, 0x47fe47fe, 0x27fe77fe, 0x0ffe17fe, 0x000007fe, // RICON_CUBE_FACE_FRONT
0x7fe00000, 0x50286030, 0x47fe4804, 0x44224402, 0x44224422, 0x3ff27fe2, 0x0ffe1ffa, 0x000007fe, // RICON_CUBE_FACE_BOTTOM
0x7fe00000, 0x70286030, 0x7ffe7804, 0x7c227c02, 0x7c227c22, 0x3c127de2, 0x0c061c0a, 0x000007fe, // RICON_CUBE_FACE_RIGHT
0x7fe00000, 0x7fe87ff0, 0x7ffe7fe4, 0x7fe27fe2, 0x7fe27fe2, 0x24127fe2, 0x0c06140a, 0x000007fe, // RICON_CUBE_FACE_BACK
0x00000000, 0x2a0233fe, 0x22022602, 0x22022202, 0x2a022602, 0x00a033fe, 0x02080110, 0x00000000, // RICON_CAMERA
0x00000000, 0x200c3ffc, 0x000c000c, 0x3ffc000c, 0x30003000, 0x30003000, 0x3ffc3004, 0x00000000, // RICON_SPECIAL
0x00000000, 0x0022003e, 0x012201e2, 0x0100013e, 0x01000100, 0x79000100, 0x4f004900, 0x00007800, // RICON_LINK_NET
0x00000000, 0x44007c00, 0x45004600, 0x00627cbe, 0x00620022, 0x45007cbe, 0x44004600, 0x00007c00, // RICON_LINK_BOXES
0x00000000, 0x0044007c, 0x0010007c, 0x3f100010, 0x3f1021f0, 0x3f100010, 0x3f0021f0, 0x00000000, // RICON_LINK_MULTI
0x00000000, 0x0044007c, 0x00440044, 0x0010007c, 0x00100010, 0x44107c10, 0x440047f0, 0x00007c00, // RICON_LINK
0x00000000, 0x0044007c, 0x00440044, 0x0000007c, 0x00000010, 0x44007c10, 0x44004550, 0x00007c00, // RICON_LINK_BROKE
0x02a00000, 0x22a43ffc, 0x20042004, 0x20042ff4, 0x20042ff4, 0x20042ff4, 0x20042004, 0x00003ffc, // RICON_TEXT_NOTES
0x3ffc0000, 0x20042004, 0x245e27c4, 0x27c42444, 0x2004201e, 0x201e2004, 0x20042004, 0x00003ffc, // RICON_NOTEBOOK
0x00000000, 0x07e00000, 0x04200420, 0x24243ffc, 0x24242424, 0x24242424, 0x3ffc2424, 0x00000000, // RICON_SUITCASE
0x00000000, 0x0fe00000, 0x08200820, 0x40047ffc, 0x7ffc5554, 0x40045554, 0x7ffc4004, 0x00000000, // RICON_SUITCASE_ZIP
0x00000000, 0x20043ffc, 0x3ffc2004, 0x13c81008, 0x100813c8, 0x10081008, 0x1ff81008, 0x00000000, // RICON_MAILBOX
0x00000000, 0x40027ffe, 0x5ffa5ffa, 0x5ffa5ffa, 0x40025ffa, 0x03c07ffe, 0x1ff81ff8, 0x00000000, // RICON_MONITOR
0x0ff00000, 0x6bfe7ffe, 0x7ffe7ffe, 0x68167ffe, 0x08106816, 0x08100810, 0x0ff00810, 0x00000000, // RICON_PRINTER
0x3ff80000, 0xfffe2008, 0x870a8002, 0x904a888a, 0x904a904a, 0x870a888a, 0xfffe8002, 0x00000000, // RICON_PHOTO_CAMERA
0x0fc00000, 0xfcfe0cd8, 0x8002fffe, 0x84428382, 0x84428442, 0x80028382, 0xfffe8002, 0x00000000, // RICON_PHOTO_CAMERA_FLASH
0x00000000, 0x02400180, 0x08100420, 0x20041008, 0x23c42004, 0x22442244, 0x3ffc2244, 0x00000000, // RICON_HOUSE
0x00000000, 0x1c700000, 0x3ff83ef8, 0x3ff83ff8, 0x0fe01ff0, 0x038007c0, 0x00000100, 0x00000000, // RICON_HEART
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x80000000, 0xe000c000, // RICON_CORNER
0x00000000, 0x14001c00, 0x15c01400, 0x15401540, 0x155c1540, 0x15541554, 0x1ddc1554, 0x00000000, // RICON_VERTICAL_BARS
0x00000000, 0x03000300, 0x1b001b00, 0x1b601b60, 0x1b6c1b60, 0x1b6c1b6c, 0x1b6c1b6c, 0x00000000, // RICON_VERTICAL_BARS_FILL
0x00000000, 0x00000000, 0x403e7ffe, 0x7ffe403e, 0x7ffe0000, 0x43fe43fe, 0x00007ffe, 0x00000000, // RICON_LIFE_BARS
0x7ffc0000, 0x43844004, 0x43844284, 0x43844004, 0x42844284, 0x42844284, 0x40044384, 0x00007ffc, // RICON_INFO
0x40008000, 0x10002000, 0x04000800, 0x01000200, 0x00400080, 0x00100020, 0x00040008, 0x00010002, // RICON_CROSSLINE
0x00000000, 0x1ff01ff0, 0x18301830, 0x1f001830, 0x03001f00, 0x00000300, 0x03000300, 0x00000000, // RICON_HELP
0x3ff00000, 0x2abc3550, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x2aac3554, 0x00003ffc, // RICON_FILETYPE_ALPHA
0x3ff00000, 0x201c2010, 0x22442184, 0x28142424, 0x29942814, 0x2ff42994, 0x20042004, 0x00003ffc, // RICON_FILETYPE_HOME
0x07fe0000, 0x04020402, 0x7fe20402, 0x44224422, 0x44224422, 0x402047fe, 0x40204020, 0x00007fe0, // RICON_LAYERS_VISIBLE
0x07fe0000, 0x04020402, 0x7c020402, 0x44024402, 0x44024402, 0x402047fe, 0x40204020, 0x00007fe0, // RICON_LAYERS
0x00000000, 0x40027ffe, 0x7ffe4002, 0x40024002, 0x40024002, 0x40024002, 0x7ffe4002, 0x00000000, // RICON_WINDOW
0x09100000, 0x09f00910, 0x09100910, 0x00000910, 0x24a2779e, 0x27a224a2, 0x709e20a2, 0x00000000, // RICON_HIDPI
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_200
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_201
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_202
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_203
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_204
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_205
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_206
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_207
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_208
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_209
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_210
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_211
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_212
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_213
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_214
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_215
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_216
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_217
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_218
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_219
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_220
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_221
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_222
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_223
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_224
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_225
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_226
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_227
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_228
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_229
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_230
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_231
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_232
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_233
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_234
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_235
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_236
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_237
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_238
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_239
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_240
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_241
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_242
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_243
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_244
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_245
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_246
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_247
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_248
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_249
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_250
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_251
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_252
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_253
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_254
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, // RICON_255
};
#endif // RICONS_IMPLEMENTATION

View File

@ -276,7 +276,10 @@ static void __InsertMemNode(MemPool *const mempool, AllocList *const list, MemNo
mempool->arena.offs += iter->size;
__RemoveMemNode(list, iter);
iter = list->head;
if (iter == NULL) return;
if (iter == NULL) {
list->head = node;
return;
}
}
const uintptr_t inode = ( uintptr_t )node;
const uintptr_t iiter = ( uintptr_t )iter;
@ -293,6 +296,14 @@ static void __InsertMemNode(MemPool *const mempool, AllocList *const list, MemNo
iter->size += node->size;
return;
}
else if (iter->next == NULL)
{
// we reached the end of the free list -> append the node
iter->next = node;
node->prev = iter;
list->len++;
return;
}
}
else if (iter > node)
{
@ -326,7 +337,7 @@ static void __InsertMemNode(MemPool *const mempool, AllocList *const list, MemNo
}
else
{
__InsertMemNodeBefore(list, iter, node);
__InsertMemNodeBefore(list, node, iter);
list->len++;
return;
}

View File

@ -118,7 +118,7 @@ void UpdateGestures(void); // Update gestures detec
void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
bool IsGestureDetected(int gesture); // Check if a gesture have been detected
int GetGestureDetected(void); // Get latest detected gesture
int GetTouchPointsCount(void); // Get touch points count
int GetTouchPointCount(void); // Get touch points count
float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
Vector2 GetGestureDragVector(void); // Get gesture drag vector
float GetGestureDragAngle(void); // Get gesture drag angle
@ -431,7 +431,7 @@ void UpdateGestures(void)
}
// Get number of touch points
int GetTouchPointsCount(void)
int GetTouchPointCount(void)
{
// NOTE: point count is calculated when ProcessGestureEvent(GestureEvent event) is called

View File

@ -8,6 +8,8 @@
* #define SUPPORT_FILEFORMAT_MTL
* #define SUPPORT_FILEFORMAT_IQM
* #define SUPPORT_FILEFORMAT_GLTF
* #define SUPPORT_FILEFORMAT_VOX
*
* Selected desired fileformats to be supported for model data loading.
*
* #define SUPPORT_MESH_GENERATION
@ -71,6 +73,13 @@
#include "external/stb_image.h" // glTF texture images loading
#endif
#if defined(SUPPORT_FILEFORMAT_VOX)
// TODO: Support custom memory allocators
#define VOX_LOADER_IMPLEMENTATION
#include "external/vox_loader.h" // vox file format loading (MagikaVoxel)
#endif
#if defined(SUPPORT_MESH_GENERATION)
#define PAR_MALLOC(T, N) ((T*)RL_MALLOC(N*sizeof(T)))
#define PAR_CALLOC(T, N) ((T*)RL_CALLOC(N*sizeof(T), 1))
@ -123,13 +132,16 @@ static ModelAnimation *LoadIQMModelAnimations(const char *fileName, int *animCou
static Model LoadGLTF(const char *fileName); // Load GLTF mesh data
static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCount); // Load GLTF animation data
static void LoadGLTFMaterial(Model *model, const char *fileName, const cgltf_data *data);
static void LoadGLTFMesh(cgltf_data *data, cgltf_mesh* mesh, Model* outModel, Matrix currentTransform, int* primitiveIndex, const char *fileName);
static void LoadGLTFNode(cgltf_data *data, cgltf_node* node, Model* outModel, Matrix currentTransform, int* primitiveIndex, const char *fileName);
static void LoadGLTFMesh(cgltf_data *data, cgltf_mesh *mesh, Model *outModel, Matrix currentTransform, int *primitiveIndex, const char *fileName);
static void LoadGLTFNode(cgltf_data *data, cgltf_node *node, Model *outModel, Matrix currentTransform, int *primitiveIndex, const char *fileName);
static void InitGLTFBones(Model *model, const cgltf_data *data);
static void BindGLTFPrimitiveToBones(Model *model, const cgltf_data *data, int primitiveIndex);
static void GetGLTFPrimitiveCount(cgltf_node* node, int* outCount);
static bool ReadGLTFValue(cgltf_accessor* acc, unsigned int index, void *variable);
static void *ReadGLTFValuesAs(cgltf_accessor* acc, cgltf_component_type type, bool adjustOnDownCasting);
static void GetGLTFPrimitiveCount(cgltf_node *node, int *outCount);
static bool ReadGLTFValue(cgltf_accessor *acc, unsigned int index, void *variable);
static void *ReadGLTFValuesAs(cgltf_accessor *acc, cgltf_component_type type, bool adjustOnDownCasting);
#endif
#if defined(SUPPORT_FILEFORMAT_VOX)
static Model LoadVOX(const char *filename); // Load VOX mesh data
#endif
//----------------------------------------------------------------------------------
@ -201,16 +213,16 @@ void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color)
}
// Draw a triangle strip defined by points
void DrawTriangleStrip3D(Vector3 *points, int pointsCount, Color color)
void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color)
{
if (pointsCount >= 3)
if (pointCount >= 3)
{
rlCheckRenderBatchLimit(3*(pointsCount - 2));
rlCheckRenderBatchLimit(3*(pointCount - 2));
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
for (int i = 2; i < pointsCount; i++)
for (int i = 2; i < pointCount; i++)
{
if ((i%2) == 0)
{
@ -718,6 +730,9 @@ Model LoadModel(const char *fileName)
#if defined(SUPPORT_FILEFORMAT_GLTF)
if (IsFileExtension(fileName, ".gltf;.glb")) model = LoadGLTF(fileName);
#endif
#if defined(SUPPORT_FILEFORMAT_VOX)
if (IsFileExtension(fileName, ".vox")) model = LoadVOX(fileName);
#endif
// Make sure model transform is set to identity matrix!
model.transform = MatrixIdentity();
@ -972,12 +987,6 @@ void UpdateMeshBuffer(Mesh mesh, int index, void *data, int dataSize, int offset
// Draw a 3d mesh with material and transform
void DrawMesh(Mesh mesh, Material material, Matrix transform)
{
DrawMeshInstanced(mesh, material, &transform, 1);
}
// Draw multiple mesh instances with material and different transforms
void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int instances)
{
#if defined(GRAPHICS_API_OPENGL_11)
#define GL_VERTEX_ARRAY 0x8074
@ -993,7 +1002,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int ins
rlEnableStatePointer(GL_COLOR_ARRAY, mesh.colors);
rlPushMatrix();
rlMultMatrixf(MatrixToFloat(transforms[0]));
rlMultMatrixf(MatrixToFloat(transform));
rlColor4ub(material.maps[MATERIAL_MAP_DIFFUSE].color.r,
material.maps[MATERIAL_MAP_DIFFUSE].color.g,
material.maps[MATERIAL_MAP_DIFFUSE].color.b,
@ -1012,13 +1021,6 @@ void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int ins
#endif
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Check instancing
bool instancing = false;
if (instances < 1) return;
else if (instances > 1) instancing = true;
float16 *instanceTransforms = NULL;
unsigned int instancesVboId = 0;
// Bind shader program
rlEnableShader(material.shader.id);
@ -1064,51 +1066,16 @@ void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int ins
if (material.shader.locs[SHADER_LOC_MATRIX_VIEW] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_VIEW], matView);
if (material.shader.locs[SHADER_LOC_MATRIX_PROJECTION] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_PROJECTION], matProjection);
if (instancing)
{
// Create instances buffer
instanceTransforms = (float16 *)RL_MALLOC(instances*sizeof(float16));
// Model transformation matrix is send to shader uniform location: SHADER_LOC_MATRIX_MODEL
if (material.shader.locs[SHADER_LOC_MATRIX_MODEL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MODEL], transform);
// Fill buffer with instances transformations as float16 arrays
for (int i = 0; i < instances; i++) instanceTransforms[i] = MatrixToFloatV(transforms[i]);
// Accumulate several model transformations:
// transform: model transformation provided (includes DrawModel() params combined with model.transform)
// rlGetMatrixTransform(): rlgl internal transform matrix due to push/pop matrix stack
matModel = MatrixMultiply(transform, rlGetMatrixTransform());
// Enable mesh VAO to attach new buffer
rlEnableVertexArray(mesh.vaoId);
// This could alternatively use a static VBO and either glMapBuffer() or glBufferSubData().
// It isn't clear which would be reliably faster in all cases and on all platforms,
// anecdotally glMapBuffer() seems very slow (syncs) while glBufferSubData() seems
// no faster, since we're transferring all the transform matrices anyway
instancesVboId = rlLoadVertexBuffer(instanceTransforms, instances*sizeof(float16), false);
// Instances transformation matrices are send to shader attribute location: SHADER_LOC_MATRIX_MODEL
for (unsigned int i = 0; i < 4; i++)
{
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 4, RL_FLOAT, 0, sizeof(Matrix), (void *)(i*sizeof(Vector4)));
rlSetVertexAttributeDivisor(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 1);
}
rlDisableVertexBuffer();
rlDisableVertexArray();
// Accumulate internal matrix transform (push/pop) and view matrix
// NOTE: In this case, model instance transformation must be computed in the shader
matModelView = MatrixMultiply(rlGetMatrixTransform(), matView);
}
else
{
// Model transformation matrix is send to shader uniform location: SHADER_LOC_MATRIX_MODEL
if (material.shader.locs[SHADER_LOC_MATRIX_MODEL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MODEL], transforms[0]);
// Accumulate several model transformations:
// transforms[0]: model transformation provided (includes DrawModel() params combined with model.transform)
// rlGetMatrixTransform(): rlgl internal transform matrix due to push/pop matrix stack
matModel = MatrixMultiply(transforms[0], rlGetMatrixTransform());
// Get model-view matrix
matModelView = MatrixMultiply(matModel, matView);
}
// Get model-view matrix
matModelView = MatrixMultiply(matModel, matView);
// Upload model normal matrix (if locations available)
if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));
@ -1192,14 +1159,14 @@ void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int ins
if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[6]);
}
int eyesCount = 1;
if (rlIsStereoRenderEnabled()) eyesCount = 2;
int eyeCount = 1;
if (rlIsStereoRenderEnabled()) eyeCount = 2;
for (int eye = 0; eye < eyesCount; eye++)
for (int eye = 0; eye < eyeCount; eye++)
{
// Calculate model-view-projection matrix (MVP)
Matrix matModelViewProjection = MatrixIdentity();
if (eyesCount == 1) matModelViewProjection = MatrixMultiply(matModelView, matProjection);
if (eyeCount == 1) matModelViewProjection = MatrixMultiply(matModelView, matProjection);
else
{
// Setup current eye viewport (half screen width)
@ -1210,16 +1177,9 @@ void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int ins
// Send combined model-view-projection matrix to shader
rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MVP], matModelViewProjection);
if (instancing) // Draw mesh instanced
{
if (mesh.indices != NULL) rlDrawVertexArrayElementsInstanced(0, mesh.triangleCount*3, 0, instances);
else rlDrawVertexArrayInstanced(0, mesh.vertexCount, instances);
}
else // Draw mesh
{
if (mesh.indices != NULL) rlDrawVertexArrayElements(0, mesh.triangleCount*3, 0);
else rlDrawVertexArray(0, mesh.vertexCount);
}
// Draw mesh
if (mesh.indices != NULL) rlDrawVertexArrayElements(0, mesh.triangleCount*3, 0);
else rlDrawVertexArray(0, mesh.vertexCount);
}
// Unbind all binded texture maps
@ -1243,18 +1203,224 @@ void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int ins
// Disable shader program
rlDisableShader();
if (instancing)
// Restore rlgl internal modelview and projection matrices
rlSetMatrixModelview(matView);
rlSetMatrixProjection(matProjection);
#endif
}
// Draw multiple mesh instances with material and different transforms
void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int instances)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Instancing required variables
float16 *instanceTransforms = NULL;
unsigned int instancesVboId = 0;
// Bind shader program
rlEnableShader(material.shader.id);
// Send required data to shader (matrices, values)
//-----------------------------------------------------
// Upload to shader material.colDiffuse
if (material.shader.locs[SHADER_LOC_COLOR_DIFFUSE] != -1)
{
// Remove instance transforms buffer
rlUnloadVertexBuffer(instancesVboId);
RL_FREE(instanceTransforms);
float values[4] = {
(float)material.maps[MATERIAL_MAP_DIFFUSE].color.r/255.0f,
(float)material.maps[MATERIAL_MAP_DIFFUSE].color.g/255.0f,
(float)material.maps[MATERIAL_MAP_DIFFUSE].color.b/255.0f,
(float)material.maps[MATERIAL_MAP_DIFFUSE].color.a/255.0f
};
rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_DIFFUSE], values, SHADER_UNIFORM_VEC4, 1);
}
else
// Upload to shader material.colSpecular (if location available)
if (material.shader.locs[SHADER_LOC_COLOR_SPECULAR] != -1)
{
// Restore rlgl internal modelview and projection matrices
rlSetMatrixModelview(matView);
rlSetMatrixProjection(matProjection);
float values[4] = {
(float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.r/255.0f,
(float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.g/255.0f,
(float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.b/255.0f,
(float)material.maps[SHADER_LOC_COLOR_SPECULAR].color.a/255.0f
};
rlSetUniform(material.shader.locs[SHADER_LOC_COLOR_SPECULAR], values, SHADER_UNIFORM_VEC4, 1);
}
// Get a copy of current matrices to work with,
// just in case stereo render is required and we need to modify them
// NOTE: At this point the modelview matrix just contains the view matrix (camera)
// That's because BeginMode3D() sets it and there is no model-drawing function
// that modifies it, all use rlPushMatrix() and rlPopMatrix()
Matrix matModel = MatrixIdentity();
Matrix matView = rlGetMatrixModelview();
Matrix matModelView = MatrixIdentity();
Matrix matProjection = rlGetMatrixProjection();
// Upload view and projection matrices (if locations available)
if (material.shader.locs[SHADER_LOC_MATRIX_VIEW] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_VIEW], matView);
if (material.shader.locs[SHADER_LOC_MATRIX_PROJECTION] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_PROJECTION], matProjection);
// Create instances buffer
instanceTransforms = (float16 *)RL_MALLOC(instances*sizeof(float16));
// Fill buffer with instances transformations as float16 arrays
for (int i = 0; i < instances; i++) instanceTransforms[i] = MatrixToFloatV(transforms[i]);
// Enable mesh VAO to attach new buffer
rlEnableVertexArray(mesh.vaoId);
// This could alternatively use a static VBO and either glMapBuffer() or glBufferSubData().
// It isn't clear which would be reliably faster in all cases and on all platforms,
// anecdotally glMapBuffer() seems very slow (syncs) while glBufferSubData() seems
// no faster, since we're transferring all the transform matrices anyway
instancesVboId = rlLoadVertexBuffer(instanceTransforms, instances*sizeof(float16), false);
// Instances transformation matrices are send to shader attribute location: SHADER_LOC_MATRIX_MODEL
for (unsigned int i = 0; i < 4; i++)
{
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 4, RL_FLOAT, 0, sizeof(Matrix), (void *)(i*sizeof(Vector4)));
rlSetVertexAttributeDivisor(material.shader.locs[SHADER_LOC_MATRIX_MODEL] + i, 1);
}
rlDisableVertexBuffer();
rlDisableVertexArray();
// Accumulate internal matrix transform (push/pop) and view matrix
// NOTE: In this case, model instance transformation must be computed in the shader
matModelView = MatrixMultiply(rlGetMatrixTransform(), matView);
// Upload model normal matrix (if locations available)
if (material.shader.locs[SHADER_LOC_MATRIX_NORMAL] != -1) rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_NORMAL], MatrixTranspose(MatrixInvert(matModel)));
//-----------------------------------------------------
// Bind active texture maps (if available)
for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
{
if (material.maps[i].texture.id > 0)
{
// Select current shader texture slot
rlActiveTextureSlot(i);
// Enable texture for active slot
if ((i == MATERIAL_MAP_IRRADIANCE) ||
(i == MATERIAL_MAP_PREFILTER) ||
(i == MATERIAL_MAP_CUBEMAP)) rlEnableTextureCubemap(material.maps[i].texture.id);
else rlEnableTexture(material.maps[i].texture.id);
rlSetUniform(material.shader.locs[SHADER_LOC_MAP_DIFFUSE + i], &i, SHADER_UNIFORM_INT, 1);
}
}
// Try binding vertex array objects (VAO)
// or use VBOs if not possible
if (!rlEnableVertexArray(mesh.vaoId))
{
// Bind mesh VBO data: vertex position (shader-location = 0)
rlEnableVertexBuffer(mesh.vboId[0]);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
// Bind mesh VBO data: vertex texcoords (shader-location = 1)
rlEnableVertexBuffer(mesh.vboId[1]);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01]);
if (material.shader.locs[SHADER_LOC_VERTEX_NORMAL] != -1)
{
// Bind mesh VBO data: vertex normals (shader-location = 2)
rlEnableVertexBuffer(mesh.vboId[2]);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL], 3, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_NORMAL]);
}
// Bind mesh VBO data: vertex colors (shader-location = 3, if available)
if (material.shader.locs[SHADER_LOC_VERTEX_COLOR] != -1)
{
if (mesh.vboId[3] != 0)
{
rlEnableVertexBuffer(mesh.vboId[3]);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR], 4, RL_UNSIGNED_BYTE, 1, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
}
else
{
// Set default value for unused attribute
// NOTE: Required when using default shader and no VAO support
float value[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
rlSetVertexAttributeDefault(material.shader.locs[SHADER_LOC_VERTEX_COLOR], value, SHADER_ATTRIB_VEC2, 4);
rlDisableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_COLOR]);
}
}
// Bind mesh VBO data: vertex tangents (shader-location = 4, if available)
if (material.shader.locs[SHADER_LOC_VERTEX_TANGENT] != -1)
{
rlEnableVertexBuffer(mesh.vboId[4]);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT], 4, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TANGENT]);
}
// Bind mesh VBO data: vertex texcoords2 (shader-location = 5, if available)
if (material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02] != -1)
{
rlEnableVertexBuffer(mesh.vboId[5]);
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02], 2, RL_FLOAT, 0, 0, 0);
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD02]);
}
if (mesh.indices != NULL) rlEnableVertexBufferElement(mesh.vboId[6]);
}
int eyeCount = 1;
if (rlIsStereoRenderEnabled()) eyeCount = 2;
for (int eye = 0; eye < eyeCount; eye++)
{
// Calculate model-view-projection matrix (MVP)
Matrix matModelViewProjection = MatrixIdentity();
if (eyeCount == 1) matModelViewProjection = MatrixMultiply(matModelView, matProjection);
else
{
// Setup current eye viewport (half screen width)
rlViewport(eye*rlGetFramebufferWidth()/2, 0, rlGetFramebufferWidth()/2, rlGetFramebufferHeight());
matModelViewProjection = MatrixMultiply(MatrixMultiply(matModelView, rlGetMatrixViewOffsetStereo(eye)), rlGetMatrixProjectionStereo(eye));
}
// Send combined model-view-projection matrix to shader
rlSetUniformMatrix(material.shader.locs[SHADER_LOC_MATRIX_MVP], matModelViewProjection);
// Draw mesh instanced
if (mesh.indices != NULL) rlDrawVertexArrayElementsInstanced(0, mesh.triangleCount*3, 0, instances);
else rlDrawVertexArrayInstanced(0, mesh.vertexCount, instances);
}
// Unbind all binded texture maps
for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
{
// Select current shader texture slot
rlActiveTextureSlot(i);
// Disable texture for active slot
if ((i == MATERIAL_MAP_IRRADIANCE) ||
(i == MATERIAL_MAP_PREFILTER) ||
(i == MATERIAL_MAP_CUBEMAP)) rlDisableTextureCubemap();
else rlDisableTexture();
}
// Disable all possible vertex array objects (or VBOs)
rlDisableVertexArray();
rlDisableVertexBuffer();
rlDisableVertexBufferElement();
// Disable shader program
rlDisableShader();
// Remove instance transforms buffer
rlUnloadVertexBuffer(instancesVboId);
RL_FREE(instanceTransforms);
#endif
}
@ -1297,43 +1463,43 @@ bool ExportMesh(Mesh mesh, const char *fileName)
// NOTE: Text data buffer size is estimated considering mesh data size
char *txtData = (char *)RL_CALLOC(dataSize + 2000, sizeof(char));
int bytesCount = 0;
bytesCount += sprintf(txtData + bytesCount, "# //////////////////////////////////////////////////////////////////////////////////\n");
bytesCount += sprintf(txtData + bytesCount, "# // //\n");
bytesCount += sprintf(txtData + bytesCount, "# // rMeshOBJ exporter v1.0 - Mesh exported as triangle faces and not optimized //\n");
bytesCount += sprintf(txtData + bytesCount, "# // //\n");
bytesCount += sprintf(txtData + bytesCount, "# // more info and bugs-report: github.com/raysan5/raylib //\n");
bytesCount += sprintf(txtData + bytesCount, "# // feedback and support: ray[at]raylib.com //\n");
bytesCount += sprintf(txtData + bytesCount, "# // //\n");
bytesCount += sprintf(txtData + bytesCount, "# // Copyright (c) 2018 Ramon Santamaria (@raysan5) //\n");
bytesCount += sprintf(txtData + bytesCount, "# // //\n");
bytesCount += sprintf(txtData + bytesCount, "# //////////////////////////////////////////////////////////////////////////////////\n\n");
bytesCount += sprintf(txtData + bytesCount, "# Vertex Count: %i\n", mesh.vertexCount);
bytesCount += sprintf(txtData + bytesCount, "# Triangle Count: %i\n\n", mesh.triangleCount);
int byteCount = 0;
byteCount += sprintf(txtData + byteCount, "# //////////////////////////////////////////////////////////////////////////////////\n");
byteCount += sprintf(txtData + byteCount, "# // //\n");
byteCount += sprintf(txtData + byteCount, "# // rMeshOBJ exporter v1.0 - Mesh exported as triangle faces and not optimized //\n");
byteCount += sprintf(txtData + byteCount, "# // //\n");
byteCount += sprintf(txtData + byteCount, "# // more info and bugs-report: github.com/raysan5/raylib //\n");
byteCount += sprintf(txtData + byteCount, "# // feedback and support: ray[at]raylib.com //\n");
byteCount += sprintf(txtData + byteCount, "# // //\n");
byteCount += sprintf(txtData + byteCount, "# // Copyright (c) 2018 Ramon Santamaria (@raysan5) //\n");
byteCount += sprintf(txtData + byteCount, "# // //\n");
byteCount += sprintf(txtData + byteCount, "# //////////////////////////////////////////////////////////////////////////////////\n\n");
byteCount += sprintf(txtData + byteCount, "# Vertex Count: %i\n", mesh.vertexCount);
byteCount += sprintf(txtData + byteCount, "# Triangle Count: %i\n\n", mesh.triangleCount);
bytesCount += sprintf(txtData + bytesCount, "g mesh\n");
byteCount += sprintf(txtData + byteCount, "g mesh\n");
for (int i = 0, v = 0; i < mesh.vertexCount; i++, v += 3)
{
bytesCount += sprintf(txtData + bytesCount, "v %.2f %.2f %.2f\n", mesh.vertices[v], mesh.vertices[v + 1], mesh.vertices[v + 2]);
byteCount += sprintf(txtData + byteCount, "v %.2f %.2f %.2f\n", mesh.vertices[v], mesh.vertices[v + 1], mesh.vertices[v + 2]);
}
for (int i = 0, v = 0; i < mesh.vertexCount; i++, v += 2)
{
bytesCount += sprintf(txtData + bytesCount, "vt %.3f %.3f\n", mesh.texcoords[v], mesh.texcoords[v + 1]);
byteCount += sprintf(txtData + byteCount, "vt %.3f %.3f\n", mesh.texcoords[v], mesh.texcoords[v + 1]);
}
for (int i = 0, v = 0; i < mesh.vertexCount; i++, v += 3)
{
bytesCount += sprintf(txtData + bytesCount, "vn %.3f %.3f %.3f\n", mesh.normals[v], mesh.normals[v + 1], mesh.normals[v + 2]);
byteCount += sprintf(txtData + byteCount, "vn %.3f %.3f %.3f\n", mesh.normals[v], mesh.normals[v + 1], mesh.normals[v + 2]);
}
for (int i = 0; i < mesh.triangleCount; i += 3)
{
bytesCount += sprintf(txtData + bytesCount, "f %i/%i/%i %i/%i/%i %i/%i/%i\n", i, i, i, i + 1, i + 1, i + 1, i + 2, i + 2, i + 2);
byteCount += sprintf(txtData + byteCount, "f %i/%i/%i %i/%i/%i %i/%i/%i\n", i, i, i, i + 1, i + 1, i + 1, i + 2, i + 2, i + 2);
}
bytesCount += sprintf(txtData + bytesCount, "\n");
byteCount += sprintf(txtData + byteCount, "\n");
// NOTE: Text data length exported is determined by '\0' (NULL) character
success = SaveFileText(fileName, txtData);
@ -3340,6 +3506,11 @@ RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Ve
//----------------------------------------------------------------------------------
#if defined(SUPPORT_FILEFORMAT_OBJ)
// Load OBJ mesh data
//
// Keep the following information in mind when reading this
// - A mesh is created for every material present in the obj file
// - the model.meshCount is therefore the materialCount returned from tinyobj
// - the mesh is automatically triangulated by tinyobj
static Model LoadOBJ(const char *fileName)
{
Model model = { 0 };
@ -3391,15 +3562,13 @@ static Model LoadOBJ(const char *fileName)
// Count the faces for each material
int *matFaces = RL_CALLOC(materialCount, sizeof(int));
for (unsigned int mi = 0; mi < meshCount; mi++)
for (int fi = 0; fi< attrib.num_faces; fi++)
{
for (unsigned int fi = 0; fi < meshes[mi].length; fi++)
{
int idx = attrib.material_ids[meshes[mi].face_offset + fi];
if (idx == -1) idx = 0; // for no material face (which could be the whole model)
matFaces[idx]++;
}
//tinyobj_vertex_index_t face = attrib.faces[fi];
int idx = attrib.material_ids[fi];
matFaces[idx]++;
}
//--------------------------------------
// Create the material meshes
@ -4705,14 +4874,14 @@ static Model LoadGLTF(const char *fileName)
if (data->scenes_count > 1) TRACELOG(LOG_INFO, "MODEL: [%s] Has multiple scenes but only the first one will be loaded", fileName);
int primitivesCount = 0;
int primitiveCount = 0;
for (unsigned int i = 0; i < data->scene->nodes_count; i++)
{
GetGLTFPrimitiveCount(data->scene->nodes[i], &primitivesCount);
GetGLTFPrimitiveCount(data->scene->nodes[i], &primitiveCount);
}
// Process glTF data and map to model
model.meshCount = primitivesCount;
model.meshCount = primitiveCount;
model.meshes = RL_CALLOC(model.meshCount, sizeof(Mesh));
model.materialCount = (int)data->materials_count + 1;
model.materials = RL_MALLOC(model.materialCount*sizeof(Material));
@ -4740,7 +4909,7 @@ static Model LoadGLTF(const char *fileName)
return model;
}
static void InitGLTFBones(Model* model, const cgltf_data* data)
static void InitGLTFBones(Model *model, const cgltf_data *data)
{
for (unsigned int j = 0; j < data->nodes_count; j++)
{
@ -4763,7 +4932,7 @@ static void InitGLTFBones(Model* model, const cgltf_data* data)
}
{
bool* completedBones = RL_CALLOC(model->boneCount, sizeof(bool));
bool *completedBones = RL_CALLOC(model->boneCount, sizeof(bool));
int numberCompletedBones = 0;
while (numberCompletedBones < model->boneCount)
@ -4871,7 +5040,7 @@ static void LoadGLTFMaterial(Model *model, const char *fileName, const cgltf_dat
model->materials[model->materialCount - 1] = LoadMaterialDefault();
}
static void BindGLTFPrimitiveToBones(Model* model, const cgltf_data* data, int primitiveIndex)
static void BindGLTFPrimitiveToBones(Model *model, const cgltf_data *data, int primitiveIndex)
{
for (unsigned int nodeId = 0; nodeId < data->nodes_count; nodeId++)
{
@ -4879,12 +5048,12 @@ static void BindGLTFPrimitiveToBones(Model* model, const cgltf_data* data, int p
{
if (model->meshes[primitiveIndex].boneIds == NULL)
{
model->meshes[primitiveIndex].boneIds = RL_CALLOC(4*model->meshes[primitiveIndex].vertexCount, sizeof(int));
model->meshes[primitiveIndex].boneWeights = RL_CALLOC(4*model->meshes[primitiveIndex].vertexCount, sizeof(float));
model->meshes[primitiveIndex].boneIds = RL_CALLOC(model->meshes[primitiveIndex].vertexCount*4, sizeof(int));
model->meshes[primitiveIndex].boneWeights = RL_CALLOC(model->meshes[primitiveIndex].vertexCount*4, sizeof(float));
for (int b = 0; b < 4*model->meshes[primitiveIndex].vertexCount; b++)
for (int b = 0; b < model->meshes[primitiveIndex].vertexCount*4; b++)
{
if (b % 4 == 0)
if (b%4 == 0)
{
model->meshes[primitiveIndex].boneIds[b] = nodeId;
model->meshes[primitiveIndex].boneWeights[b] = 1.0f;
@ -4961,7 +5130,7 @@ static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCo
// Getting the max animation time to consider for animation duration
for (unsigned int i = 0; i < animation->channels_count; i++)
{
cgltf_animation_channel* channel = animation->channels + i;
cgltf_animation_channel *channel = animation->channels + i;
int frameCounts = (int)channel->sampler->input->count;
float lastFrameTime = 0.0f;
@ -5008,8 +5177,8 @@ static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCo
// for each single transformation type on single bone
for (unsigned int channelId = 0; channelId < animation->channels_count; channelId++)
{
cgltf_animation_channel* channel = animation->channels + channelId;
cgltf_animation_sampler* sampler = channel->sampler;
cgltf_animation_channel *channel = animation->channels + channelId;
cgltf_animation_sampler *sampler = channel->sampler;
int boneId = (int)(channel->target_node - data->nodes);
@ -5167,7 +5336,7 @@ static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCo
return animations;
}
void LoadGLTFMesh(cgltf_data* data, cgltf_mesh* mesh, Model* outModel, Matrix currentTransform, int* primitiveIndex, const char *fileName)
void LoadGLTFMesh(cgltf_data *data, cgltf_mesh *mesh, Model *outModel, Matrix currentTransform, int *primitiveIndex, const char *fileName)
{
for (unsigned int p = 0; p < mesh->primitives_count; p++)
{
@ -5292,22 +5461,56 @@ void LoadGLTFMesh(cgltf_data* data, cgltf_mesh* mesh, Model* outModel, Matrix cu
}
}
void LoadGLTFNode(cgltf_data* data, cgltf_node* node, Model* outModel, Matrix currentTransform, int* primitiveIndex, const char *fileName)
static Matrix GetNodeTransformationMatrix(cgltf_node *node, Matrix current)
{
Matrix nodeTransform = {
if (node->has_matrix)
{
Matrix nodeTransform = {
node->matrix[0], node->matrix[4], node->matrix[8], node->matrix[12],
node->matrix[1], node->matrix[5], node->matrix[9], node->matrix[13],
node->matrix[2], node->matrix[6], node->matrix[10], node->matrix[14],
node->matrix[3], node->matrix[7], node->matrix[11], node->matrix[15] };
current= MatrixMultiply(nodeTransform, current);
}
if (node->has_translation)
{
Matrix tl = MatrixTranslate(node->translation[0],node->translation[1],node->translation[2]);
current = MatrixMultiply(tl, current);
}
if (node->has_rotation)
{
Matrix rot = QuaternionToMatrix((Quaternion){node->rotation[0],node->rotation[1],node->rotation[2],node->rotation[3]});
current = MatrixMultiply(rot, current);
}
if (node->has_scale)
{
Matrix scale = MatrixScale(node->scale[0],node->scale[1],node->scale[2]);
current = MatrixMultiply(scale, current);
}
return current;
}
currentTransform = MatrixMultiply(nodeTransform, currentTransform);
if (node->mesh != NULL) LoadGLTFMesh(data, node->mesh, outModel, currentTransform, primitiveIndex, fileName);
void LoadGLTFNode(cgltf_data *data, cgltf_node *node, Model *outModel, Matrix currentTransform, int *primitiveIndex, const char *fileName)
{
// Apply the transforms if they exist (Will still be applied even if no mesh is present to support emptys and bone structures)
Matrix localTransform = GetNodeTransformationMatrix(node, MatrixIdentity());
currentTransform = MatrixMultiply(localTransform, currentTransform);
// Load mesh if it exists
if (node->mesh != NULL)
{
// Check if skinning is enabled and load Mesh accordingly
Matrix vertexTransform = currentTransform;
if((node->skin != NULL) && (node->parent != NULL))
{
vertexTransform = localTransform;
TRACELOG(LOG_WARNING,"MODEL: GLTF Node %s is skinned but not root node! Parent transformations will be ignored (NODE_SKINNED_MESH_NON_ROOT)",node->name);
}
LoadGLTFMesh(data, node->mesh, outModel, vertexTransform, primitiveIndex, fileName);
}
for (unsigned int i = 0; i < node->children_count; i++) LoadGLTFNode(data, node->children[i], outModel, currentTransform, primitiveIndex, fileName);
}
static void GetGLTFPrimitiveCount(cgltf_node* node, int* outCount)
static void GetGLTFPrimitiveCount(cgltf_node *node, int *outCount)
{
if (node->mesh != NULL) *outCount += node->mesh->primitives_count;
@ -5315,3 +5518,92 @@ static void GetGLTFPrimitiveCount(cgltf_node* node, int* outCount)
}
#endif
#if defined(SUPPORT_FILEFORMAT_VOX)
// Load VOX (MagikaVoxel) mesh data
static Model LoadVOX(const char *fileName)
{
Model model = { 0 };
int nbvertices = 0;
int meshescount = 0;
VoxArray3D voxarray = { 0 };
int ret = Vox_LoadFileName(fileName, &voxarray);
if (ret != VOX_SUCCESS)
{
TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load VOX data", fileName);
return model;
}
else
{
// Compute meshes count
nbvertices = voxarray.vertices.used;
meshescount = 1 + (nbvertices/65536);
TRACELOG(LOG_INFO, "MODEL: [%s] VOX data loaded successfully : %i vertices/%i meshes", fileName, nbvertices, meshescount);
}
// Build models from meshes
model.transform = MatrixIdentity();
model.meshCount = meshescount;
model.meshes = (Mesh *)MemAlloc(model.meshCount*sizeof(Mesh));
model.meshMaterial = (int *)MemAlloc(model.meshCount*sizeof(int));
model.materialCount = 1;
model.materials = (Material *)MemAlloc(model.materialCount*sizeof(Material));
model.materials[0] = LoadMaterialDefault();
// Init model meshes
int verticesRemain = voxarray.vertices.used;
int verticesMax = 65532; // 5461 voxels x 12 vertices per voxel -> 65532 (must be inf 65536)
Vector3 *pvertices = voxarray.vertices.array; // 6*4 = 12 vertices per voxel
Color *pcolors = voxarray.colors.array;
unsigned short *pindices = voxarray.indices.array; // 5461*6*6 = 196596 indices max per mesh
int size = 0;
for (int idxMesh = 0; idxMesh < meshescount; idxMesh++)
{
Mesh *pmesh = &model.meshes[idxMesh];
memset(pmesh, 0, sizeof(Mesh));
// Copy vertices
pmesh->vertexCount = (int)fmin(verticesMax, verticesRemain);
size = pmesh->vertexCount*sizeof(float)*3;
pmesh->vertices = MemAlloc(size);
memcpy(pmesh->vertices, pvertices, size);
// Copy indices
// TODO: compute globals indices array
size = voxarray.indices.used * sizeof(unsigned short);
pmesh->indices = MemAlloc(size);
memcpy(pmesh->indices, pindices, size);
pmesh->triangleCount = (pmesh->vertexCount/4)*2;
// Copy colors
size = pmesh->vertexCount*sizeof(Color);
pmesh->colors = MemAlloc(size);
memcpy(pmesh->colors, pcolors, size);
// First material index
model.meshMaterial[idxMesh] = 0;
// Upload mesh data to GPU
UploadMesh(pmesh, false);
verticesRemain -= verticesMax;
pvertices += verticesMax;
pcolors += verticesMax;
}
Vox_FreeArrays(&voxarray);
return model;
}
#endif

View File

@ -877,14 +877,14 @@ void UnloadSound(Sound sound)
}
// Update sound buffer with new data
void UpdateSound(Sound sound, const void *data, int samplesCount)
void UpdateSound(Sound sound, const void *data, int sampleCount)
{
if (sound.stream.buffer != NULL)
{
StopAudioBuffer(sound.stream.buffer);
// TODO: May want to lock/unlock this since this data buffer is read at mixing time
memcpy(sound.stream.buffer->data, data, samplesCount*ma_get_bytes_per_frame(sound.stream.buffer->converter.config.formatIn, sound.stream.buffer->converter.config.channelsIn));
memcpy(sound.stream.buffer->data, data, sampleCount*ma_get_bytes_per_frame(sound.stream.buffer->converter.config.formatIn, sound.stream.buffer->converter.config.channelsIn));
}
}
@ -942,19 +942,19 @@ bool ExportWaveAsCode(Wave wave, const char *fileName)
// NOTE: Text data buffer size is estimated considering wave data size in bytes
// and requiring 6 char bytes for every byte: "0x00, "
char *txtData = (char *)RL_CALLOC(6*waveDataSize + 2000, sizeof(char));
char *txtData = (char *)RL_CALLOC(waveDataSize*6 + 2000, sizeof(char));
int bytesCount = 0;
bytesCount += sprintf(txtData + bytesCount, "\n//////////////////////////////////////////////////////////////////////////////////\n");
bytesCount += sprintf(txtData + bytesCount, "// //\n");
bytesCount += sprintf(txtData + bytesCount, "// WaveAsCode exporter v1.0 - Wave data exported as an array of bytes //\n");
bytesCount += sprintf(txtData + bytesCount, "// //\n");
bytesCount += sprintf(txtData + bytesCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
bytesCount += sprintf(txtData + bytesCount, "// feedback and support: ray[at]raylib.com //\n");
bytesCount += sprintf(txtData + bytesCount, "// //\n");
bytesCount += sprintf(txtData + bytesCount, "// Copyright (c) 2018 Ramon Santamaria (@raysan5) //\n");
bytesCount += sprintf(txtData + bytesCount, "// //\n");
bytesCount += sprintf(txtData + bytesCount, "//////////////////////////////////////////////////////////////////////////////////\n\n");
int byteCount = 0;
byteCount += sprintf(txtData + byteCount, "\n//////////////////////////////////////////////////////////////////////////////////\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// WaveAsCode exporter v1.0 - Wave data exported as an array of bytes //\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2021 Ramon Santamaria (@raysan5) //\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "//////////////////////////////////////////////////////////////////////////////////\n\n");
char varFileName[256] = { 0 };
#if !defined(RAUDIO_STANDALONE)
@ -965,17 +965,18 @@ bool ExportWaveAsCode(Wave wave, const char *fileName)
strcpy(varFileName, fileName);
#endif
bytesCount += sprintf(txtData + bytesCount, "// Wave data information\n");
bytesCount += sprintf(txtData + bytesCount, "#define %s_FRAME_COUNT %u\n", varFileName, wave.frameCount);
bytesCount += sprintf(txtData + bytesCount, "#define %s_SAMPLE_COUNT %u\n", varFileName, wave.frameCount*wave.channels);
bytesCount += sprintf(txtData + bytesCount, "#define %s_SAMPLE_RATE %u\n", varFileName, wave.sampleRate);
bytesCount += sprintf(txtData + bytesCount, "#define %s_SAMPLE_SIZE %u\n", varFileName, wave.sampleSize);
bytesCount += sprintf(txtData + bytesCount, "#define %s_CHANNELS %u\n\n", varFileName, wave.channels);
byteCount += sprintf(txtData + byteCount, "// Wave data information\n");
byteCount += sprintf(txtData + byteCount, "#define %s_FRAME_COUNT %u\n", varFileName, wave.frameCount);
byteCount += sprintf(txtData + byteCount, "#define %s_FRAME_COUNT %u\n", varFileName, wave.frameCount);
byteCount += sprintf(txtData + byteCount, "#define %s_SAMPLE_RATE %u\n", varFileName, wave.sampleRate);
byteCount += sprintf(txtData + byteCount, "#define %s_SAMPLE_SIZE %u\n", varFileName, wave.sampleSize);
byteCount += sprintf(txtData + byteCount, "#define %s_CHANNELS %u\n\n", varFileName, wave.channels);
// Write byte data as hexadecimal text
bytesCount += sprintf(txtData + bytesCount, "static unsigned char %s_DATA[%i] = { ", varFileName, waveDataSize);
for (int i = 0; i < waveDataSize - 1; i++) bytesCount += sprintf(txtData + bytesCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), ((unsigned char *)wave.data)[i]);
bytesCount += sprintf(txtData + bytesCount, "0x%x };\n", ((unsigned char *)wave.data)[waveDataSize - 1]);
// NOTE: Frame data exported is interlaced: Frame01[Sample-Channel01, Sample-Channel02, ...], Frame02[], Frame03[]
byteCount += sprintf(txtData + byteCount, "static unsigned char %s_DATA[%i] = { ", varFileName, waveDataSize);
for (int i = 0; i < waveDataSize - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), ((unsigned char *)wave.data)[i]);
byteCount += sprintf(txtData + byteCount, "0x%x };\n", ((unsigned char *)wave.data)[waveDataSize - 1]);
// NOTE: Text data length exported is determined by '\0' (NULL) character
success = SaveFileText(fileName, txtData);
@ -1504,9 +1505,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int d
// Copy data to allocated memory for default UnloadMusicStream
unsigned char *newData = (unsigned char *)RL_MALLOC(dataSize);
int it = dataSize/sizeof(unsigned char);
for (int i = 0; i < it; i++){
newData[i] = data[i];
}
for (int i = 0; i < it; i++) newData[i] = data[i];
// Memory loaded version for jar_mod_load_file()
if (dataSize && dataSize < 32*1024*1024)
@ -1715,7 +1714,7 @@ void UpdateMusicStream(Music music)
#if defined(SUPPORT_FILEFORMAT_XM)
case MUSIC_MODULE_XM:
{
// NOTE: Internally we consider 2 channels generation, so samplesCount/2
// NOTE: Internally we consider 2 channels generation, so sampleCount/2
if (AUDIO_DEVICE_FORMAT == ma_format_f32) jar_xm_generate_samples((jar_xm_context_t *)music.ctxData, (float *)pcm, frameCountToStream);
else if (AUDIO_DEVICE_FORMAT == ma_format_s16) jar_xm_generate_samples_16bit((jar_xm_context_t *)music.ctxData, (short *)pcm, frameCountToStream);
else if (AUDIO_DEVICE_FORMAT == ma_format_u8) jar_xm_generate_samples_8bit((jar_xm_context_t *)music.ctxData, (char *)pcm, frameCountToStream);

View File

@ -287,11 +287,11 @@ typedef struct GlyphInfo {
// Font, font texture and GlyphInfo array data
typedef struct Font {
int baseSize; // Base size (default chars height)
int charsCount; // Number of characters
int charsPadding; // Padding around the chars
Texture2D texture; // Characters texture atlas
Rectangle *recs; // Characters rectangles in texture
GlyphInfo *chars; // Characters glyphs info data
int glyphCount; // Number of glyph characters
int glyphPadding; // Padding around the glyph characters
Texture2D texture; // Texture atlas containing the glyphs
Rectangle *recs; // Rectangles in texture for the glyphs
GlyphInfo *glyphs; // Glyphs info data
} Font;
// Camera, defines position/orientation in 3d space
@ -1111,7 +1111,7 @@ RLAPI Vector2 GetTouchPosition(int index); // Get touch posit
RLAPI void SetGesturesEnabled(unsigned int flags); // Enable a set of gestures using flags
RLAPI bool IsGestureDetected(int gesture); // Check if a gesture have been detected
RLAPI int GetGestureDetected(void); // Get latest detected gesture
RLAPI int GetTouchPointsCount(void); // Get touch points count
RLAPI int GetTouchPointCount(void); // Get touch points count
RLAPI float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
RLAPI Vector2 GetGestureDragVector(void); // Get gesture drag vector
RLAPI float GetGestureDragAngle(void); // Get gesture drag angle
@ -1145,7 +1145,7 @@ RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color);
RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line defining thickness
RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line using cubic-bezier curves in-out
RLAPI void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, float thick, Color color); //Draw line using quadratic bezier curves with a control point
RLAPI void DrawLineStrip(Vector2 *points, int pointsCount, Color color); // Draw lines sequence
RLAPI void DrawLineStrip(Vector2 *points, int pointCount, Color color); // Draw lines sequence
RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle
RLAPI void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline
@ -1169,8 +1169,8 @@ RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Co
RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline
RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!)
RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!)
RLAPI void DrawTriangleFan(Vector2 *points, int pointsCount, Color color); // Draw a triangle fan defined by points (first vertex is the center)
RLAPI void DrawTriangleStrip(Vector2 *points, int pointsCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawTriangleFan(Vector2 *points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center)
RLAPI void DrawTriangleStrip(Vector2 *points, int pointCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides
RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters
@ -1239,7 +1239,7 @@ RLAPI void ImageColorContrast(Image *image, float contrast);
RLAPI void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255)
RLAPI void ImageColorReplace(Image *image, Color color, Color replace); // Modify image color: replace color
RLAPI Color *LoadImageColors(Image image); // Load color data from image as a Color array (RGBA - 32bit)
RLAPI Color *LoadImagePalette(Image image, int maxPaletteSize, int *colorsCount); // Load colors palette from image as a Color array (RGBA - 32bit)
RLAPI Color *LoadImagePalette(Image image, int maxPaletteSize, int *colorCount); // Load colors palette from image as a Color array (RGBA - 32bit)
RLAPI void UnloadImageColors(Color *colors); // Unload color data loaded with LoadImageColors()
RLAPI void UnloadImagePalette(Color *colors); // Unload colors palette loaded with LoadImagePalette()
RLAPI Rectangle GetImageAlphaBorder(Image image, float threshold); // Get image alpha border rectangle
@ -1286,7 +1286,7 @@ RLAPI void DrawTextureQuad(Texture2D texture, Vector2 tiling, Vector2 offset, Re
RLAPI void DrawTextureTiled(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, float scale, Color tint); // Draw part of a texture (defined by a rectangle) with rotation and scale tiled into dest.
RLAPI void DrawTexturePro(Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a rectangle with 'pro' parameters
RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draws a texture (or part of it) that stretches or shrinks nicely
RLAPI void DrawTexturePoly(Texture2D texture, Vector2 center, Vector2 *points, Vector2 *texcoords, int pointsCount, Color tint); // Draw a textured polygon
RLAPI void DrawTexturePoly(Texture2D texture, Vector2 center, Vector2 *points, Vector2 *texcoords, int pointCount, Color tint); // Draw a textured polygon
// Color/pixel related functions
RLAPI Color Fade(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f
@ -1297,7 +1297,7 @@ RLAPI Vector3 ColorToHSV(Color color); // G
RLAPI Color ColorFromHSV(float hue, float saturation, float value); // Get a Color from HSV values, hue [0..360], saturation/value [0..1]
RLAPI Color ColorAlpha(Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f
RLAPI Color ColorAlphaBlend(Color dst, Color src, Color tint); // Get src alpha-blended into dst color with tint
RLAPI Color GetColor(int hexValue); // Get Color structure from hexadecimal value
RLAPI Color GetColor(unsigned int hexValue); // Get Color structure from hexadecimal value
RLAPI Color GetPixelColor(void *srcPtr, int format); // Get Color from a source pixel pointer of certain format
RLAPI void SetPixelColor(void *dstPtr, Color color, int format); // Set color formatted into destination pixel pointer
RLAPI int GetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes for certain format
@ -1309,12 +1309,12 @@ RLAPI int GetPixelDataSize(int width, int height, int format); // G
// Font loading/unloading functions
RLAPI Font GetFontDefault(void); // Get the default Font
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int charsCount); // Load font from file with extended parameters
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int glyphCount); // Load font from file with extended parameters
RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style)
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int charsCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int charsCount, int type); // Load font data for further use
RLAPI Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **recs, int charsCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info
RLAPI void UnloadFontData(GlyphInfo *chars, int charsCount); // Unload font chars info data (RAM)
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int glyphCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int glyphCount, int type); // Load font data for further use
RLAPI Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **recs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info
RLAPI void UnloadFontData(GlyphInfo *chars, int glyphCount); // Unload font chars info data (RAM)
RLAPI void UnloadFont(Font font); // Unload Font from GPU memory (VRAM)
// Text drawing functions
@ -1334,9 +1334,9 @@ RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint);
// Text codepoints management functions (unicode characters)
RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory
RLAPI int GetCodepointsCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string
RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string
RLAPI int GetCodepoint(const char *text, int *bytesProcessed); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
RLAPI const char *CodepointToUTF8(int codepoint, int *byteLength); // Encode one codepoint into UTF-8 byte array (array length returned as parameter)
RLAPI const char *CodepointToUTF8(int codepoint, int *byteSize); // Encode one codepoint into UTF-8 byte array (array length returned as parameter)
RLAPI char *TextCodepointsToUTF8(int *codepoints, int length); // Encode text as codepoints array into UTF-8 text string (WARNING: memory must be freed!)
// Text strings management functions (no UTF-8 strings, only byte chars)
@ -1366,7 +1366,7 @@ RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color);
RLAPI void DrawPoint3D(Vector3 position, Color color); // Draw a point in 3D space, actually a small line
RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space
RLAPI void DrawTriangle3D(Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!)
RLAPI void DrawTriangleStrip3D(Vector3 *points, int pointsCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawTriangleStrip3D(Vector3 *points, int pointCount, Color color); // Draw a triangle strip defined by points
RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube
RLAPI void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
RLAPI void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); // Draw cube wires
@ -1434,7 +1434,7 @@ RLAPI void SetMaterialTexture(Material *material, int mapType, Texture2D texture
RLAPI void SetModelMeshMaterial(Model *model, int meshId, int materialId); // Set material for a mesh
// Model animations loading/unloading functions
RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animsCount); // Load model animations from file
RLAPI ModelAnimation *LoadModelAnimations(const char *fileName, int *animCount); // Load model animations from file
RLAPI void UpdateModelAnimation(Model model, ModelAnimation anim, int frame); // Update model animation pose
RLAPI void UnloadModelAnimation(ModelAnimation anim); // Unload animation data
RLAPI void UnloadModelAnimations(ModelAnimation* animations, unsigned int count); // Unload animation array data
@ -1466,7 +1466,7 @@ RLAPI Wave LoadWave(const char *fileName); // Load wa
RLAPI Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav'
RLAPI Sound LoadSound(const char *fileName); // Load sound from file
RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
RLAPI void UpdateSound(Sound sound, const void *data, int samplesCount);// Update sound buffer with new data
RLAPI void UpdateSound(Sound sound, const void *data, int sampleCount); // Update sound buffer with new data
RLAPI void UnloadWave(Wave wave); // Unload wave data
RLAPI void UnloadSound(Sound sound); // Unload sound
RLAPI bool ExportWave(Wave wave, const char *fileName); // Export wave data to file, returns true on success
@ -1507,7 +1507,7 @@ RLAPI float GetMusicTimePlayed(Music music); // Get cur
// AudioStream management functions
RLAPI AudioStream LoadAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels); // Load audio stream (to stream raw audio pcm data)
RLAPI void UnloadAudioStream(AudioStream stream); // Unload audio stream and free memory
RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int framesCount); // Update audio stream buffers with data
RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int frameCount); // Update audio stream buffers with data
RLAPI bool IsAudioStreamProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
RLAPI void PlayAudioStream(AudioStream stream); // Play audio stream
RLAPI void PauseAudioStream(AudioStream stream); // Pause audio stream

View File

@ -279,7 +279,7 @@ typedef enum {
// Dynamic vertex buffers (position + texcoords + colors + indices arrays)
typedef struct rlVertexBuffer {
int elementsCount; // Number of elements in the buffer (QUADS)
int elementCount; // 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
@ -316,12 +316,12 @@ typedef struct rlDrawCall {
// rlRenderBatch type
typedef struct rlRenderBatch {
int buffersCount; // Number of vertex buffers (multi-buffering support)
int bufferCount; // Number of vertex buffers (multi-buffering support)
int currentBuffer; // Current buffer tracking in case of multi-buffering
rlVertexBuffer *vertexBuffer; // Dynamic buffer(s) for vertex data
rlDrawCall *draws; // Draw calls array, depends on textureId
int drawsCounter; // Draw calls counter
int drawCounter; // Draw calls counter
float currentDepth; // Current depth value for next draw
} rlRenderBatch;
@ -1210,34 +1210,34 @@ void rlBegin(int mode)
{
// Draw mode can be RL_LINES, RL_TRIANGLES and RL_QUADS
// NOTE: In all three cases, vertex are accumulated over default internal vertex buffer
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode != mode)
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode != mode)
{
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount > 0)
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount > 0)
{
// Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4,
// that way, following QUADS drawing will keep aligned with index processing
// It implies adding some extra alignment vertex at the end of the draw,
// those vertex are not processed but they are considered as an additional offset
// for the next set of vertex to be drawn
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4);
else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4)));
else RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = 0;
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4);
else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4)));
else RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = 0;
if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment))
if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment))
{
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.currentBatch->drawsCounter++;
RLGL.currentBatch->drawCounter++;
}
}
if (RLGL.currentBatch->drawsCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch);
if (RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch);
RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode = mode;
RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount = 0;
RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].textureId = RLGL.State.defaultTextureId;
RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode = mode;
RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount = 0;
RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = RLGL.State.defaultTextureId;
}
}
@ -1285,7 +1285,7 @@ void rlEnd(void)
// Verify internal buffers limits
// NOTE: This check is combined with usage of rlCheckRenderBatchLimit()
if ((RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter) >=
(RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4 - 4))
(RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4 - 4))
{
// WARNING: If we are between rlPushMatrix() and rlPopMatrix() and we need to force a rlDrawRenderBatch(),
// we need to call rlPopMatrix() before to recover *RLGL.State.currentMatrix (RLGL.State.modelview) for the next forced draw call!
@ -1312,14 +1312,14 @@ void rlVertex3f(float x, float y, float z)
}
// Verify that current vertex buffer elements limit has not been reached
if (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter < (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4))
if (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter < (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4))
{
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter] = tx;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter + 1] = ty;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vertices[3*RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter + 2] = tz;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter++;
RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount++;
RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount++;
}
else TRACELOG(RL_LOG_ERROR, "RLGL: Batch elements overflow");
}
@ -1390,7 +1390,7 @@ void rlSetTexture(unsigned int id)
#else
// NOTE: If quads batch limit is reached, we force a draw call and next batch starts
if (RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter >=
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4)
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4)
{
rlDrawRenderBatch(RLGL.currentBatch);
}
@ -1401,33 +1401,33 @@ void rlSetTexture(unsigned int id)
#if defined(GRAPHICS_API_OPENGL_11)
rlEnableTexture(id);
#else
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].textureId != id)
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId != id)
{
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount > 0)
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount > 0)
{
// Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4,
// that way, following QUADS drawing will keep aligned with index processing
// It implies adding some extra alignment vertex at the end of the draw,
// those vertex are not processed but they are considered as an additional offset
// for the next set of vertex to be drawn
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4);
else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount%4)));
else RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment = 0;
if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_LINES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount : RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4);
else if (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].mode == RL_TRIANGLES) RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = ((RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount < 4)? 1 : (4 - (RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount%4)));
else RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment = 0;
if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment))
if (!rlCheckRenderBatchLimit(RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment))
{
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].cCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].tcCounter += RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexAlignment;
RLGL.currentBatch->drawsCounter++;
RLGL.currentBatch->drawCounter++;
}
}
if (RLGL.currentBatch->drawsCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch);
if (RLGL.currentBatch->drawCounter >= RL_DEFAULT_BATCH_DRAWCALLS) rlDrawRenderBatch(RLGL.currentBatch);
RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].textureId = id;
RLGL.currentBatch->draws[RLGL.currentBatch->drawsCounter - 1].vertexCount = 0;
RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].textureId = id;
RLGL.currentBatch->draws[RLGL.currentBatch->drawCounter - 1].vertexCount = 0;
}
#endif
}
@ -1910,12 +1910,12 @@ void rlLoadExtensions(void *loader)
const char *extensions = (const char *)glGetString(GL_EXTENSIONS); // One big const string
// NOTE: We have to duplicate string because glGetString() returns a const string
int len = strlen(extensions) + 1;
char *extensionsDup = (char *)RL_CALLOC(len, sizeof(char));
int size = strlen(extensions) + 1; // Get extensions string size in bytes
char *extensionsDup = (char *)RL_CALLOC(size, sizeof(char));
strcpy(extensionsDup, extensions);
extList[numExt] = extensionsDup;
for (int i = 0; i < len; i++)
for (int i = 0; i < size; i++)
{
if (extensionsDup[i] == ' ')
{
@ -2169,7 +2169,7 @@ rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements)
for (int i = 0; i < numBuffers; i++)
{
batch.vertexBuffer[i].elementsCount = bufferElements;
batch.vertexBuffer[i].elementCount = 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
@ -2274,8 +2274,8 @@ rlRenderBatch rlLoadRenderBatch(int numBuffers, int bufferElements)
//batch.draws[i].RLGL.State.modelview = rlMatrixIdentity();
}
batch.buffersCount = numBuffers; // Record buffer count
batch.drawsCounter = 1; // Reset draws counter
batch.bufferCount = numBuffers; // Record buffer count
batch.drawCounter = 1; // Reset draws counter
batch.currentDepth = -1.0f; // Reset depth value
//--------------------------------------------------------------------------------------------
#endif
@ -2297,7 +2297,7 @@ void rlUnloadRenderBatch(rlRenderBatch batch)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// Unload all vertex buffers data
for (int i = 0; i < batch.buffersCount; i++)
for (int i = 0; i < batch.bufferCount; i++)
{
// Delete VBOs from GPU (VRAM)
glDeleteBuffers(1, &batch.vertexBuffer[i].vboId[0]);
@ -2338,17 +2338,17 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
// Vertex positions buffer
glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, batch->vertexBuffer[batch->currentBuffer].vCounter*3*sizeof(float), batch->vertexBuffer[batch->currentBuffer].vertices);
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*batch->vertexBuffer[batch->currentBuffer].elementsCount, batch->vertexBuffer[batch->currentBuffer].vertices, GL_DYNAMIC_DRAW); // Update all buffer
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].vertices, GL_DYNAMIC_DRAW); // Update all buffer
// Texture coordinates buffer
glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[1]);
glBufferSubData(GL_ARRAY_BUFFER, 0, batch->vertexBuffer[batch->currentBuffer].vCounter*2*sizeof(float), batch->vertexBuffer[batch->currentBuffer].texcoords);
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*batch->vertexBuffer[batch->currentBuffer].elementsCount, batch->vertexBuffer[batch->currentBuffer].texcoords, GL_DYNAMIC_DRAW); // Update all buffer
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].texcoords, GL_DYNAMIC_DRAW); // Update all buffer
// Colors buffer
glBindBuffer(GL_ARRAY_BUFFER, batch->vertexBuffer[batch->currentBuffer].vboId[2]);
glBufferSubData(GL_ARRAY_BUFFER, 0, batch->vertexBuffer[batch->currentBuffer].vCounter*4*sizeof(unsigned char), batch->vertexBuffer[batch->currentBuffer].colors);
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementsCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer
//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer
// NOTE: glMapBuffer() causes sync issue.
// If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job.
@ -2375,12 +2375,12 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
Matrix matProjection = RLGL.State.projection;
Matrix matModelView = RLGL.State.modelview;
int eyesCount = 1;
if (RLGL.State.stereoRender) eyesCount = 2;
int eyeCount = 1;
if (RLGL.State.stereoRender) eyeCount = 2;
for (int eye = 0; eye < eyesCount; eye++)
for (int eye = 0; eye < eyeCount; eye++)
{
if (eyesCount == 2)
if (eyeCount == 2)
{
// Setup current eye viewport (half screen width)
rlViewport(eye*RLGL.State.framebufferWidth/2, 0, RLGL.State.framebufferWidth/2, RLGL.State.framebufferHeight);
@ -2447,7 +2447,7 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
// NOTE: Batch system accumulates calls by texture0 changes, additional textures are enabled for all the draw calls
glActiveTexture(GL_TEXTURE0);
for (int i = 0, vertexOffset = 0; i < batch->drawsCounter; i++)
for (int i = 0, vertexOffset = 0; i < batch->drawCounter; i++)
{
// Bind current draw call texture, activated as GL_TEXTURE0 and binded to sampler2D texture0 by default
glBindTexture(GL_TEXTURE_2D, batch->draws[i].textureId);
@ -2456,7 +2456,7 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
else
{
#if defined(GRAPHICS_API_OPENGL_33)
// We need to define the number of indices to be processed: quadsCount*6
// We need to define the number of indices to be processed: elementCount*6
// NOTE: The final parameter tells the GPU the offset in bytes from the
// start of the index buffer to the location of the first index to process
glDrawElements(GL_TRIANGLES, batch->draws[i].vertexCount/4*6, GL_UNSIGNED_INT, (GLvoid *)(vertexOffset/4*6*sizeof(GLuint)));
@ -2510,12 +2510,12 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
for (int i = 0; i < RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS; i++) RLGL.State.activeTextureId[i] = 0;
// Reset draws counter to one draw for the batch
batch->drawsCounter = 1;
batch->drawCounter = 1;
//------------------------------------------------------------------------------------------------------------
// Change to next buffer in the list (in case of multi-buffering)
batch->currentBuffer++;
if (batch->currentBuffer >= batch->buffersCount) batch->currentBuffer = 0;
if (batch->currentBuffer >= batch->bufferCount) batch->currentBuffer = 0;
#endif
}
@ -2546,7 +2546,7 @@ bool rlCheckRenderBatchLimit(int vCount)
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
if ((RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].vCounter + vCount) >=
(RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementsCount*4))
(RLGL.currentBatch->vertexBuffer[RLGL.currentBatch->currentBuffer].elementCount*4))
{
overflow = true;
rlDrawRenderBatch(RLGL.currentBatch); // NOTE: Stereo rendering is checked inside
@ -2956,9 +2956,9 @@ void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int
*mipmaps = mipmapCount + 1;
RL_FREE(texData); // Once mipmaps have been generated and data has been uploaded to GPU VRAM, we can discard RAM data
TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Mipmaps generated manually on CPU side, total: %i", texture->id, texture->mipmaps);
TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Mipmaps generated manually on CPU side, total: %i", id, *mipmaps);
}
else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to generate mipmaps for provided texture format", texture->id);
else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to generate mipmaps for provided texture format", id);
}
#endif
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)

View File

@ -190,16 +190,16 @@ void DrawLineBezierQuad(Vector2 startPos, Vector2 endPos, Vector2 controlPos, fl
}
// Draw lines sequence
void DrawLineStrip(Vector2 *points, int pointsCount, Color color)
void DrawLineStrip(Vector2 *points, int pointCount, Color color)
{
if (pointsCount >= 2)
if (pointCount >= 2)
{
rlCheckRenderBatchLimit(pointsCount);
rlCheckRenderBatchLimit(pointCount);
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
for (int i = 0; i < pointsCount - 1; i++)
for (int i = 0; i < pointCount - 1; i++)
{
rlVertex2f(points[i].x, points[i].y);
rlVertex2f(points[i + 1].x, points[i + 1].y);
@ -1318,17 +1318,17 @@ void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
// Draw a triangle fan defined by points
// NOTE: First vertex provided is the center, shared by all triangles
// By default, following vertex should be provided in counter-clockwise order
void DrawTriangleFan(Vector2 *points, int pointsCount, Color color)
void DrawTriangleFan(Vector2 *points, int pointCount, Color color)
{
if (pointsCount >= 3)
if (pointCount >= 3)
{
rlCheckRenderBatchLimit((pointsCount - 2)*4);
rlCheckRenderBatchLimit((pointCount - 2)*4);
rlSetTexture(texShapes.id);
rlBegin(RL_QUADS);
rlColor4ub(color.r, color.g, color.b, color.a);
for (int i = 1; i < pointsCount - 1; i++)
for (int i = 1; i < pointCount - 1; i++)
{
rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height);
rlVertex2f(points[0].x, points[0].y);
@ -1349,16 +1349,16 @@ void DrawTriangleFan(Vector2 *points, int pointsCount, Color color)
// Draw a triangle strip defined by points
// NOTE: Every new vertex connects with previous two
void DrawTriangleStrip(Vector2 *points, int pointsCount, Color color)
void DrawTriangleStrip(Vector2 *points, int pointCount, Color color)
{
if (pointsCount >= 3)
if (pointCount >= 3)
{
rlCheckRenderBatchLimit(3*(pointsCount - 2));
rlCheckRenderBatchLimit(3*(pointCount - 2));
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
for (int i = 2; i < pointsCount; i++)
for (int i = 2; i < pointCount; i++)
{
if ((i%2) == 0)
{

View File

@ -192,7 +192,8 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB
<script type='text/javascript'>
function saveFileFromMEMFSToDisk(memoryFSname, localFSname) // This can be called by C/C++ code
{
var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
var isSafari = false; // Not supported, navigator.userAgent access is being restricted
//var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
var data = FS.readFile(memoryFSname);
var blob;

View File

@ -129,8 +129,8 @@ extern void LoadFontDefault(void)
// NOTE: Using UTF-8 encoding table for Unicode U+0000..U+00FF Basic Latin + Latin-1 Supplement
// Ref: http://www.utf8-chartable.de/unicode-utf8-table.pl
defaultFont.charsCount = 224; // Number of chars included in our default font
defaultFont.charsPadding = 0; // Characters padding
defaultFont.glyphCount = 224; // Number of chars included in our default font
defaultFont.glyphPadding = 0; // Characters padding
// Default font is directly defined here (data generated from a sprite font image)
// This way, we reconstruct Font without creating large global variables
@ -220,21 +220,21 @@ extern void LoadFontDefault(void)
defaultFont.texture = LoadTextureFromImage(imFont);
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, charsCount
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, glyphCount
//------------------------------------------------------------------------------
// Allocate space for our characters info data
// NOTE: This memory should be freed at end! --> CloseWindow()
defaultFont.chars = (GlyphInfo *)RL_MALLOC(defaultFont.charsCount*sizeof(GlyphInfo));
defaultFont.recs = (Rectangle *)RL_MALLOC(defaultFont.charsCount*sizeof(Rectangle));
defaultFont.glyphs = (GlyphInfo *)RL_MALLOC(defaultFont.glyphCount*sizeof(GlyphInfo));
defaultFont.recs = (Rectangle *)RL_MALLOC(defaultFont.glyphCount*sizeof(Rectangle));
int currentLine = 0;
int currentPosX = charsDivisor;
int testPosX = charsDivisor;
for (int i = 0; i < defaultFont.charsCount; i++)
for (int i = 0; i < defaultFont.glyphCount; i++)
{
defaultFont.chars[i].value = 32 + i; // First char is 32
defaultFont.glyphs[i].value = 32 + i; // First char is 32
defaultFont.recs[i].x = (float)currentPosX;
defaultFont.recs[i].y = (float)(charsDivisor + currentLine*(charsHeight + charsDivisor));
@ -255,12 +255,12 @@ extern void LoadFontDefault(void)
else currentPosX = testPosX;
// NOTE: On default font character offsets and xAdvance are not required
defaultFont.chars[i].offsetX = 0;
defaultFont.chars[i].offsetY = 0;
defaultFont.chars[i].advanceX = 0;
defaultFont.glyphs[i].offsetX = 0;
defaultFont.glyphs[i].offsetY = 0;
defaultFont.glyphs[i].advanceX = 0;
// Fill character image data from fontClear data
defaultFont.chars[i].image = ImageFromImage(imFont, defaultFont.recs[i]);
defaultFont.glyphs[i].image = ImageFromImage(imFont, defaultFont.recs[i]);
}
UnloadImage(imFont);
@ -273,9 +273,9 @@ extern void LoadFontDefault(void)
// Unload raylib default font
extern void UnloadFontDefault(void)
{
for (int i = 0; i < defaultFont.charsCount; i++) UnloadImage(defaultFont.chars[i].image);
for (int i = 0; i < defaultFont.glyphCount; i++) UnloadImage(defaultFont.glyphs[i].image);
UnloadTexture(defaultFont.texture);
RL_FREE(defaultFont.chars);
RL_FREE(defaultFont.glyphs);
RL_FREE(defaultFont.recs);
}
#endif // SUPPORT_DEFAULT_FONT
@ -337,7 +337,7 @@ Font LoadFont(const char *fileName)
// Load Font from TTF font file with generation parameters
// NOTE: You can pass an array with desired characters, those characters should be available in the font
// if array is NULL, default char set is selected 32..126
Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int charsCount)
Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int glyphCount)
{
Font font = { 0 };
@ -348,7 +348,7 @@ Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int charsCou
if (fileData != NULL)
{
// Loading font from memory data
font = LoadFontFromMemory(GetFileExtension(fileName), fileData, fileSize, fontSize, fontChars, charsCount);
font = LoadFontFromMemory(GetFileExtension(fileName), fileData, fileSize, fontSize, fontChars, glyphCount);
RL_FREE(fileData);
}
@ -449,28 +449,28 @@ Font LoadFontFromImage(Image image, Color key, int firstChar)
Font font = { 0 };
font.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture
font.charsCount = index;
font.charsPadding = 0;
font.glyphCount = index;
font.glyphPadding = 0;
// We got tempCharValues and tempCharsRecs populated with chars data
// Now we move temp data to sized charValues and charRecs arrays
font.chars = (GlyphInfo *)RL_MALLOC(font.charsCount*sizeof(GlyphInfo));
font.recs = (Rectangle *)RL_MALLOC(font.charsCount*sizeof(Rectangle));
font.glyphs = (GlyphInfo *)RL_MALLOC(font.glyphCount*sizeof(GlyphInfo));
font.recs = (Rectangle *)RL_MALLOC(font.glyphCount*sizeof(Rectangle));
for (int i = 0; i < font.charsCount; i++)
for (int i = 0; i < font.glyphCount; i++)
{
font.chars[i].value = tempCharValues[i];
font.glyphs[i].value = tempCharValues[i];
// Get character rectangle in the font atlas texture
font.recs[i] = tempCharRecs[i];
// NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0)
font.chars[i].offsetX = 0;
font.chars[i].offsetY = 0;
font.chars[i].advanceX = 0;
font.glyphs[i].offsetX = 0;
font.glyphs[i].offsetY = 0;
font.glyphs[i].advanceX = 0;
// Fill character image data from fontClear data
font.chars[i].image = ImageFromImage(fontClear, tempCharRecs[i]);
font.glyphs[i].image = ImageFromImage(fontClear, tempCharRecs[i]);
}
UnloadImage(fontClear); // Unload processed image once converted to texture
@ -481,7 +481,7 @@ Font LoadFontFromImage(Image image, Color key, int firstChar)
}
// Load font from memory buffer, fileType refers to extension: i.e. ".ttf"
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 glyphCount)
{
Font font = { 0 };
@ -493,22 +493,22 @@ Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int
TextIsEqual(fileExtLower, ".otf"))
{
font.baseSize = fontSize;
font.charsCount = (charsCount > 0)? charsCount : 95;
font.charsPadding = 0;
font.chars = LoadFontData(fileData, dataSize, font.baseSize, fontChars, font.charsCount, FONT_DEFAULT);
font.glyphCount = (glyphCount > 0)? glyphCount : 95;
font.glyphPadding = 0;
font.glyphs = LoadFontData(fileData, dataSize, font.baseSize, fontChars, font.glyphCount, FONT_DEFAULT);
if (font.chars != NULL)
if (font.glyphs != NULL)
{
font.charsPadding = FONT_TTF_DEFAULT_CHARS_PADDING;
font.glyphPadding = FONT_TTF_DEFAULT_CHARS_PADDING;
Image atlas = GenImageFontAtlas(font.chars, &font.recs, font.charsCount, font.baseSize, font.charsPadding, 0);
Image atlas = GenImageFontAtlas(font.glyphs, &font.recs, font.glyphCount, font.baseSize, font.glyphPadding, 0);
font.texture = LoadTextureFromImage(atlas);
// Update chars[i].image to use alpha, required to be used on ImageDrawText()
for (int i = 0; i < font.charsCount; i++)
// Update glyphs[i].image to use alpha, required to be used on ImageDrawText()
for (int i = 0; i < font.glyphCount; i++)
{
UnloadImage(font.chars[i].image);
font.chars[i].image = ImageFromImage(atlas, font.recs[i]);
UnloadImage(font.glyphs[i].image);
font.glyphs[i].image = ImageFromImage(atlas, font.recs[i]);
}
UnloadImage(atlas);
@ -524,7 +524,7 @@ Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int
// Load font data for further use
// NOTE: Requires TTF font memory data and can generate SDF data
GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int charsCount, int type)
GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int glyphCount, int type)
{
// NOTE: Using some SDF generation default values,
// trades off precision with ability to handle *smaller* sizes
@ -562,22 +562,22 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap);
// In case no chars count provided, default to 95
charsCount = (charsCount > 0)? charsCount : 95;
glyphCount = (glyphCount > 0)? glyphCount : 95;
// Fill fontChars in case not provided externally
// NOTE: By default we fill charsCount consecutevely, starting at 32 (Space)
// NOTE: By default we fill glyphCount consecutevely, starting at 32 (Space)
if (fontChars == NULL)
{
fontChars = (int *)RL_MALLOC(charsCount*sizeof(int));
for (int i = 0; i < charsCount; i++) fontChars[i] = i + 32;
fontChars = (int *)RL_MALLOC(glyphCount*sizeof(int));
for (int i = 0; i < glyphCount; i++) fontChars[i] = i + 32;
genFontChars = true;
}
chars = (GlyphInfo *)RL_MALLOC(charsCount*sizeof(GlyphInfo));
chars = (GlyphInfo *)RL_MALLOC(glyphCount*sizeof(GlyphInfo));
// NOTE: Using simple packaging, one char after another
for (int i = 0; i < charsCount; i++)
for (int i = 0; i < glyphCount; i++)
{
int chw = 0, chh = 0; // Character width and height (on generation)
int ch = fontChars[i]; // Character value to get info for
@ -650,7 +650,7 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
// Generate image font atlas using chars info
// NOTE: Packing method: 0-Default, 1-Skyline
#if defined(SUPPORT_FILEFORMAT_TTF)
Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int charsCount, int fontSize, int padding, int packMethod)
Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int glyphCount, int fontSize, int padding, int packMethod)
{
Image atlas = { 0 };
@ -663,17 +663,17 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int charsC
*charRecs = NULL;
// In case no chars count provided we suppose default of 95
charsCount = (charsCount > 0)? charsCount : 95;
glyphCount = (glyphCount > 0)? glyphCount : 95;
// NOTE: Rectangles memory is loaded here!
Rectangle *recs = (Rectangle *)RL_MALLOC(charsCount*sizeof(Rectangle));
Rectangle *recs = (Rectangle *)RL_MALLOC(glyphCount*sizeof(Rectangle));
// Calculate image size based on required pixel area
// NOTE 1: Image is forced to be squared and POT... very conservative!
// NOTE 2: SDF font characters already contain an internal padding,
// so image size would result bigger than default font type
float requiredArea = 0;
for (int i = 0; i < charsCount; i++) requiredArea += ((chars[i].image.width + 2*padding)*(chars[i].image.height + 2*padding));
for (int i = 0; i < glyphCount; i++) requiredArea += ((chars[i].image.width + 2*padding)*(chars[i].image.height + 2*padding));
float guessSize = sqrtf(requiredArea)*1.3f;
int imageSize = (int)powf(2, ceilf(logf((float)guessSize)/logf(2))); // Calculate next POT
@ -692,7 +692,7 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int charsC
int offsetY = padding;
// NOTE: Using simple packaging, one char after another
for (int i = 0; i < charsCount; i++)
for (int i = 0; i < glyphCount; i++)
{
// Copy pixel data from fc.data to atlas
for (int y = 0; y < chars[i].image.height; y++)
@ -728,13 +728,13 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int charsC
else if (packMethod == 1) // Use Skyline rect packing algorythm (stb_pack_rect)
{
stbrp_context *context = (stbrp_context *)RL_MALLOC(sizeof(*context));
stbrp_node *nodes = (stbrp_node *)RL_MALLOC(charsCount*sizeof(*nodes));
stbrp_node *nodes = (stbrp_node *)RL_MALLOC(glyphCount*sizeof(*nodes));
stbrp_init_target(context, atlas.width, atlas.height, nodes, charsCount);
stbrp_rect *rects = (stbrp_rect *)RL_MALLOC(charsCount*sizeof(stbrp_rect));
stbrp_init_target(context, atlas.width, atlas.height, nodes, glyphCount);
stbrp_rect *rects = (stbrp_rect *)RL_MALLOC(glyphCount*sizeof(stbrp_rect));
// Fill rectangles for packaging
for (int i = 0; i < charsCount; i++)
for (int i = 0; i < glyphCount; i++)
{
rects[i].id = i;
rects[i].w = chars[i].image.width + 2*padding;
@ -742,9 +742,9 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int charsC
}
// Package rectangles into atlas
stbrp_pack_rects(context, rects, charsCount);
stbrp_pack_rects(context, rects, glyphCount);
for (int i = 0; i < charsCount; i++)
for (int i = 0; i < glyphCount; i++)
{
// It return char rectangles in atlas
recs[i].x = rects[i].x + (float)padding;
@ -792,12 +792,12 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int charsC
}
#endif
// Unload font chars info data (RAM)
void UnloadFontData(GlyphInfo *chars, int charsCount)
// Unload font glyphs info data (RAM)
void UnloadFontData(GlyphInfo *glyphs, int glyphCount)
{
for (int i = 0; i < charsCount; i++) UnloadImage(chars[i].image);
for (int i = 0; i < glyphCount; i++) UnloadImage(glyphs[i].image);
RL_FREE(chars);
RL_FREE(glyphs);
}
// Unload Font from GPU memory (VRAM)
@ -806,7 +806,7 @@ void UnloadFont(Font font)
// NOTE: Make sure font is not default font (fallback)
if (font.texture.id != GetFontDefault().texture.id)
{
UnloadFontData(font.chars, font.charsCount);
UnloadFontData(font.glyphs, font.glyphCount);
UnloadTexture(font.texture);
RL_FREE(font.recs);
@ -851,14 +851,14 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f
{
if (font.texture.id == 0) font = GetFontDefault(); // Security check in case of not valid font
int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop
int size = TextLength(text); // Total size in bytes of the text, scanned by codepoints in loop
int textOffsetY = 0; // Offset between lines (on line break '\n')
float textOffsetX = 0.0f; // Offset X to next character to draw
float scaleFactor = fontSize/font.baseSize; // Character quad scaling factor
for (int i = 0; i < length;)
for (int i = 0; i < size;)
{
// Get next codepoint from byte string and glyph index in font
int codepointByteCount = 0;
@ -883,8 +883,8 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f
DrawTextCodepoint(font, codepoint, (Vector2){ position.x + textOffsetX, position.y + textOffsetY }, fontSize, tint);
}
if (font.chars[index].advanceX == 0) textOffsetX += ((float)font.recs[index].width*scaleFactor + spacing);
else textOffsetX += ((float)font.chars[index].advanceX*scaleFactor + spacing);
if (font.glyphs[index].advanceX == 0) textOffsetX += ((float)font.recs[index].width*scaleFactor + spacing);
else textOffsetX += ((float)font.glyphs[index].advanceX*scaleFactor + spacing);
}
i += codepointByteCount; // Move text bytes counter to next codepoint
@ -914,16 +914,16 @@ void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSiz
float scaleFactor = fontSize/font.baseSize; // Character quad scaling factor
// Character destination rectangle on screen
// NOTE: We consider charsPadding on drawing
Rectangle dstRec = { position.x + font.chars[index].offsetX*scaleFactor - (float)font.charsPadding*scaleFactor,
position.y + font.chars[index].offsetY*scaleFactor - (float)font.charsPadding*scaleFactor,
(font.recs[index].width + 2.0f*font.charsPadding)*scaleFactor,
(font.recs[index].height + 2.0f*font.charsPadding)*scaleFactor };
// NOTE: We consider glyphPadding on drawing
Rectangle dstRec = { position.x + font.glyphs[index].offsetX*scaleFactor - (float)font.glyphPadding*scaleFactor,
position.y + font.glyphs[index].offsetY*scaleFactor - (float)font.glyphPadding*scaleFactor,
(font.recs[index].width + 2.0f*font.glyphPadding)*scaleFactor,
(font.recs[index].height + 2.0f*font.glyphPadding)*scaleFactor };
// Character source rectangle from font texture atlas
// NOTE: We consider chars padding when drawing, it could be required for outline/glow shader effects
Rectangle srcRec = { font.recs[index].x - (float)font.charsPadding, font.recs[index].y - (float)font.charsPadding,
font.recs[index].width + 2.0f*font.charsPadding, font.recs[index].height + 2.0f*font.charsPadding };
Rectangle srcRec = { font.recs[index].x - (float)font.glyphPadding, font.recs[index].y - (float)font.glyphPadding,
font.recs[index].width + 2.0f*font.glyphPadding, font.recs[index].height + 2.0f*font.glyphPadding };
// Draw the character texture on the screen
DrawTexturePro(font.texture, srcRec, dstRec, (Vector2){ 0, 0 }, 0.0f, tint);
@ -950,9 +950,9 @@ int MeasureText(const char *text, int fontSize)
// Measure string size for Font
Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing)
{
int len = TextLength(text);
int tempLen = 0; // Used to count longer text line num chars
int lenCounter = 0;
int size = TextLength(text); // Get size in bytes of text
int tempByteCounter = 0; // Used to count longer text line num chars
int byteCounter = 0;
float textWidth = 0.0f;
float tempTextWidth = 0.0f; // Used to count longer text line width
@ -963,9 +963,9 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
int letter = 0; // Current character
int index = 0; // Index position in sprite font
for (int i = 0; i < len; i++)
for (int i = 0; i < size; i++)
{
lenCounter++;
byteCounter++;
int next = 0;
letter = GetCodepoint(&text[i], &next);
@ -978,24 +978,24 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
if (letter != '\n')
{
if (font.chars[index].advanceX != 0) textWidth += font.chars[index].advanceX;
else textWidth += (font.recs[index].width + font.chars[index].offsetX);
if (font.glyphs[index].advanceX != 0) textWidth += font.glyphs[index].advanceX;
else textWidth += (font.recs[index].width + font.glyphs[index].offsetX);
}
else
{
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
lenCounter = 0;
byteCounter = 0;
textWidth = 0;
textHeight += ((float)font.baseSize*1.5f); // NOTE: Fixed line spacing of 1.5 lines
}
if (tempLen < lenCounter) tempLen = lenCounter;
if (tempByteCounter < byteCounter) tempByteCounter = byteCounter;
}
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
Vector2 vec = { 0 };
vec.x = tempTextWidth*scaleFactor + (float)((tempLen - 1)*spacing); // Adds chars spacing to measure
vec.x = tempTextWidth*scaleFactor + (float)((tempByteCounter - 1)*spacing); // Adds chars spacing to measure
vec.y = textHeight*scaleFactor;
return vec;
@ -1014,9 +1014,9 @@ int GetGlyphIndex(Font font, int codepoint)
#if defined(SUPPORT_UNORDERED_CHARSET)
int index = GLYPH_NOTFOUND_CHAR_FALLBACK;
for (int i = 0; i < font.charsCount; i++)
for (int i = 0; i < font.glyphCount; i++)
{
if (font.chars[i].value == codepoint)
if (font.glyphs[i].value == codepoint)
{
index = i;
break;
@ -1035,7 +1035,7 @@ GlyphInfo GetGlyphInfo(Font font, int codepoint)
{
GlyphInfo info = { 0 };
info = font.chars[GetGlyphIndex(font, codepoint)];
info = font.glyphs[GetGlyphIndex(font, codepoint)];
return info;
}
@ -1429,28 +1429,28 @@ char *TextCodepointsToUTF8(int *codepoints, int length)
// Encode codepoint into utf8 text (char array length returned as parameter)
// NOTE: It uses a static array to store UTF-8 bytes
RLAPI const char *CodepointToUTF8(int codepoint, int *byteLength)
RLAPI const char *CodepointToUTF8(int codepoint, int *byteSize)
{
static char utf8[6] = { 0 };
int length = 0;
int size = 0; // Byte size of codepoint
if (codepoint <= 0x7f)
{
utf8[0] = (char)codepoint;
length = 1;
size = 1;
}
else if (codepoint <= 0x7ff)
{
utf8[0] = (char)(((codepoint >> 6) & 0x1f) | 0xc0);
utf8[1] = (char)((codepoint & 0x3f) | 0x80);
length = 2;
size = 2;
}
else if (codepoint <= 0xffff)
{
utf8[0] = (char)(((codepoint >> 12) & 0x0f) | 0xe0);
utf8[1] = (char)(((codepoint >> 6) & 0x3f) | 0x80);
utf8[2] = (char)((codepoint & 0x3f) | 0x80);
length = 3;
size = 3;
}
else if (codepoint <= 0x10ffff)
{
@ -1458,10 +1458,10 @@ RLAPI const char *CodepointToUTF8(int codepoint, int *byteLength)
utf8[1] = (char)(((codepoint >> 12) & 0x3f) | 0x80);
utf8[2] = (char)(((codepoint >> 6) & 0x3f) | 0x80);
utf8[3] = (char)((codepoint & 0x3f) | 0x80);
length = 4;
size = 4;
}
*byteLength = length;
*byteSize = size;
return utf8;
}
@ -1472,22 +1472,22 @@ int *LoadCodepoints(const char *text, int *count)
int textLength = TextLength(text);
int bytesProcessed = 0;
int codepointsCount = 0;
int codepointCount = 0;
// Allocate a big enough buffer to store as many codepoints as text bytes
int *codepoints = RL_CALLOC(textLength, sizeof(int));
for (int i = 0; i < textLength; codepointsCount++)
for (int i = 0; i < textLength; codepointCount++)
{
codepoints[codepointsCount] = GetCodepoint(text + i, &bytesProcessed);
codepoints[codepointCount] = GetCodepoint(text + i, &bytesProcessed);
i += bytesProcessed;
}
// Re-allocate buffer to the actual number of codepoints loaded
void *temp = RL_REALLOC(codepoints, codepointsCount*sizeof(int));
void *temp = RL_REALLOC(codepoints, codepointCount*sizeof(int));
if (temp != NULL) codepoints = temp;
*count = codepointsCount;
*count = codepointCount;
return codepoints;
}
@ -1500,9 +1500,9 @@ void UnloadCodepoints(int *codepoints)
// Get total number of characters(codepoints) in a UTF-8 encoded text, until '\0' is found
// NOTE: If an invalid UTF-8 sequence is encountered a '?'(0x3f) codepoint is counted instead
int GetCodepointsCount(const char *text)
int GetCodepointCount(const char *text)
{
unsigned int len = 0;
unsigned int length = 0;
char *ptr = (char *)&text[0];
while (*ptr != '\0')
@ -1513,10 +1513,10 @@ int GetCodepointsCount(const char *text)
if (letter == 0x3f) ptr += 1;
else ptr += next;
len++;
length++;
}
return len;
return length;
}
#endif // SUPPORT_TEXT_MANIPULATION
@ -1657,7 +1657,7 @@ static Font LoadBMFont(const char *fileName)
char *searchPoint = NULL;
int fontSize = 0;
int charsCount = 0;
int glyphCount = 0;
int imWidth = 0;
int imHeight = 0;
@ -1694,10 +1694,10 @@ static Font LoadBMFont(const char *fileName)
lineBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE);
searchPoint = strstr(buffer, "count");
sscanf(searchPoint, "count=%i", &charsCount);
sscanf(searchPoint, "count=%i", &glyphCount);
fileTextPtr += (lineBytes + 1);
TRACELOGD(" > Chars count: %i", charsCount);
TRACELOGD(" > Chars count: %i", glyphCount);
// Compose correct path using route of .fnt file (fileName) and imFileName
char *imPath = NULL;
@ -1746,14 +1746,14 @@ static Font LoadBMFont(const char *fileName)
// Fill font characters info data
font.baseSize = fontSize;
font.charsCount = charsCount;
font.charsPadding = 0;
font.chars = (GlyphInfo *)RL_MALLOC(charsCount*sizeof(GlyphInfo));
font.recs = (Rectangle *)RL_MALLOC(charsCount*sizeof(Rectangle));
font.glyphCount = glyphCount;
font.glyphPadding = 0;
font.glyphs = (GlyphInfo *)RL_MALLOC(glyphCount*sizeof(GlyphInfo));
font.recs = (Rectangle *)RL_MALLOC(glyphCount*sizeof(Rectangle));
int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX;
for (int i = 0; i < charsCount; i++)
for (int i = 0; i < glyphCount; i++)
{
lineBytes = GetLine(fileTextPtr, buffer, MAX_BUFFER_SIZE);
sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i",
@ -1764,13 +1764,13 @@ static Font LoadBMFont(const char *fileName)
font.recs[i] = (Rectangle){ (float)charX, (float)charY, (float)charWidth, (float)charHeight };
// Save data properly in sprite font
font.chars[i].value = charId;
font.chars[i].offsetX = charOffsetX;
font.chars[i].offsetY = charOffsetY;
font.chars[i].advanceX = charAdvanceX;
font.glyphs[i].value = charId;
font.glyphs[i].offsetX = charOffsetX;
font.glyphs[i].offsetY = charOffsetY;
font.glyphs[i].advanceX = charAdvanceX;
// Fill character image data from imFont data
font.chars[i].image = ImageFromImage(imFont, font.recs[i]);
font.glyphs[i].image = ImageFromImage(imFont, font.recs[i]);
}
UnloadImage(imFont);

View File

@ -102,6 +102,10 @@
#define STBI_NO_PIC
#define STBI_NO_PNM // Image format .ppm and .pgm
#if defined(__TINYC__)
#define STBI_NO_SIMD
#endif
#if (defined(SUPPORT_FILEFORMAT_BMP) || \
defined(SUPPORT_FILEFORMAT_PNG) || \
defined(SUPPORT_FILEFORMAT_TGA) || \
@ -254,7 +258,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
Image LoadImageAnim(const char *fileName, int *frames)
{
Image image = { 0 };
int framesCount = 1;
int frameCount = 1;
#if defined(SUPPORT_FILEFORMAT_GIF)
if (IsFileExtension(fileName, ".gif"))
@ -266,7 +270,7 @@ Image LoadImageAnim(const char *fileName, int *frames)
{
int comp = 0;
int **delays = NULL;
image.data = stbi_load_gif_from_memory(fileData, dataSize, delays, &image.width, &image.height, &framesCount, &comp, 4);
image.data = stbi_load_gif_from_memory(fileData, dataSize, delays, &image.width, &image.height, &frameCount, &comp, 4);
image.mipmaps = 1;
image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
@ -282,7 +286,7 @@ Image LoadImageAnim(const char *fileName, int *frames)
// TODO: Support APNG animated images?
*frames = framesCount;
*frames = frameCount;
return image;
}
@ -514,19 +518,19 @@ bool ExportImageAsCode(Image image, const char *fileName)
// 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));
char *txtData = (char *)RL_CALLOC(dataSize*6 + 2000, sizeof(char));
int bytesCount = 0;
bytesCount += sprintf(txtData + bytesCount, "////////////////////////////////////////////////////////////////////////////////////////\n");
bytesCount += sprintf(txtData + bytesCount, "// //\n");
bytesCount += sprintf(txtData + bytesCount, "// ImageAsCode exporter v1.0 - Image pixel data exported as an array of bytes //\n");
bytesCount += sprintf(txtData + bytesCount, "// //\n");
bytesCount += sprintf(txtData + bytesCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
bytesCount += sprintf(txtData + bytesCount, "// feedback and support: ray[at]raylib.com //\n");
bytesCount += sprintf(txtData + bytesCount, "// //\n");
bytesCount += sprintf(txtData + bytesCount, "// Copyright (c) 2020 Ramon Santamaria (@raysan5) //\n");
bytesCount += sprintf(txtData + bytesCount, "// //\n");
bytesCount += sprintf(txtData + bytesCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n");
int byteCount = 0;
byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// ImageAsCode exporter v1.0 - Image pixel data exported as an array of bytes //\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2018-2021 Ramon Santamaria (@raysan5) //\n");
byteCount += sprintf(txtData + byteCount, "// //\n");
byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n");
// Get file name from path and convert variable name to uppercase
char varFileName[256] = { 0 };
@ -534,16 +538,16 @@ bool ExportImageAsCode(Image image, const char *fileName)
for (int i = 0; varFileName[i] != '\0'; i++) if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; }
// Add image information
bytesCount += sprintf(txtData + bytesCount, "// Image data information\n");
bytesCount += sprintf(txtData + bytesCount, "#define %s_WIDTH %i\n", varFileName, image.width);
bytesCount += sprintf(txtData + bytesCount, "#define %s_HEIGHT %i\n", varFileName, image.height);
bytesCount += sprintf(txtData + bytesCount, "#define %s_FORMAT %i // raylib internal pixel format\n\n", varFileName, image.format);
byteCount += sprintf(txtData + byteCount, "// Image data information\n");
byteCount += sprintf(txtData + byteCount, "#define %s_WIDTH %i\n", varFileName, image.width);
byteCount += sprintf(txtData + byteCount, "#define %s_HEIGHT %i\n", varFileName, image.height);
byteCount += sprintf(txtData + byteCount, "#define %s_FORMAT %i // raylib internal pixel format\n\n", varFileName, image.format);
bytesCount += sprintf(txtData + bytesCount, "static unsigned char %s_DATA[%i] = { ", varFileName, dataSize);
for (int i = 0; i < dataSize - 1; i++) bytesCount += sprintf(txtData + bytesCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), ((unsigned char *)image.data)[i]);
bytesCount += sprintf(txtData + bytesCount, "0x%x };\n", ((unsigned char *)image.data)[dataSize - 1]);
byteCount += sprintf(txtData + byteCount, "static unsigned char %s_DATA[%i] = { ", varFileName, dataSize);
for (int i = 0; i < dataSize - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), ((unsigned char *)image.data)[i]);
byteCount += sprintf(txtData + byteCount, "0x%x };\n", ((unsigned char *)image.data)[dataSize - 1]);
// NOTE: Text data length exported is determined by '\0' (NULL) character
// NOTE: Text data size exported is determined by '\0' (NULL) character
success = SaveFileText(fileName, txtData);
RL_FREE(txtData);
@ -761,11 +765,11 @@ Image GenImageCellular(int width, int height, int tileSize)
int seedsPerRow = width/tileSize;
int seedsPerCol = height/tileSize;
int seedsCount = seedsPerRow*seedsPerCol;
int seedCount = seedsPerRow*seedsPerCol;
Vector2 *seeds = (Vector2 *)RL_MALLOC(seedsCount*sizeof(Vector2));
Vector2 *seeds = (Vector2 *)RL_MALLOC(seedCount*sizeof(Vector2));
for (int i = 0; i < seedsCount; i++)
for (int i = 0; i < seedCount; i++)
{
int y = (i/seedsPerRow)*tileSize + GetRandomValue(0, tileSize - 1);
int x = (i%seedsPerRow)*tileSize + GetRandomValue(0, tileSize - 1);
@ -1143,7 +1147,7 @@ Image ImageText(const char *text, int fontSize, Color color)
// Create an image from text (custom sprite font)
Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint)
{
int length = (int)strlen(text);
int size = (int)strlen(text); // Get size in bytes of text
int textOffsetX = 0; // Image drawing position X
int textOffsetY = 0; // Offset between lines (on line break '\n')
@ -1154,7 +1158,7 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
// Create image to store text
Image imText = GenImageColor((int)imSize.x, (int)imSize.y, BLANK);
for (int i = 0; i < length; i++)
for (int i = 0; i < size; i++)
{
// Get next codepoint from byte string and glyph index in font
int codepointByteCount = 0;
@ -1176,12 +1180,12 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
{
if ((codepoint != ' ') && (codepoint != '\t'))
{
Rectangle rec = { (float)(textOffsetX + font.chars[index].offsetX), (float)(textOffsetY + font.chars[index].offsetY), (float)font.recs[index].width, (float)font.recs[index].height };
ImageDraw(&imText, font.chars[index].image, (Rectangle){ 0, 0, (float)font.chars[index].image.width, (float)font.chars[index].image.height }, rec, tint);
Rectangle rec = { (float)(textOffsetX + font.glyphs[index].offsetX), (float)(textOffsetY + font.glyphs[index].offsetY), (float)font.recs[index].width, (float)font.recs[index].height };
ImageDraw(&imText, font.glyphs[index].image, (Rectangle){ 0, 0, (float)font.glyphs[index].image.width, (float)font.glyphs[index].image.height }, rec, tint);
}
if (font.chars[index].advanceX == 0) textOffsetX += (int)(font.recs[index].width + spacing);
else textOffsetX += font.chars[index].advanceX + (int)spacing;
if (font.glyphs[index].advanceX == 0) textOffsetX += (int)(font.recs[index].width + spacing);
else textOffsetX += font.glyphs[index].advanceX + (int)spacing;
}
i += (codepointByteCount - 1); // Move text bytes counter to next codepoint
@ -2181,7 +2185,7 @@ Color *LoadImageColors(Image image)
// Load colors palette from image as a Color array (RGBA - 32bit)
// NOTE: Memory allocated should be freed using UnloadImagePalette()
Color *LoadImagePalette(Image image, int maxPaletteSize, int *colorsCount)
Color *LoadImagePalette(Image image, int maxPaletteSize, int *colorCount)
{
#define COLOR_EQUAL(col1, col2) ((col1.r == col2.r)&&(col1.g == col2.g)&&(col1.b == col2.b)&&(col1.a == col2.a))
@ -2230,7 +2234,7 @@ Color *LoadImagePalette(Image image, int maxPaletteSize, int *colorsCount)
UnloadImageColors(pixels);
}
*colorsCount = palCount;
*colorCount = palCount;
return palette;
}
@ -3483,9 +3487,9 @@ void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest,
// Draw textured polygon, defined by vertex and texturecoordinates
// NOTE: Polygon center must have straight line path to all points
// without crossing perimeter, points must be in anticlockwise order
void DrawTexturePoly(Texture2D texture, Vector2 center, Vector2 *points, Vector2 *texcoords, int pointsCount, Color tint)
void DrawTexturePoly(Texture2D texture, Vector2 center, Vector2 *points, Vector2 *texcoords, int pointCount, Color tint)
{
rlCheckRenderBatchLimit((pointsCount - 1)*4);
rlCheckRenderBatchLimit((pointCount - 1)*4);
rlSetTexture(texture.id);
@ -3494,7 +3498,7 @@ void DrawTexturePoly(Texture2D texture, Vector2 center, Vector2 *points, Vector2
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
for (int i = 0; i < pointsCount - 1; i++)
for (int i = 0; i < pointCount - 1; i++)
{
rlTexCoord2f(0.5f, 0.5f);
rlVertex2f(center.x, center.y);
@ -3707,7 +3711,7 @@ Color ColorAlphaBlend(Color dst, Color src, Color tint)
}
// Get a Color struct from hexadecimal value
Color GetColor(int hexValue)
Color GetColor(unsigned int hexValue)
{
Color color;