Merge branch 'raysan5:master' into master

This commit is contained in:
630Studios 2021-08-11 16:12:36 -05:00 committed by GitHub
commit 7d2eee484f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 2194 additions and 1537 deletions

12
.gitignore vendored
View File

@ -1,6 +1,11 @@
# Ignore generated files # Ignore generated files
# ... # ...
# Ignore all without extensions
*
!*.*
!*/
# Ignore VIM's backup generated files # Ignore VIM's backup generated files
*.swp *.swp
*.swo *.swo
@ -52,6 +57,13 @@ packages/
*.a *.a
*.bc *.bc
*.so *.so
*.so.*
# Ignore wasm data in examples/
examples/**/*.wasm
examples/**/*.data
examples/**/*.js
examples/**/*.html
# Ignore files build by xcode # Ignore files build by xcode
*.mode*v* *.mode*v*

View File

@ -1,13 +1,12 @@
## raylib bindings # raylib bindings and wrappers
Some people ported raylib to other languages in form of bindings or wrappers to the library. Some people ported raylib to other languages in form of bindings or wrappers to the library. Here it is alist with all the ports available. Feel free to send a PR if you know of any binding/wrapper not in this list.
Here it is a list with the ones I'm aware of: ### Language Bindings
| name | raylib version | language | repo | | name | raylib version | language | repo |
|:------------------:|:-------------: | :--------:|----------------------------------------------------------------------| |:------------------:|:-------------: | :--------:|----------------------------------------------------------------------|
| raylib | **3.7** | [C](https://en.wikipedia.org/wiki/C_(programming_language)) | https://github.com/raysan5/raylib | | raylib | **3.7** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | https://github.com/raysan5/raylib |
| raylib-cpp | 3.7 | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | https://github.com/robloach/raylib-cpp |
| Raylib-cs | 3.7 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/ChrisDill/Raylib-cs | | Raylib-cs | 3.7 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/ChrisDill/Raylib-cs |
| raylib-cppsharp | 2.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/phxvyper/raylib-cppsharp | | raylib-cppsharp | 2.5 | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | https://github.com/phxvyper/raylib-cppsharp |
| raylib-boo | 3.7 | [Boo](http://boo-language.github.io/) | https://github.com/Rabios/raylib-boo | | raylib-boo | 3.7 | [Boo](http://boo-language.github.io/) | https://github.com/Rabios/raylib-boo |
@ -28,6 +27,7 @@ Here it is a list with the ones I'm aware of:
| raylib-luamore | 3.0 | [Lua](http://www.lua.org/) | https://github.com/HDPLocust/raylib-luamore | | raylib-luamore | 3.0 | [Lua](http://www.lua.org/) | https://github.com/HDPLocust/raylib-luamore |
| raylua | 3.7 | [Lua](http://www.lua.org/) | https://github.com/Rabios/raylua | | raylua | 3.7 | [Lua](http://www.lua.org/) | https://github.com/Rabios/raylua |
| LuaJIT-Raylib | 2.6 | [Lua](http://www.lua.org/) | https://github.com/Bambofy/LuaJIT-Raylib | | LuaJIT-Raylib | 2.6 | [Lua](http://www.lua.org/) | https://github.com/Bambofy/LuaJIT-Raylib |
| raylib-nelua | 3.7 | [nelua](https://nelua.io/) | https://github.com/edubart/nelua-decl/tree/main/libs/raylib |
| raylib-nelua | 3.0 | [Nelua](https://nelua.io/) | https://github.com/Andre-LA/raylib-nelua | | raylib-nelua | 3.0 | [Nelua](https://nelua.io/) | https://github.com/Andre-LA/raylib-nelua |
| raylib-Nim | 1.7 | [Nim](https://nim-lang.org/) | https://gitlab.com/define-private-public/raylib-Nim | | raylib-Nim | 1.7 | [Nim](https://nim-lang.org/) | https://gitlab.com/define-private-public/raylib-Nim |
| raylib-nim | 2.0 | [Nim](https://nim-lang.org/) | https://github.com/Skrylar/raylib-nim | | raylib-nim | 2.0 | [Nim](https://nim-lang.org/) | https://github.com/Skrylar/raylib-nim |
@ -96,10 +96,16 @@ Here it is a list with the ones I'm aware of:
| raylib-never | 3.0 | [Never](https://github.com/never-lang/never) | https://github.com/never-lang/raylib-never | | raylib-never | 3.0 | [Never](https://github.com/never-lang/never) | https://github.com/never-lang/raylib-never |
| hb-raylib | 3.5 | [Harbour](https://harbour.github.io) | https://github.com/MarcosLeonardoMendezGerencir/hb-raylib | | hb-raylib | 3.5 | [Harbour](https://harbour.github.io) | https://github.com/MarcosLeonardoMendezGerencir/hb-raylib |
| Relib | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | https://github.com/RedCubeDev-ByteSpace/Relib | | Relib | 3.5 | [ReCT](https://github.com/RedCubeDev-ByteSpace/ReCT) | https://github.com/RedCubeDev-ByteSpace/Relib |
| rayex | 3.7 | [elixir](https://elixir-lang.org/) | https://github.com/shiryel/rayex |
| raylib.cbl | 2.0 | [COBOL](https://en.wikipedia.org/wiki/COBOL) | *[code examples](https://github.com/Martinfx/Cobol/tree/master/OpenCobol/Games/raylib)* | | raylib.cbl | 2.0 | [COBOL](https://en.wikipedia.org/wiki/COBOL) | *[code examples](https://github.com/Martinfx/Cobol/tree/master/OpenCobol/Games/raylib)* |
### Utility Wrapers
| name | raylib version | language | repo |
|:------------------:|:-------------: | :--------:|----------------------------------------------------------------------|
| raylib-cpp | 3.7 | [C++](https://en.wikipedia.org/wiki/C%2B%2B) | https://github.com/robloach/raylib-cpp |
Missing some language? Feel free to create a new binding! :) Missing some language or wrapper? Feel free to create a new one! :)
Usually, raylib bindings follow the convention: `raylib-{language}` Usually, raylib bindings follow the convention: `raylib-{language}`

View File

@ -3,6 +3,17 @@ changelog
Current Release: raylib 3.7.0 (26 April 2021) Current Release: raylib 3.7.0 (26 April 2021)
-------------------------------------------------------------------------
Release: raylib 4.0 (November? 2021)
-------------------------------------------------------------------------
KEY CHANGES:
-
-
-
Detailed changes:
------------------------------------------------------------------------- -------------------------------------------------------------------------
Release: raylib 3.7 (26 April 2021) Release: raylib 3.7 (26 April 2021)
------------------------------------------------------------------------- -------------------------------------------------------------------------

View File

@ -8,7 +8,7 @@ Defines | ALL_CAPS | `#define PLATFORM_DESKTOP`
Macros | ALL_CAPS | `#define MIN(a,b) (((a)<(b))?(a):(b))` Macros | ALL_CAPS | `#define MIN(a,b) (((a)<(b))?(a):(b))`
Variables | lowerCase | `int screenWidth = 0;`, `float targetFrameTime = 0.016f;` Variables | lowerCase | `int screenWidth = 0;`, `float targetFrameTime = 0.016f;`
Local variables | lowerCase | `Vector2 playerPosition = { 0 };` Local variables | lowerCase | `Vector2 playerPosition = { 0 };`
Global variables | lowerCase | `bool fullscreen = false;` Global variables | lowerCase | `bool windowReady = false;`
Constants | lowerCase | `const int maxValue = 8;` Constants | lowerCase | `const int maxValue = 8;`
Pointers | MyType *pointer | `Texture2D *array = NULL;` Pointers | MyType *pointer | `Texture2D *array = NULL;`
float values | always x.xf | `float gravity = 10.0f` float values | always x.xf | `float gravity = 10.0f`

View File

@ -27,6 +27,7 @@ Note that Sponsors donations vary between sponsors, I just decided not to make a
- Merlyn Morgan-Graham ([@kavika13](https://github.com/kavika13)) - Merlyn Morgan-Graham ([@kavika13](https://github.com/kavika13))
- Toby4213 ([@Toby4213](https://github.com/Toby4213)) - Toby4213 ([@Toby4213](https://github.com/Toby4213))
- linus ([@hochbaum](https://github.com/hochbaum)) - linus ([@hochbaum](https://github.com/hochbaum))
- Nawarian ([@nawarian](https://github.com/nawarian) - [thephp.website](https://thephp.website/))
### Past raylib GitHub Sponsors ### Past raylib GitHub Sponsors

View File

@ -195,7 +195,7 @@ endif
# -std=gnu99 defines C language mode (GNU C from 1999 revision) # -std=gnu99 defines C language mode (GNU C from 1999 revision)
# -Wno-missing-braces ignore invalid warning (GCC bug 53119) # -Wno-missing-braces ignore invalid warning (GCC bug 53119)
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec # -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
CFLAGS += -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces CFLAGS += -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces -Wunused-result
ifeq ($(BUILD_MODE),DEBUG) ifeq ($(BUILD_MODE),DEBUG)
CFLAGS += -g CFLAGS += -g
@ -244,7 +244,7 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
# --memory-init-file 0 # to avoid an external memory initialization code file (.mem) # --memory-init-file 0 # to avoid an external memory initialization code file (.mem)
# --preload-file resources # specify a resources folder for data compilation # --preload-file resources # specify a resources folder for data compilation
# --source-map-base # allow debugging in browser with source map # --source-map-base # allow debugging in browser with source map
CFLAGS += -s USE_GLFW=3 -s ASYNCIFY -s TOTAL_MEMORY=67108864 -s FORCE_FILESYSTEM=1 $(dir $<)resources@resources CFLAGS += -s USE_GLFW=3 -s ASYNCIFY -s TOTAL_MEMORY=67108864 -s FORCE_FILESYSTEM=1 --preload-file $(dir $<)resources@resources
# NOTE: Simple raylib examples are compiled to be interpreter with asyncify, that way, # NOTE: Simple raylib examples are compiled to be interpreter with asyncify, that way,
# we can compile same code for ALL platforms with no change required, but, working on bigger # we can compile same code for ALL platforms with no change required, but, working on bigger

View File

@ -14,6 +14,8 @@
#include "raylib.h" #include "raylib.h"
#include "rlgl.h" #include "rlgl.h"
#include <math.h> // Required for: cosf(), sinf()
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module Functions Declaration // Module Functions Declaration
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------

View File

@ -11,6 +11,7 @@
#include "raylib.h" #include "raylib.h"
#include "rlgl.h" #include "rlgl.h"
#include "raymath.h"
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
#define GLSL_VERSION 330 #define GLSL_VERSION 330

View File

@ -12,7 +12,7 @@
#include "raylib.h" #include "raylib.h"
#define RNET_IMPLEMENTATION #define RNET_IMPLEMENTATION
#include "rnet.h" #include "extras/rnet.h"
float elapsed = 0.0f; float elapsed = 0.0f;
float delay = 1.0f; float delay = 1.0f;

View File

@ -12,7 +12,7 @@
#include "raylib.h" #include "raylib.h"
#define RNET_IMPLEMENTATION #define RNET_IMPLEMENTATION
#include "rnet.h" #include "extras/rnet.h"
int main(void) int main(void)
{ {

View File

@ -12,7 +12,7 @@
#include "raylib.h" #include "raylib.h"
#define RNET_IMPLEMENTATION #define RNET_IMPLEMENTATION
#include "rnet.h" #include "extras/rnet.h"
int main(void) int main(void)
{ {

View File

@ -12,7 +12,7 @@
#include "raylib.h" #include "raylib.h"
#define RNET_IMPLEMENTATION #define RNET_IMPLEMENTATION
#include "rnet.h" #include "extras/rnet.h"
int main(void) int main(void)
{ {

View File

@ -12,7 +12,7 @@
#include "raylib.h" #include "raylib.h"
#define RNET_IMPLEMENTATION #define RNET_IMPLEMENTATION
#include "rnet.h" #include "extras/rnet.h"
#include <assert.h> #include <assert.h>

View File

@ -12,7 +12,7 @@
#include "raylib.h" #include "raylib.h"
#define RNET_IMPLEMENTATION #define RNET_IMPLEMENTATION
#include "rnet.h" #include "extras/rnet.h"
int main(void) int main(void)
{ {

View File

@ -12,7 +12,7 @@
#include "raylib.h" #include "raylib.h"
#define RNET_IMPLEMENTATION #define RNET_IMPLEMENTATION
#include "rnet.h" #include "extras/rnet.h"
int main(void) int main(void)
{ {

View File

@ -2,7 +2,7 @@
* *
* raylib [shaders] example - OpenGL point particle system * raylib [shaders] example - OpenGL point particle system
* *
* This example has been created using raylib 2ad3eb1 (www.raylib.com) * 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) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
* *
* Example contributed by Stephan Soller (@arkanis - http://arkanis.de/) * Example contributed by Stephan Soller (@arkanis - http://arkanis.de/)
@ -24,8 +24,9 @@
********************************************************************************************/ ********************************************************************************************/
#include "raylib.h" #include "raylib.h"
#include "rlgl.h" #include "rlgl.h" // Required for: rlDrawRenderBatchActive(), rlGetMatrixModelview(), rlGetMatrixProjection()
#include "glad.h" #include "glad.h" // Required for: OpenGL functionality
#include "raymath.h" // Required for: MatrixMultiply(), MatrixToFloat()
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
#define GLSL_VERSION 330 #define GLSL_VERSION 330
@ -33,6 +34,15 @@
#define GLSL_VERSION 100 #define GLSL_VERSION 100
#endif #endif
#define MAX_PARTICLES 1000
// Particle type
typedef struct Particle {
float x;
float y;
float period;
} Particle;
int main() int main()
{ {
// Initialization // Initialization
@ -42,32 +52,34 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib - point particles"); InitWindow(screenWidth, screenHeight, "raylib - point particles");
Shader shader = LoadShader( Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/point_particle.vs", GLSL_VERSION),
TextFormat("resources/shaders/glsl%i/point_particle.vs", GLSL_VERSION), TextFormat("resources/shaders/glsl%i/point_particle.fs", GLSL_VERSION));
TextFormat("resources/shaders/glsl%i/point_particle.fs", GLSL_VERSION));
int currentTimeLoc = GetShaderLocation(shader, "currentTime"); int currentTimeLoc = GetShaderLocation(shader, "currentTime");
int colorLoc = GetShaderLocation(shader, "color"); int colorLoc = GetShaderLocation(shader, "color");
// Initialize the vertex buffer for the particles and assign each particle random values // Initialize the vertex buffer for the particles and assign each particle random values
struct { float x, y, period; } particles[10000]; Particle particles[MAX_PARTICLES] = { 0 };
const size_t particleCount = sizeof(particles) / sizeof(particles[0]);
for (size_t i = 0; i < particleCount; i++) for (int i = 0; i < MAX_PARTICLES; i++)
{ {
particles[i].x = GetRandomValue(20, screenWidth - 20); particles[i].x = (float)GetRandomValue(20, screenWidth - 20);
particles[i].y = GetRandomValue(50, screenHeight - 20); particles[i].y = (float)GetRandomValue(50, screenHeight - 20);
// Give each particle a slightly different period. But don't spread it to much. This way the particles line up
// every so often and you get a glimps of what is going on. // Give each particle a slightly different period. But don't spread it to much.
particles[i].period = GetRandomValue(10, 30) / 10.0f; // This way the particles line up every so often and you get a glimps of what is going on.
particles[i].period = (float)GetRandomValue(10, 30)/10.0f;
} }
// Create a plain OpenGL vertex buffer with the data and an vertex array object that feeds the data from the buffer // Create a plain OpenGL vertex buffer with the data and an vertex array object
// into the vertexPosition shader attribute. // that feeds the data from the buffer into the vertexPosition shader attribute.
GLuint vao = 0, vbo = 0; GLuint vao = 0;
GLuint vbo = 0;
glGenVertexArrays(1, &vao); glGenVertexArrays(1, &vao);
glBindVertexArray(vao); glBindVertexArray(vao);
glGenBuffers(1, &vbo); glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(particles), particles, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, MAX_PARTICLES*sizeof(Particle), particles, GL_STATIC_DRAW);
// Note: LoadShader() automatically fetches the attribute index of "vertexPosition" and saves it in shader.locs[SHADER_LOC_VERTEX_POSITION] // Note: LoadShader() automatically fetches the attribute index of "vertexPosition" and saves it in shader.locs[SHADER_LOC_VERTEX_POSITION]
glVertexAttribPointer(shader.locs[SHADER_LOC_VERTEX_POSITION], 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(shader.locs[SHADER_LOC_VERTEX_POSITION], 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -89,32 +101,33 @@ int main()
ClearBackground(WHITE); ClearBackground(WHITE);
DrawRectangle(10, 10, 210, 30, MAROON); DrawRectangle(10, 10, 210, 30, MAROON);
DrawText(TextFormat("%zu particles in one vertex buffer", particleCount), 20, 20, 10, RAYWHITE); DrawText(TextFormat("%zu particles in one vertex buffer", MAX_PARTICLES), 20, 20, 10, RAYWHITE);
rlDrawRenderBatchActive(); // Draw iternal buffers data (previous draw calls)
// Switch to plain OpenGL // Switch to plain OpenGL
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// rlglDraw() in raylib 3.5
rlDrawRenderBatchActive();
glUseProgram(shader.id); glUseProgram(shader.id);
glUniform1f(currentTimeLoc, GetTime()); glUniform1f(currentTimeLoc, GetTime());
Vector4 color = ColorNormalize((Color){ 255, 0, 0, 128 }); Vector4 color = ColorNormalize((Color){ 255, 0, 0, 128 });
glUniform4fv(colorLoc, 1, (float*)&color); glUniform4fv(colorLoc, 1, (float *)&color);
// The the current model view projection matrix so the particle system is displayed and transformed // Get the current modelview and projection matrix so the particle system is displayed and transformed
// (e.g. by cameras) just like everything else.
// GetMatrixModelview() and GetMatrixProjection() in raylib 3.5
Matrix modelViewProjection = MatrixMultiply(rlGetMatrixModelview(), rlGetMatrixProjection()); Matrix modelViewProjection = MatrixMultiply(rlGetMatrixModelview(), rlGetMatrixProjection());
glUniformMatrix4fv(shader.locs[SHADER_LOC_MATRIX_MVP], 1, false, MatrixToFloat(modelViewProjection)); glUniformMatrix4fv(shader.locs[SHADER_LOC_MATRIX_MVP], 1, false, MatrixToFloat(modelViewProjection));
glBindVertexArray(vao); glBindVertexArray(vao);
glDrawArrays(GL_POINTS, 0, particleCount); glDrawArrays(GL_POINTS, 0, MAX_PARTICLES);
glBindVertexArray(0); glBindVertexArray(0);
glUseProgram(0); glUseProgram(0);
// And back to raylib again
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
DrawFPS(screenWidth - 100, 10); DrawFPS(screenWidth - 100, 10);
EndDrawing(); EndDrawing();
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
} }
@ -124,8 +137,9 @@ int main()
glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao); glDeleteVertexArrays(1, &vao);
UnloadShader(shader); UnloadShader(shader); // Unload shader
CloseWindow(); // Close window and OpenGL context
CloseWindow(); // Close window and OpenGL context
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;

View File

Before

Width:  |  Height:  |  Size: 263 KiB

After

Width:  |  Height:  |  Size: 263 KiB

View File

@ -2,18 +2,17 @@
* *
* raylib [rlgl] example - Using rlgl module as standalone module * raylib [rlgl] example - Using rlgl module as standalone module
* *
* NOTE: This example requires OpenGL 3.3 or ES2 versions for shaders support, * rlgl library is an abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, ES 2.0)
* that provides a pseudo-OpenGL 1.1 immediate-mode style API (rlVertex, rlTranslate, rlRotate...)
*
* NOTE: This example requires OpenGL 3.3 or OpenGL ES 2.0 for shaders support,
* OpenGL 1.1 does not support shaders but it can also be used. * OpenGL 1.1 does not support shaders but it can also be used.
* *
* DEPENDENCIES: * DEPENDENCIES:
* rlgl.h - OpenGL 1.1 immediate-mode style coding translation layer
* glad.h - OpenGL extensions initialization library (required by rlgl)
* raymath.h - 3D math library (required by rlgl)
* glfw3 - Windows and context initialization library * glfw3 - Windows and context initialization library
* * rlgl.h - OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2
* rlgl library is provided as a single-file header-only library, this library * glad.h - OpenGL extensions initialization library (required by rlgl)
* allows coding in a pseudo-OpenGL 1.1 style while translating calls to multiple * raymath.h - 3D math library
* OpenGL versions backends (1.1, 2.1, 3.3, ES 2.0).
* *
* WINDOWS COMPILATION: * WINDOWS COMPILATION:
* gcc -o rlgl_standalone.exe rlgl_standalone.c -s -Iexternal\include -I..\..\src \ * gcc -o rlgl_standalone.exe rlgl_standalone.c -s -Iexternal\include -I..\..\src \
@ -21,15 +20,16 @@
* *
* APPLE COMPILATION: * APPLE COMPILATION:
* gcc -o rlgl_standalone rlgl_standalone.c -I../../src -Iexternal/include -Lexternal/lib \ * gcc -o rlgl_standalone rlgl_standalone.c -I../../src -Iexternal/include -Lexternal/lib \
* -lglfw3 -std=c99 -framework CoreVideo -framework OpenGL -framework OpenAL \ * -lglfw3 -framework CoreVideo -framework OpenGL -framework IOKit -framework Cocoa
* -framework IOKit -framework Cocoa -Wno-deprecated-declarations * -Wno-deprecated-declarations -std=c99 -DGRAPHICS_API_OPENGL_33
*
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
* This example is licensed under an unmodified zlib/libpng license, which is an OSI-certified, * This example is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software: * BSD-like license that allows static linking with closed source software:
* *
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5) * Copyright (c) 2014-2021 Ramon Santamaria (@raysan5)
* *
* This software is provided "as-is", without any express or implied warranty. In no event * This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software. * will the authors be held liable for any damages arising from the use of this software.
@ -48,15 +48,25 @@
* *
********************************************************************************************/ ********************************************************************************************/
// NOTE: rlgl can be configured just re-defining the following values:
//#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 // Default internal render batch elements limits
//#define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering)
//#define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture)
//#define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture())
//#define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack
//#define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported
//#define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance
//#define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance
#define RLGL_IMPLEMENTATION #define RLGL_IMPLEMENTATION
#define RLGL_STANDALONE #include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
#define RLGL_SUPPORT_TRACELOG
#include "rlgl.h" // OpenGL 1.1 immediate-mode style coding #define RAYMATH_STATIC_INLINE
#include "raymath.h" // Vector2, Vector3, Quaternion and Matrix functionality
#if defined(__EMSCRIPTEN__) #if defined(__EMSCRIPTEN__)
#define GLFW_INCLUDE_ES2 #define GLFW_INCLUDE_ES2
#endif #endif
#include "GLFW/glfw3.h" // Windows/Context and inputs management #include "GLFW/glfw3.h" // Windows/Context and inputs management
#include <stdio.h> // Required for: printf() #include <stdio.h> // Required for: printf()
@ -65,6 +75,9 @@
#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo) #define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray #define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
//----------------------------------------------------------------------------------
// Structures Definition
//----------------------------------------------------------------------------------
// Color, 4 components, R8G8B8A8 (32bit) // Color, 4 components, R8G8B8A8 (32bit)
typedef struct Color { typedef struct Color {
unsigned char r; // Color red value unsigned char r; // Color red value
@ -94,6 +107,12 @@ static void DrawCube(Vector3 position, float width, float height, float length,
static void DrawCubeWires(Vector3 position, float width, float height, float length, Color color); static void DrawCubeWires(Vector3 position, float width, float height, float length, Color color);
static void DrawRectangleV(Vector2 position, Vector2 size, Color color); static void DrawRectangleV(Vector2 position, Vector2 size, Color color);
// NOTE: We use raymath to get this functionality but it could be implemented in this module
//static Matrix MatrixIdentity(void);
//static Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far);
//static Matrix MatrixPerspective(double fovy, double aspect, double near, double far);
//static Matrix MatrixLookAt(Vector3 eye, Vector3 target, Vector3 up);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Main Entry point // Main Entry point
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -125,7 +144,6 @@ int main(void)
glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE ); glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE );
#endif #endif
GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "rlgl standalone", NULL, NULL); GLFWwindow *window = glfwCreateWindow(screenWidth, screenHeight, "rlgl standalone", NULL, NULL);
if (!window) if (!window)
@ -200,8 +218,8 @@ int main(void)
// Draw '2D' elements in the scene (GUI) // Draw '2D' elements in the scene (GUI)
//----------------------------------------------- //-----------------------------------------------
#define RLGL_CREATE_MATRIX_MANUALLY #define RLGL_SET_MATRIX_MANUALLY
#if defined(RLGL_CREATE_MATRIX_MANUALLY) #if defined(RLGL_SET_MATRIX_MANUALLY)
matProj = MatrixOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); matProj = MatrixOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0);
matView = MatrixIdentity(); matView = MatrixIdentity();
@ -218,7 +236,7 @@ int main(void)
#endif #endif
DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 780.0f, 20.0f }, DARKGRAY); DrawRectangleV((Vector2){ 10.0f, 10.0f }, (Vector2){ 780.0f, 20.0f }, DARKGRAY);
// Draw internal render batch buffers (3D data) // Draw internal render batch buffers (2D data)
rlDrawRenderBatchActive(); rlDrawRenderBatchActive();
//----------------------------------------------- //-----------------------------------------------

View File

@ -14,7 +14,7 @@
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#include "physac.h" #include "extras/physac.h"
int main(void) int main(void)
{ {

View File

@ -14,7 +14,7 @@
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#include "physac.h" #include "extras/physac.h"
int main(void) int main(void)
{ {

View File

@ -14,7 +14,7 @@
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#include "physac.h" #include "extras/physac.h"
#define VELOCITY 0.5f #define VELOCITY 0.5f

View File

@ -14,7 +14,7 @@
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#include "physac.h" #include "extras/physac.h"
int main(void) int main(void)
{ {

View File

@ -14,7 +14,7 @@
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#include "physac.h" #include "extras/physac.h"
int main(void) int main(void)
{ {

View File

@ -9,3 +9,5 @@
| raysan.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - | | raysan.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
| space.png | ❔ | ❔ | - | | space.png | ❔ | ❔ | - |
| texel_checker.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [UV Checker Map Maker](http://uvchecker.byvalle.com/) | | texel_checker.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | Made with [UV Checker Map Maker](http://uvchecker.byvalle.com/) |
| egg.png | [@GoldenThumbs](https://github.com/GoldenThumbs) |
| torus.png | [@GoldenThumbs](https://github.com/GoldenThumbs) |

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

View File

@ -0,0 +1,35 @@
#version 100
precision mediump float;
// Input vertex attributes (from vertex shader)
varying vec2 fragTexCoord;
varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
uniform vec2 texScale;
// Function for drawing outlines on alpha-blended textures
vec4 DrawOutline(sampler2D tex, vec2 uv, vec2 lineScale, vec3 lineCol)
{
vec2 texelScale = 1.0 / lineScale;
vec4 center = texture2D(tex, uv); // We sample the center texel, (with all color data)
// Next we sample four corner texels, but only for the alpha channel (this is for the outline)
vec4 corners;
corners.x = texture2D(tex, uv+vec2( texelScale.x, texelScale.y)).a;
corners.y = texture2D(tex, uv+vec2( texelScale.x,-texelScale.y)).a;
corners.z = texture2D(tex, uv+vec2(-texelScale.x, texelScale.y)).a;
corners.w = texture2D(tex, uv+vec2(-texelScale.x,-texelScale.y)).a;
float outline = min(dot(corners, vec4(1.0)), 1.0);
vec4 col = mix(vec4(0.0), vec4(lineCol, 1.0), outline);
col = mix(col, center, center.a);
return col;
}
void main()
{
gl_FragColor = DrawOutline(texture0, fragTexCoord, texScale, vec3(0.0));
}

View File

@ -0,0 +1,36 @@
#version 330
// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
uniform vec2 texScale;
// Output fragment color
out vec4 finalColor;
// Function for drawing outlines on alpha-blended textures
vec4 DrawOutline(sampler2D tex, vec2 uv, vec2 lineScale, vec3 lineCol)
{
vec2 texelScale = 1.0 / lineScale;
vec4 center = texture(tex, uv); // We sample the center texel, (with all color data)
// Next we sample four corner texels, but only for the alpha channel (this is for the outline)
vec4 corners;
corners.x = texture(tex, uv+vec2( texelScale.x, texelScale.y)).a;
corners.y = texture(tex, uv+vec2( texelScale.x,-texelScale.y)).a;
corners.z = texture(tex, uv+vec2(-texelScale.x, texelScale.y)).a;
corners.w = texture(tex, uv+vec2(-texelScale.x,-texelScale.y)).a;
float outline = min(dot(corners, vec4(1.0)), 1.0);
vec4 col = mix(vec4(0.0), vec4(lineCol, 1.0), outline);
col = mix(col, center, center.a);
return col;
}
void main()
{
finalColor = DrawOutline(texture0, fragTexCoord, texScale, vec3(0.0));
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

View File

@ -77,7 +77,7 @@ int main(void)
// Try reloading updated shader // Try reloading updated shader
Shader updatedShader = LoadShader(0, TextFormat(fragShaderFileName, GLSL_VERSION)); Shader updatedShader = LoadShader(0, TextFormat(fragShaderFileName, GLSL_VERSION));
if (updatedShader.id != rlGetShaderDefault().id) // It was correctly loaded if (updatedShader.id != rlGetShaderIdDefault()) // It was correctly loaded
{ {
UnloadShader(shader); UnloadShader(shader);
shader = updatedShader; shader = updatedShader;

View File

@ -0,0 +1,84 @@
/*******************************************************************************************
*
* raylib [shaders] example - Apply an shdrOutline to a texture
*
* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
*
* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3).
*
* 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 Samuel Skiff (@GoldenThumbs)
*
* Copyright (c) 2021 Samuel SKiff (@GoldenThumbs) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#if defined(PLATFORM_DESKTOP)
#define GLSL_VERSION 330
#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
#define GLSL_VERSION 100
#endif
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - Apply an shdrOutline to a texture");
Texture2D egg = LoadTexture("resources/egg.png");
Texture2D torus = LoadTexture("resources/torus.png");
Shader shdrOutline = LoadShader(0, TextFormat("resources/shaders/glsl%i/shdrOutline.fs", GLSL_VERSION));
float outlineScale = 16.0f;
float textureScale[2] = { 16.0f*4, 16.0f*4 };
SetShaderValue(shdrOutline, GetShaderLocation(shdrOutline, "texScale"), textureScale, SHADER_UNIFORM_VEC2);
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
//----------------------------------------------------------------------------------
// TODO: Update your variables here
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
BeginShaderMode(shdrOutline);
DrawTextureEx(egg, (Vector2){ 0, 230 }, 0.0, outlineScale, WHITE);
DrawTextureEx(torus, (Vector2){ 544, 230 }, 0.0, outlineScale, WHITE);
EndShaderMode();
DrawText("Shader-based shdrOutlines for textures", 190, 200, 20, LIGHTGRAY);
DrawFPS(710, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(egg);
UnloadTexture(torus);
UnloadShader(shdrOutline);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -1,263 +0,0 @@
/*******************************************************************************************
*
* raylib easings (header only file)
*
* Useful easing functions for values animation
*
* This header uses:
* #define EASINGS_STATIC_INLINE // Inlines all functions code, so it runs faster.
* // This requires lots of memory on system.
* How to use:
* The four inputs t,b,c,d are defined as follows:
* t = current time (in any unit measure, but same unit as duration)
* b = starting value to interpolate
* c = the total change in value of b that needs to occur
* d = total time it should take to complete (duration)
*
* Example:
*
* int currentTime = 0;
* int duration = 100;
* float startPositionX = 0.0f;
* float finalPositionX = 30.0f;
* float currentPositionX = startPositionX;
*
* while (currentPositionX < finalPositionX)
* {
* currentPositionX = EaseSineIn(currentTime, startPositionX, finalPositionX - startPositionX, duration);
* currentTime++;
* }
*
* A port of Robert Penner's easing equations to C (http://robertpenner.com/easing/)
*
* Robert Penner License
* ---------------------------------------------------------------------------------
* Open source under the BSD License.
*
* Copyright (c) 2001 Robert Penner. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the author nor the names of contributors may be used
* to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ---------------------------------------------------------------------------------
*
* Copyright (c) 2015 Ramon Santamaria
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#ifndef EASINGS_H
#define EASINGS_H
#define EASINGS_STATIC_INLINE // NOTE: By default, compile functions as static inline
#if defined(EASINGS_STATIC_INLINE)
#define EASEDEF static inline
#else
#define EASEDEF extern
#endif
#include <math.h> // Required for: sin(), cos(), sqrt(), pow()
#ifndef PI
#define PI 3.14159265358979323846f //Required as PI is not always defined in math.h
#endif
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
// Linear Easing functions
EASEDEF float EaseLinearNone(float t, float b, float c, float d) { return (c*t/d + b); }
EASEDEF float EaseLinearIn(float t, float b, float c, float d) { return (c*t/d + b); }
EASEDEF float EaseLinearOut(float t, float b, float c, float d) { return (c*t/d + b); }
EASEDEF float EaseLinearInOut(float t,float b, float c, float d) { return (c*t/d + b); }
// Sine Easing functions
EASEDEF float EaseSineIn(float t, float b, float c, float d) { return (-c*cos(t/d*(PI/2)) + c + b); }
EASEDEF float EaseSineOut(float t, float b, float c, float d) { return (c*sin(t/d*(PI/2)) + b); }
EASEDEF float EaseSineInOut(float t, float b, float c, float d) { return (-c/2*(cos(PI*t/d) - 1) + b); }
// Circular Easing functions
EASEDEF float EaseCircIn(float t, float b, float c, float d) { t /= d; return (-c*(sqrt(1 - t*t) - 1) + b); }
EASEDEF float EaseCircOut(float t, float b, float c, float d) { t = t/d - 1; return (c*sqrt(1 - t*t) + b); }
EASEDEF float EaseCircInOut(float t, float b, float c, float d)
{
if ((t/=d/2) < 1) return (-c/2*(sqrt(1 - t*t) - 1) + b);
t -= 2; return (c/2*(sqrt(1 - t*t) + 1) + b);
}
// Cubic Easing functions
EASEDEF float EaseCubicIn(float t, float b, float c, float d) { t /= d; return (c*t*t*t + b); }
EASEDEF float EaseCubicOut(float t, float b, float c, float d) { t = t/d-1; return (c*(t*t*t + 1) + b); }
EASEDEF float EaseCubicInOut(float t, float b, float c, float d)
{
if ((t/=d/2) < 1) return (c/2*t*t*t + b);
t -= 2; return (c/2*(t*t*t + 2) + b);
}
// Quadratic Easing functions
EASEDEF float EaseQuadIn(float t, float b, float c, float d) { t /= d; return (c*t*t + b); }
EASEDEF float EaseQuadOut(float t, float b, float c, float d) { t /= d; return (-c*t*(t - 2) + b); }
EASEDEF float EaseQuadInOut(float t, float b, float c, float d)
{
if ((t/=d/2) < 1) return (((c/2)*(t*t)) + b);
t--; return (-c/2*(((t - 2)*t) - 1) + b);
}
// Exponential Easing functions
EASEDEF float EaseExpoIn(float t, float b, float c, float d) { return (t == 0) ? b : (c*pow(2, 10*(t/d - 1)) + b); }
EASEDEF float EaseExpoOut(float t, float b, float c, float d) { return (t == d) ? (b + c) : (c*(-pow(2, -10*t/d) + 1) + b); }
EASEDEF float EaseExpoInOut(float t, float b, float c, float d)
{
if (t == 0) return b;
if (t == d) return (b + c);
if ((t/=d/2) < 1) return (c/2*pow(2, 10*(t - 1)) + b);
return (c/2*(-pow(2, -10*--t) + 2) + b);
}
// Back Easing functions
EASEDEF float EaseBackIn(float t, float b, float c, float d)
{
float s = 1.70158f;
float postFix = t/=d;
return (c*(postFix)*t*((s + 1)*t - s) + b);
}
EASEDEF float EaseBackOut(float t, float b, float c, float d)
{
float s = 1.70158f;
t = t/d - 1;
return (c*(t*t*((s + 1)*t + s) + 1) + b);
}
EASEDEF float EaseBackInOut(float t, float b, float c, float d)
{
float s = 1.70158f;
if ((t/=d/2) < 1)
{
s *= 1.525f;
return (c/2*(t*t*((s + 1)*t - s)) + b);
}
float postFix = t-=2;
s *= 1.525f;
return (c/2*((postFix)*t*((s + 1)*t + s) + 2) + b);
}
// Bounce Easing functions
EASEDEF float EaseBounceOut(float t, float b, float c, float d)
{
if ((t/=d) < (1/2.75f))
{
return (c*(7.5625f*t*t) + b);
}
else if (t < (2/2.75f))
{
float postFix = t-=(1.5f/2.75f);
return (c*(7.5625f*(postFix)*t + 0.75f) + b);
}
else if (t < (2.5/2.75))
{
float postFix = t-=(2.25f/2.75f);
return (c*(7.5625f*(postFix)*t + 0.9375f) + b);
}
else
{
float postFix = t-=(2.625f/2.75f);
return (c*(7.5625f*(postFix)*t + 0.984375f) + b);
}
}
EASEDEF float EaseBounceIn(float t, float b, float c, float d) { return (c - EaseBounceOut(d-t, 0, c, d) + b); }
EASEDEF float EaseBounceInOut(float t, float b, float c, float d)
{
if (t < d/2) return (EaseBounceIn(t*2, 0, c, d)*0.5f + b);
else return (EaseBounceOut(t*2-d, 0, c, d)*0.5f + c*0.5f + b);
}
// Elastic Easing functions
EASEDEF float EaseElasticIn(float t, float b, float c, float d)
{
if (t == 0) return b;
if ((t/=d) == 1) return (b + c);
float p = d*0.3f;
float a = c;
float s = p/4;
float postFix = a*pow(2, 10*(t-=1));
return (-(postFix*sin((t*d-s)*(2*PI)/p )) + b);
}
EASEDEF float EaseElasticOut(float t, float b, float c, float d)
{
if (t == 0) return b;
if ((t/=d) == 1) return (b + c);
float p = d*0.3f;
float a = c;
float s = p/4;
return (a*pow(2,-10*t)*sin((t*d-s)*(2*PI)/p) + c + b);
}
EASEDEF float EaseElasticInOut(float t, float b, float c, float d)
{
if (t == 0) return b;
if ((t/=d/2) == 2) return (b + c);
float p = d*(0.3f*1.5f);
float a = c;
float s = p/4;
if (t < 1)
{
float postFix = a*pow(2, 10*(t-=1));
return -0.5f*(postFix*sin((t*d-s)*(2*PI)/p)) + b;
}
float postFix = a*pow(2, -10*(t-=1));
return (postFix*sin((t*d-s)*(2*PI)/p)*0.5f + c + b);
}
#ifdef __cplusplus
}
#endif
#endif // EASINGS_H

View File

@ -14,7 +14,7 @@
#include <raylib.h> #include <raylib.h>
#define RAYGUI_IMPLEMENTATION #define RAYGUI_IMPLEMENTATION
#include "raygui.h" // Required for GUI controls #include "extras/raygui.h" // Required for GUI controls
int main(void) int main(void)
{ {

View File

@ -14,7 +14,7 @@
#include <raylib.h> #include <raylib.h>
#define RAYGUI_IMPLEMENTATION #define RAYGUI_IMPLEMENTATION
#include "raygui.h" // Required for GUI controls #include "extras/raygui.h" // Required for GUI controls
int main(void) int main(void)
{ {

View File

@ -14,7 +14,7 @@
#include <raylib.h> #include <raylib.h>
#define RAYGUI_IMPLEMENTATION #define RAYGUI_IMPLEMENTATION
#include "raygui.h" // Required for GUI controls #include "extras/raygui.h" // Required for GUI controls
int main(void) int main(void)
{ {

View File

@ -11,7 +11,7 @@
#include "raylib.h" #include "raylib.h"
#include "easings.h" // Required for easing functions #include "extras/easings.h" // Required for easing functions
int main(void) int main(void)
{ {

View File

@ -11,7 +11,7 @@
#include "raylib.h" #include "raylib.h"
#include "easings.h" // Required for easing functions #include "extras/easings.h" // Required for easing functions
int main(void) int main(void)
{ {

View File

@ -14,7 +14,7 @@
#include "raylib.h" #include "raylib.h"
#include "easings.h" // Required for easing functions #include "extras/easings.h" // Required for easing functions
#define RECS_WIDTH 50 #define RECS_WIDTH 50
#define RECS_HEIGHT 50 #define RECS_HEIGHT 50

View File

@ -138,9 +138,9 @@ int main(void)
DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha)); DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha));
DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha)); DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha));
DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha)); DrawRectangle(GetScreenWidth()/2 - 112, GetScreenHeight()/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
DrawText(TextSubtext("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha)); DrawText(TextSubtext("raylib", 0, lettersCount), GetScreenWidth()/2 - 44, GetScreenHeight()/2 + 48, 50, Fade(BLACK, alpha));
} }
else if (state == 4) else if (state == 4)
{ {

View File

@ -5,14 +5,14 @@
* Draw a 2D text in 3D space, each letter is drawn in a quad (or 2 quads if backface is set) * Draw a 2D text in 3D space, each letter is drawn in a quad (or 2 quads if backface is set)
* where the texture coodinates of each quad map to the texture coordinates of the glyphs * where the texture coodinates of each quad map to the texture coordinates of the glyphs
* inside the font texture. * inside the font texture.
* A more efficient approach, i believe, would be to render the text in a render texture and * A more efficient approach, i believe, would be to render the text in a render texture and
* map that texture to a plane and render that, or maybe a shader but my method allows more * map that texture to a plane and render that, or maybe a shader but my method allows more
* flexibility...for example to change position of each letter individually to make somethink * flexibility...for example to change position of each letter individually to make somethink
* like a wavy text effect. * like a wavy text effect.
* *
* Special thanks to: * Special thanks to:
* @Nighten for the DrawTextStyle() code https://github.com/NightenDushi/Raylib_DrawTextStyle * @Nighten for the DrawTextStyle() code https://github.com/NightenDushi/Raylib_DrawTextStyle
* Chris Camacho (codifies - http://bedroomcoders.co.uk/) for the alpha discard shader * Chris Camacho (codifies - http://bedroomcoders.co.uk/) for the alpha discard shader
* *
* This example has been created using raylib 3.5 (www.raylib.com) * This example has been created using raylib 3.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
@ -196,7 +196,7 @@ int main(void)
(Vector3){ cubePosition.x + cubeSize.x/2, cubePosition.y + cubeSize.y/2, cubePosition.z + cubeSize.z/2 }}); (Vector3){ cubePosition.x + cubeSize.x/2, cubePosition.y + cubeSize.y/2, cubePosition.z + cubeSize.z/2 }});
if (collision.hit) if (collision.hit)
{ {
// Generate new random colors // Generate new random colors
light = GenerateRandomColor(0.5f, 0.78f); light = GenerateRandomColor(0.5f, 0.78f);
dark = GenerateRandomColor(0.4f, 0.58f); dark = GenerateRandomColor(0.4f, 0.58f);
} }

View File

@ -13,6 +13,10 @@
#include "raylib.h" #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
// Main entry point
int main(void) int main(void)
{ {
// Initialization // Initialization
@ -119,4 +123,144 @@ tempor incididunt ut labore et dolore magna aliqua. Nec ullamcorper sit amet ris
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
}
//--------------------------------------------------------------------------------------
// Module functions definition
//--------------------------------------------------------------------------------------
// 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)
{
DrawTextRecEx(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)
{
int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop
float textOffsetY = 0; // Offset between lines (on line break '\n')
float textOffsetX = 0.0f; // Offset X to next character to draw
float scaleFactor = fontSize/(float)font.baseSize; // Character rectangle scaling factor
// Word/character wrapping mechanism variables
enum { MEASURE_STATE = 0, DRAW_STATE = 1 };
int state = wordWrap? MEASURE_STATE : DRAW_STATE;
int startLine = -1; // Index where to begin drawing (where a line begins)
int endLine = -1; // Index where to stop drawing (where a line ends)
int lastk = -1; // Holds last value of the character position
for (int i = 0, k = 0; i < length; i++, k++)
{
// Get next codepoint from byte string and glyph index in font
int codepointByteCount = 0;
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
int index = GetGlyphIndex(font, codepoint);
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
// but we need to draw all of the bad bytes using the '?' symbol moving one byte
if (codepoint == 0x3f) codepointByteCount = 1;
i += (codepointByteCount - 1);
float glyphWidth = 0;
if (codepoint != '\n')
{
glyphWidth = (font.chars[index].advanceX == 0) ? font.recs[index].width*scaleFactor : font.chars[index].advanceX*scaleFactor;
if (i + 1 < length) glyphWidth = glyphWidth + spacing;
}
// NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside of the rec container
// We store this info in startLine and endLine, then we change states, draw the text between those two variables
// and change states again and again recursively until the end of the text (or until we get outside of the container).
// When wordWrap is OFF we don't need the measure state so we go to the drawing state immediately
// and begin drawing on the next line before we can get outside the container.
if (state == MEASURE_STATE)
{
// TODO: There are multiple types of spaces in UNICODE, maybe it's a good idea to add support for more
// Ref: http://jkorpela.fi/chars/spaces.html
if ((codepoint == ' ') || (codepoint == '\t') || (codepoint == '\n')) endLine = i;
if ((textOffsetX + glyphWidth) > rec.width)
{
endLine = (endLine < 1)? i : endLine;
if (i == endLine) endLine -= codepointByteCount;
if ((startLine + codepointByteCount) == endLine) endLine = (i - codepointByteCount);
state = !state;
}
else if ((i + 1) == length)
{
endLine = i;
state = !state;
}
else if (codepoint == '\n') state = !state;
if (state == DRAW_STATE)
{
textOffsetX = 0;
i = startLine;
glyphWidth = 0;
// Save character position when we switch states
int tmp = lastk;
lastk = k - 1;
k = tmp;
}
}
else
{
if (codepoint == '\n')
{
if (!wordWrap)
{
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
textOffsetX = 0;
}
}
else
{
if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width))
{
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
textOffsetX = 0;
}
// When text overflows rectangle height limit, just stop drawing
if ((textOffsetY + font.baseSize*scaleFactor) > rec.height) break;
// Draw selection background
bool isGlyphSelected = false;
if ((selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength)))
{
DrawRectangleRec((Rectangle){ rec.x + textOffsetX - 1, rec.y + textOffsetY, glyphWidth, (float)font.baseSize*scaleFactor }, selectBackTint);
isGlyphSelected = true;
}
// Draw current character glyph
if ((codepoint != ' ') && (codepoint != '\t'))
{
DrawTextCodepoint(font, codepoint, (Vector2){ rec.x + textOffsetX, rec.y + textOffsetY }, fontSize, isGlyphSelected? selectTint : tint);
}
}
if (wordWrap && (i == endLine))
{
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
textOffsetX = 0;
startLine = endLine;
endLine = -1;
glyphWidth = 0;
selectStart += lastk - k;
k = lastk;
state = !state;
}
}
textOffsetX += glyphWidth;
}
} }

View File

@ -133,6 +133,9 @@ struct {
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
static void RandomizeEmoji(void); // Fills the emoji array with random emojis 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
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Global variables // Global variables
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
@ -145,6 +148,9 @@ struct {
static int hovered = -1, selected = -1; static int hovered = -1, selected = -1;
//--------------------------------------------------------------------------------------
// Main entry point
//--------------------------------------------------------------------------------------
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
// Initialization // Initialization
@ -317,3 +323,143 @@ static void RandomizeEmoji(void)
emoji[i].message = GetRandomValue(0, SIZEOF(messages) - 1); emoji[i].message = GetRandomValue(0, SIZEOF(messages) - 1);
} }
} }
//--------------------------------------------------------------------------------------
// Module functions definition
//--------------------------------------------------------------------------------------
// 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)
{
DrawTextRecEx(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)
{
int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop
float textOffsetY = 0; // Offset between lines (on line break '\n')
float textOffsetX = 0.0f; // Offset X to next character to draw
float scaleFactor = fontSize/(float)font.baseSize; // Character rectangle scaling factor
// Word/character wrapping mechanism variables
enum { MEASURE_STATE = 0, DRAW_STATE = 1 };
int state = wordWrap? MEASURE_STATE : DRAW_STATE;
int startLine = -1; // Index where to begin drawing (where a line begins)
int endLine = -1; // Index where to stop drawing (where a line ends)
int lastk = -1; // Holds last value of the character position
for (int i = 0, k = 0; i < length; i++, k++)
{
// Get next codepoint from byte string and glyph index in font
int codepointByteCount = 0;
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
int index = GetGlyphIndex(font, codepoint);
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
// but we need to draw all of the bad bytes using the '?' symbol moving one byte
if (codepoint == 0x3f) codepointByteCount = 1;
i += (codepointByteCount - 1);
float glyphWidth = 0;
if (codepoint != '\n')
{
glyphWidth = (font.chars[index].advanceX == 0) ? font.recs[index].width*scaleFactor : font.chars[index].advanceX*scaleFactor;
if (i + 1 < length) glyphWidth = glyphWidth + spacing;
}
// NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside of the rec container
// We store this info in startLine and endLine, then we change states, draw the text between those two variables
// and change states again and again recursively until the end of the text (or until we get outside of the container).
// When wordWrap is OFF we don't need the measure state so we go to the drawing state immediately
// and begin drawing on the next line before we can get outside the container.
if (state == MEASURE_STATE)
{
// TODO: There are multiple types of spaces in UNICODE, maybe it's a good idea to add support for more
// Ref: http://jkorpela.fi/chars/spaces.html
if ((codepoint == ' ') || (codepoint == '\t') || (codepoint == '\n')) endLine = i;
if ((textOffsetX + glyphWidth) > rec.width)
{
endLine = (endLine < 1)? i : endLine;
if (i == endLine) endLine -= codepointByteCount;
if ((startLine + codepointByteCount) == endLine) endLine = (i - codepointByteCount);
state = !state;
}
else if ((i + 1) == length)
{
endLine = i;
state = !state;
}
else if (codepoint == '\n') state = !state;
if (state == DRAW_STATE)
{
textOffsetX = 0;
i = startLine;
glyphWidth = 0;
// Save character position when we switch states
int tmp = lastk;
lastk = k - 1;
k = tmp;
}
}
else
{
if (codepoint == '\n')
{
if (!wordWrap)
{
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
textOffsetX = 0;
}
}
else
{
if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width))
{
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
textOffsetX = 0;
}
// When text overflows rectangle height limit, just stop drawing
if ((textOffsetY + font.baseSize*scaleFactor) > rec.height) break;
// Draw selection background
bool isGlyphSelected = false;
if ((selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength)))
{
DrawRectangleRec((Rectangle){ rec.x + textOffsetX - 1, rec.y + textOffsetY, glyphWidth, (float)font.baseSize*scaleFactor }, selectBackTint);
isGlyphSelected = true;
}
// Draw current character glyph
if ((codepoint != ' ') && (codepoint != '\t'))
{
DrawTextCodepoint(font, codepoint, (Vector2){ rec.x + textOffsetX, rec.y + textOffsetY }, fontSize, isGlyphSelected? selectTint : tint);
}
}
if (wordWrap && (i == endLine))
{
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
textOffsetX = 0;
startLine = endLine;
endLine = -1;
glyphWidth = 0;
selectStart += lastk - k;
k = lastk;
state = !state;
}
}
textOffsetX += glyphWidth;
}
}

View File

@ -70,6 +70,10 @@
#define MAX_LINE_LENGTH 512 // Maximum length of one line (including comments) #define MAX_LINE_LENGTH 512 // Maximum length of one line (including comments)
#define MAX_STRUCT_LINE_LENGTH 2048 // Maximum length of one struct (multiple lines) #define MAX_STRUCT_LINE_LENGTH 2048 // Maximum length of one struct (multiple lines)
#define MAX_FUNCTION_PARAMETERS 12 // Maximum number of function parameters
#define MAX_STRUCT_FIELDS 32 // Maximum number of struct fields
#define MAX_ENUM_VALUES 512 // Maximum number of enum values
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -79,9 +83,9 @@ typedef struct FunctionInfo {
char desc[128]; // Function description (comment at the end) char desc[128]; // Function description (comment at the end)
char retType[32]; // Return value type char retType[32]; // Return value type
int paramCount; // Number of function parameters int paramCount; // Number of function parameters
char paramType[12][32]; // Parameters type (max: 12 parameters) char paramType[MAX_FUNCTION_PARAMETERS][32]; // Parameters type
char paramName[12][32]; // Parameters name (max: 12 parameters) char paramName[MAX_FUNCTION_PARAMETERS][32]; // Parameters name
char paramDesc[12][8]; // Parameters description (max: 12 parameters) char paramDesc[MAX_FUNCTION_PARAMETERS][8]; // Parameters description
} FunctionInfo; } FunctionInfo;
// Struct info data // Struct info data
@ -89,9 +93,9 @@ typedef struct StructInfo {
char name[64]; // Struct name char name[64]; // Struct name
char desc[64]; // Struct type description char desc[64]; // Struct type description
int fieldCount; // Number of fields in the struct int fieldCount; // Number of fields in the struct
char fieldType[16][32]; // Field type (max: 16 fields) char fieldType[MAX_STRUCT_FIELDS][64]; // Field type
char fieldName[16][32]; // Field name (max: 16 fields) char fieldName[MAX_STRUCT_FIELDS][64]; // Field name
char fieldDesc[16][128]; // Field description (max: 16 fields) char fieldDesc[MAX_STRUCT_FIELDS][128]; // Field description
} StructInfo; } StructInfo;
// Enum info data // Enum info data
@ -99,9 +103,9 @@ typedef struct EnumInfo {
char name[64]; // Enum name char name[64]; // Enum name
char desc[64]; // Enum description char desc[64]; // Enum description
int valueCount; // Number of values in enumerator int valueCount; // Number of values in enumerator
char valueName[128][64]; // Value name definition (max: 128 values) char valueName[MAX_ENUM_VALUES][64]; // Value name definition
int valueInteger[128]; // Value integer (max: 128 values) int valueInteger[MAX_ENUM_VALUES]; // Value integer
char valueDesc[128][64]; // Value description (max: 128 values) char valueDesc[MAX_ENUM_VALUES][64]; // Value description
} EnumInfo; } EnumInfo;
// Output format for parsed data // Output format for parsed data
@ -116,6 +120,7 @@ static int enumCount = 0;
static FunctionInfo *funcs = NULL; static FunctionInfo *funcs = NULL;
static StructInfo *structs = NULL; static StructInfo *structs = NULL;
static EnumInfo *enums = NULL; static EnumInfo *enums = NULL;
static char apiDefine[32] = "RLAPI\0";
// Command line variables // Command line variables
static char inFileName[512] = { 0 }; // Input file name (required in case of provided through CLI) static char inFileName[512] = { 0 }; // Input file name (required in case of provided through CLI)
@ -171,8 +176,8 @@ int main(int argc, char* argv[])
// Read function lines // Read function lines
for (int i = 0; i < linesCount; i++) for (int i = 0; i < linesCount; i++)
{ {
// Read function line (starting with "RLAPI") // Read function line (starting with `define`, i.e. for raylib.h "RLAPI")
if (IsTextEqual(lines[i], "RLAPI", 5)) if (IsTextEqual(lines[i], apiDefine, TextLength(apiDefine)))
{ {
// Keep a pointer to the function line // Keep a pointer to the function line
funcLines[funcCount] = lines[i]; funcLines[funcCount] = lines[i];
@ -217,12 +222,6 @@ int main(int argc, char* argv[])
j++; j++;
} }
while (buffer[i + j] != '}')
{
structLines[structCount][j] = buffer[i + j];
j++;
}
while (buffer[i + j] != '\n') while (buffer[i + j] != '\n')
{ {
structLines[structCount][j] = buffer[i + j]; structLines[structCount][j] = buffer[i + j];
@ -238,7 +237,7 @@ int main(int argc, char* argv[])
// Read enum lines // Read enum lines
for (int i = 0; i < linesCount; i++) for (int i = 0; i < linesCount; i++)
{ {
// Read function line (starting with "RLAPI") // Read enum line
if (IsTextEqual(lines[i], "typedef enum {", 14)) if (IsTextEqual(lines[i], "typedef enum {", 14))
{ {
// Keep the line position in the array of lines, // Keep the line position in the array of lines,
@ -335,7 +334,7 @@ int main(int argc, char* argv[])
{ {
// TODO: Get enum description from lines[enumLines[i] - 1] // TODO: Get enum description from lines[enumLines[i] - 1]
for (int j = 1; j < 256; j++) // Maximum number of lines following enum first line for (int j = 1; j < MAX_ENUM_VALUES*2; j++) // Maximum number of lines following enum first line
{ {
char *linePtr = lines[enumLines[i] + j]; char *linePtr = lines[enumLines[i] + j];
@ -428,8 +427,9 @@ int main(int argc, char* argv[])
// At this point we have function return type and function name // At this point we have function return type and function name
char funcRetTypeName[128] = { 0 }; char funcRetTypeName[128] = { 0 };
int funcRetTypeNameLen = c - 6; // Substract "RLAPI " int dc = TextLength(apiDefine) + 1;
MemoryCopy(funcRetTypeName, &funcLines[i][6], funcRetTypeNameLen); int funcRetTypeNameLen = c - dc; // Substract `define` ("RLAPI " for raylib.h)
MemoryCopy(funcRetTypeName, &funcLines[i][dc], funcRetTypeNameLen);
GetDataTypeAndName(funcRetTypeName, funcRetTypeNameLen, funcs[i].retType, funcs[i].name); GetDataTypeAndName(funcRetTypeName, funcRetTypeNameLen, funcs[i].retType, funcs[i].name);
break; break;
@ -525,7 +525,7 @@ static void ShowCommandLineInfo(void)
printf("//////////////////////////////////////////////////////////////////////////////////\n\n"); printf("//////////////////////////////////////////////////////////////////////////////////\n\n");
printf("USAGE:\n\n"); printf("USAGE:\n\n");
printf(" > raylib_parser [--help] [--input <filename.h>] [--output <filename.ext>] [--format <type>]\n"); printf(" > raylib_parser [--help] [--input <filename.h>] [--output <filename.ext>] [--format <type>] [--define <DEF>]\n");
printf("\nOPTIONS:\n\n"); printf("\nOPTIONS:\n\n");
printf(" -h, --help : Show tool version and command line usage help\n\n"); printf(" -h, --help : Show tool version and command line usage help\n\n");
@ -536,12 +536,16 @@ static void ShowCommandLineInfo(void)
printf(" NOTE: If not specified, defaults to: raylib_api.txt\n\n"); printf(" NOTE: If not specified, defaults to: raylib_api.txt\n\n");
printf(" -f, --format <type> : Define output format for parser data.\n"); printf(" -f, --format <type> : Define output format for parser data.\n");
printf(" Supported types: DEFAULT, JSON, XML\n\n"); printf(" Supported types: DEFAULT, JSON, XML\n\n");
printf(" -d, --define <DEF> : Define functions define (i.e. RLAPI for raylib.h, RMDEF for raymath.h, etc\n");
printf(" NOTE: If not specified, defaults to: RLAPI\n\n");
printf("\nEXAMPLES:\n\n"); printf("\nEXAMPLES:\n\n");
printf(" > raylib_parser --input raylib.h --output api.json\n"); printf(" > raylib_parser --input raylib.h --output api.json\n");
printf(" Process <raylib.h> to generate <api.json>\n\n"); printf(" Process <raylib.h> to generate <api.json>\n\n");
printf(" > raylib_parser --output raylib_data.info --format XML\n"); printf(" > raylib_parser --output raylib_data.info --format XML\n");
printf(" Process <raylib.h> to generate <raylib_data.info> as XML text data\n\n"); printf(" Process <raylib.h> to generate <raylib_data.info> as XML text data\n\n");
printf(" > raylib_parser --input raymath.h --output raymath_data.info --format XML\n");
printf(" Process <raymath.h> to generate <raymath_data.info> as XML text data\n\n");
} }
// Process command line arguments // Process command line arguments
@ -583,6 +587,16 @@ static void ProcessCommandLine(int argc, char *argv[])
} }
else printf("WARNING: No format parameters provided\n"); else printf("WARNING: No format parameters provided\n");
} }
else if (IsTextEqual(argv[i], "-d", 2) || IsTextEqual(argv[i], "--define", 8))
{
if (((i + 1) < argc) && (argv[i + 1][0] != '-'))
{
MemoryCopy(apiDefine, argv[i + 1], TextLength(argv[i + 1])); // Read functions define
apiDefine[TextLength(argv[i + 1])] = '\0';
i++;
}
else printf("WARNING: No define key provided\n");
}
} }
} }

View File

@ -313,6 +313,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\..\..\src\camera.h" /> <ClInclude Include="..\..\..\src\camera.h" />
<ClInclude Include="..\..\..\src\config.h" />
<ClInclude Include="..\..\..\src\external\glad.h" /> <ClInclude Include="..\..\..\src\external\glad.h" />
<ClInclude Include="..\..\..\src\external\jar_mod.h" /> <ClInclude Include="..\..\..\src\external\jar_mod.h" />
<ClInclude Include="..\..\..\src\external\jar_xm.h" /> <ClInclude Include="..\..\..\src\external\jar_xm.h" />

View File

@ -87,41 +87,36 @@
// Show OpenGL extensions and capabilities detailed logs on init // Show OpenGL extensions and capabilities detailed logs on init
//#define SUPPORT_GL_DETAILS_INFO 1 //#define SUPPORT_GL_DETAILS_INFO 1
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_33) //#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 4096 // Default internal render batch elements limits
#define DEFAULT_BATCH_BUFFER_ELEMENTS 8192 // Default internal render batch limits #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering)
#elif defined(GRAPHICS_API_OPENGL_ES2) #define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture)
#define DEFAULT_BATCH_BUFFER_ELEMENTS 2048 // Default internal render batch limits #define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture())
#endif
#define DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) #define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack
#define DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture)
#define MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported
#define MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh
#define MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported
#define MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported
#define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance #define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance
#define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance #define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance
// Default shader vertex attribute names to set location points // Default shader vertex attribute names to set location points
// NOTE: When a new shader is loaded, the following locations are tried to be set for convenience // NOTE: When a new shader is loaded, the following locations are tried to be set for convenience
#define DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Binded by default to shader location: 0 #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Binded by default to shader location: 0
#define DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Binded by default to shader location: 1 #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Binded by default to shader location: 1
#define DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Binded by default to shader location: 2 #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Binded by default to shader location: 2
#define DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Binded by default to shader location: 3 #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Binded by default to shader location: 3
#define DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Binded by default to shader location: 4 #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Binded by default to shader location: 4
#define DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Binded by default to shader location: 5 #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Binded by default to shader location: 5
#define DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix
#define DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix
#define DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix
#define DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix
#define DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView))
#define DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color)
#define DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0)
#define DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1)
#define DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2)
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -191,6 +186,10 @@
// NOTE: Some generated meshes DO NOT include generated texture coordinates // NOTE: Some generated meshes DO NOT include generated texture coordinates
#define SUPPORT_MESH_GENERATION 1 #define SUPPORT_MESH_GENERATION 1
// models: Configuration values
//------------------------------------------------------------------------------------
#define MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported
#define MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Module: audio - Configuration Flags // Module: audio - Configuration Flags
@ -224,4 +223,3 @@
// utils: Configuration values // utils: Configuration values
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
#define MAX_TRACELOG_MSG_LENGTH 128 // Max length of one trace-log message #define MAX_TRACELOG_MSG_LENGTH 128 // Max length of one trace-log message
#define MAX_UWP_MESSAGES 512 // Max UWP messages to process

View File

@ -119,19 +119,14 @@
#include "config.h" // Defines module configuration flags #include "config.h" // Defines module configuration flags
#endif #endif
#include "utils.h" // TRACELOG macros #include "utils.h" // Required for: TRACELOG() macros
#if (defined(__linux__) || defined(PLATFORM_WEB)) && _POSIX_C_SOURCE < 199309L #define RLGL_IMPLEMENTATION
#undef _POSIX_C_SOURCE #include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
#define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext.
#endif
#define RAYMATH_IMPLEMENTATION // Define external out-of-line implementation #define RAYMATH_IMPLEMENTATION // Define external out-of-line implementation
#include "raymath.h" // Vector3, Quaternion and Matrix functionality #include "raymath.h" // Vector3, Quaternion and Matrix functionality
#define RLGL_IMPLEMENTATION
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
#if defined(SUPPORT_GESTURES_SYSTEM) #if defined(SUPPORT_GESTURES_SYSTEM)
#define GESTURES_IMPLEMENTATION #define GESTURES_IMPLEMENTATION
#include "gestures.h" // Gestures detection functionality #include "gestures.h" // Gestures detection functionality
@ -159,6 +154,11 @@
#include "external/sdefl.h" // Deflate (RFC 1951) compressor #include "external/sdefl.h" // Deflate (RFC 1951) compressor
#endif #endif
#if (defined(__linux__) || defined(PLATFORM_WEB)) && _POSIX_C_SOURCE < 199309L
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 199309L // Required for: CLOCK_MONOTONIC if compiled with c99 without gnu ext.
#endif
#include <stdlib.h> // Required for: srand(), rand(), atexit() #include <stdlib.h> // Required for: srand(), rand(), atexit()
#include <stdio.h> // Required for: sprintf() [Used in OpenURL()] #include <stdio.h> // Required for: sprintf() [Used in OpenURL()]
#include <string.h> // Required for: strrchr(), strcmp(), strlen() #include <string.h> // Required for: strrchr(), strcmp(), strlen()
@ -622,6 +622,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
#endif #endif
#if defined(PLATFORM_WEB) #if defined(PLATFORM_WEB)
static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData); static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData);
static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData); static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData);
static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *e, void *userData); static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *e, void *userData);
@ -794,8 +795,10 @@ void InitWindow(int width, int height, const char *title)
// NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering // NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 });
#else #else
// Set default internal texture (1px white) and rectangle to be used for shapes drawing // Set default texture and rectangle to be used for shapes drawing
SetShapesTexture(rlGetTextureDefault(), (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f }); // NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8
Texture2D texture = { rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
SetShapesTexture(texture, (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f });
#endif #endif
#if defined(PLATFORM_DESKTOP) #if defined(PLATFORM_DESKTOP)
if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0) if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0)
@ -823,6 +826,9 @@ void InitWindow(int width, int height, const char *title)
//emscripten_set_keypress_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback); //emscripten_set_keypress_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback);
//emscripten_set_keydown_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback); //emscripten_set_keydown_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback);
// Support mouse events
emscripten_set_click_callback("#canvas", NULL, 1, EmscriptenMouseCallback);
// Support touch events // Support touch events
emscripten_set_touchstart_callback("#canvas", NULL, 1, EmscriptenTouchCallback); emscripten_set_touchstart_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenTouchCallback); emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
@ -2134,13 +2140,13 @@ void EndTextureMode(void)
// Begin custom shader mode // Begin custom shader mode
void BeginShaderMode(Shader shader) void BeginShaderMode(Shader shader)
{ {
rlSetShader(shader); rlSetShader(shader.id, shader.locs);
} }
// End custom shader mode (returns to default shader) // End custom shader mode (returns to default shader)
void EndShaderMode(void) void EndShaderMode(void)
{ {
rlSetShader(rlGetShaderDefault()); rlSetShader(rlGetShaderIdDefault(), rlGetShaderLocsDefault());
} }
// Begin blending mode (alpha, additive, multiplied, subtract, custom) // Begin blending mode (alpha, additive, multiplied, subtract, custom)
@ -2290,10 +2296,10 @@ Shader LoadShader(const char *vsFileName, const char *fsFileName)
RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode) RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
{ {
Shader shader = { 0 }; Shader shader = { 0 };
shader.locs = (int *)RL_CALLOC(MAX_SHADER_LOCATIONS, sizeof(int)); shader.locs = (int *)RL_CALLOC(RL_MAX_SHADER_LOCATIONS, sizeof(int));
// NOTE: All locations must be reseted to -1 (no location) // NOTE: All locations must be reseted to -1 (no location)
for (int i = 0; i < MAX_SHADER_LOCATIONS; i++) shader.locs[i] = -1; for (int i = 0; i < RL_MAX_SHADER_LOCATIONS; i++) shader.locs[i] = -1;
shader.id = rlLoadShaderCode(vsCode, fsCode); shader.id = rlLoadShaderCode(vsCode, fsCode);
@ -2311,25 +2317,25 @@ RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
// NOTE: If any location is not found, loc point becomes -1 // NOTE: If any location is not found, loc point becomes -1
// Get handles to GLSL input attibute locations // Get handles to GLSL input attibute locations
shader.locs[SHADER_LOC_VERTEX_POSITION] = rlGetLocationAttrib(shader.id, DEFAULT_SHADER_ATTRIB_NAME_POSITION); shader.locs[SHADER_LOC_VERTEX_POSITION] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION);
shader.locs[SHADER_LOC_VERTEX_TEXCOORD01] = rlGetLocationAttrib(shader.id, DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD); shader.locs[SHADER_LOC_VERTEX_TEXCOORD01] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD);
shader.locs[SHADER_LOC_VERTEX_TEXCOORD02] = rlGetLocationAttrib(shader.id, DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2); shader.locs[SHADER_LOC_VERTEX_TEXCOORD02] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2);
shader.locs[SHADER_LOC_VERTEX_NORMAL] = rlGetLocationAttrib(shader.id, DEFAULT_SHADER_ATTRIB_NAME_NORMAL); shader.locs[SHADER_LOC_VERTEX_NORMAL] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL);
shader.locs[SHADER_LOC_VERTEX_TANGENT] = rlGetLocationAttrib(shader.id, DEFAULT_SHADER_ATTRIB_NAME_TANGENT); shader.locs[SHADER_LOC_VERTEX_TANGENT] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT);
shader.locs[SHADER_LOC_VERTEX_COLOR] = rlGetLocationAttrib(shader.id, DEFAULT_SHADER_ATTRIB_NAME_COLOR); shader.locs[SHADER_LOC_VERTEX_COLOR] = rlGetLocationAttrib(shader.id, RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR);
// Get handles to GLSL uniform locations (vertex shader) // Get handles to GLSL uniform locations (vertex shader)
shader.locs[SHADER_LOC_MATRIX_MVP] = rlGetLocationUniform(shader.id, DEFAULT_SHADER_UNIFORM_NAME_MVP); shader.locs[SHADER_LOC_MATRIX_MVP] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_MVP);
shader.locs[SHADER_LOC_MATRIX_VIEW] = rlGetLocationUniform(shader.id, DEFAULT_SHADER_UNIFORM_NAME_VIEW); shader.locs[SHADER_LOC_MATRIX_VIEW] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW);
shader.locs[SHADER_LOC_MATRIX_PROJECTION] = rlGetLocationUniform(shader.id, DEFAULT_SHADER_UNIFORM_NAME_PROJECTION); shader.locs[SHADER_LOC_MATRIX_PROJECTION] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION);
shader.locs[SHADER_LOC_MATRIX_MODEL] = rlGetLocationUniform(shader.id, DEFAULT_SHADER_UNIFORM_NAME_MODEL); shader.locs[SHADER_LOC_MATRIX_MODEL] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL);
shader.locs[SHADER_LOC_MATRIX_NORMAL] = rlGetLocationUniform(shader.id, DEFAULT_SHADER_UNIFORM_NAME_NORMAL); shader.locs[SHADER_LOC_MATRIX_NORMAL] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL);
// Get handles to GLSL uniform locations (fragment shader) // Get handles to GLSL uniform locations (fragment shader)
shader.locs[SHADER_LOC_COLOR_DIFFUSE] = rlGetLocationUniform(shader.id, DEFAULT_SHADER_UNIFORM_NAME_COLOR); shader.locs[SHADER_LOC_COLOR_DIFFUSE] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR);
shader.locs[SHADER_LOC_MAP_DIFFUSE] = rlGetLocationUniform(shader.id, DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0); // SHADER_LOC_MAP_ALBEDO shader.locs[SHADER_LOC_MAP_DIFFUSE] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0); // SHADER_LOC_MAP_ALBEDO
shader.locs[SHADER_LOC_MAP_SPECULAR] = rlGetLocationUniform(shader.id, DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1); // SHADER_LOC_MAP_METALNESS shader.locs[SHADER_LOC_MAP_SPECULAR] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1); // SHADER_LOC_MAP_METALNESS
shader.locs[SHADER_LOC_MAP_NORMAL] = rlGetLocationUniform(shader.id, DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2); shader.locs[SHADER_LOC_MAP_NORMAL] = rlGetLocationUniform(shader.id, RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2);
} }
return shader; return shader;
@ -2338,7 +2344,7 @@ RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
// Unload shader from GPU memory (VRAM) // Unload shader from GPU memory (VRAM)
void UnloadShader(Shader shader) void UnloadShader(Shader shader)
{ {
if (shader.id != rlGetShaderDefault().id) if (shader.id != rlGetShaderIdDefault())
{ {
rlUnloadShaderProgram(shader.id); rlUnloadShaderProgram(shader.id);
RL_FREE(shader.locs); RL_FREE(shader.locs);
@ -5315,6 +5321,13 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
#endif #endif
#if defined(PLATFORM_WEB) #if defined(PLATFORM_WEB)
// Register mouse input events
static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
{
// This is only for registering mouse click events with emscripten and doesn't need to do anything
return 0;
}
// Register touch input events // Register touch input events
static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData) static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
{ {

View File

@ -21,8 +21,7 @@
// coordinates (one per vertex). That's it! If you need something fancier, // coordinates (one per vertex). That's it! If you need something fancier,
// look elsewhere. // look elsewhere.
// //
// The MIT License // Distributed under the MIT License, see bottom of file.
// Copyright (c) 2015 Philip Rideout
#ifndef PAR_SHAPES_H #ifndef PAR_SHAPES_H
#define PAR_SHAPES_H #define PAR_SHAPES_H
@ -32,8 +31,7 @@ extern "C" {
#endif #endif
#include <stdint.h> #include <stdint.h>
// Ray (@raysan5): Commented to avoid conflict with raylib bool
// Ray: commented to avoid conflict with raylib bool
/* /*
#if !defined(_MSC_VER) #if !defined(_MSC_VER)
# include <stdbool.h> # include <stdbool.h>
@ -41,9 +39,9 @@ extern "C" {
# if _MSC_VER >= 1800 # if _MSC_VER >= 1800
# include <stdbool.h> # include <stdbool.h>
# else // stdbool.h missing prior to MSVC++ 12.0 (VS2013) # else // stdbool.h missing prior to MSVC++ 12.0 (VS2013)
//# define bool int # define bool int
//# define true 1 # define true 1
//# define false 0 # define false 0
# endif # endif
#endif #endif
*/ */
@ -71,6 +69,14 @@ void par_shapes_free_mesh(par_shapes_mesh*);
// both 1.0, but they can easily be changed with par_shapes_scale. // both 1.0, but they can easily be changed with par_shapes_scale.
par_shapes_mesh* par_shapes_create_cylinder(int slices, int stacks); par_shapes_mesh* par_shapes_create_cylinder(int slices, int stacks);
// Cone is similar to cylinder but the radius diminishes to zero as Z increases.
// Again, height and radius are 1.0, but can be changed with par_shapes_scale.
par_shapes_mesh* par_shapes_create_cone(int slices, int stacks);
// Create a disk of radius 1.0 with texture coordinates and normals by squashing
// a cone flat on the Z=0 plane.
par_shapes_mesh* par_shapes_create_parametric_disk(int slices, int stacks);
// Create a donut that sits on the Z=0 plane with the specified inner radius. // Create a donut that sits on the Z=0 plane with the specified inner radius.
// The outer radius can be controlled with par_shapes_scale. // The outer radius can be controlled with par_shapes_scale.
par_shapes_mesh* par_shapes_create_torus(int slices, int stacks, float radius); par_shapes_mesh* par_shapes_create_torus(int slices, int stacks, float radius);
@ -172,6 +178,17 @@ par_shapes_mesh* par_shapes_weld(par_shapes_mesh const*, float epsilon,
// Compute smooth normals by averaging adjacent facet normals. // Compute smooth normals by averaging adjacent facet normals.
void par_shapes_compute_normals(par_shapes_mesh* m); void par_shapes_compute_normals(par_shapes_mesh* m);
// Global Config ---------------------------------------------------------------
void par_shapes_set_epsilon_welded_normals(float epsilon);
void par_shapes_set_epsilon_degenerate_sphere(float epsilon);
// Advanced --------------------------------------------------------------------
void par_shapes__compute_welded_normals(par_shapes_mesh* m);
void par_shapes__connect(par_shapes_mesh* scene, par_shapes_mesh* cylinder,
int slices);
#ifndef PAR_PI #ifndef PAR_PI
#define PAR_PI (3.14159265359) #define PAR_PI (3.14159265359)
#define PAR_MIN(a, b) (a > b ? b : a) #define PAR_MIN(a, b) (a > b ? b : a)
@ -205,11 +222,15 @@ void par_shapes_compute_normals(par_shapes_mesh* m);
#include <math.h> #include <math.h>
#include <errno.h> #include <errno.h>
static float par_shapes__epsilon_welded_normals = 0.001;
static float par_shapes__epsilon_degenerate_sphere = 0.0001;
static void par_shapes__sphere(float const* uv, float* xyz, void*); static void par_shapes__sphere(float const* uv, float* xyz, void*);
static void par_shapes__hemisphere(float const* uv, float* xyz, void*); static void par_shapes__hemisphere(float const* uv, float* xyz, void*);
static void par_shapes__plane(float const* uv, float* xyz, void*); static void par_shapes__plane(float const* uv, float* xyz, void*);
static void par_shapes__klein(float const* uv, float* xyz, void*); static void par_shapes__klein(float const* uv, float* xyz, void*);
static void par_shapes__cylinder(float const* uv, float* xyz, void*); static void par_shapes__cylinder(float const* uv, float* xyz, void*);
static void par_shapes__cone(float const* uv, float* xyz, void*);
static void par_shapes__torus(float const* uv, float* xyz, void*); static void par_shapes__torus(float const* uv, float* xyz, void*);
static void par_shapes__trefoil(float const* uv, float* xyz, void*); static void par_shapes__trefoil(float const* uv, float* xyz, void*);
@ -298,11 +319,12 @@ static float par_shapes__sqrdist3(float const* a, float const* b)
return dx * dx + dy * dy + dz * dz; return dx * dx + dy * dy + dz * dz;
} }
static void par_shapes__compute_welded_normals(par_shapes_mesh* m) void par_shapes__compute_welded_normals(par_shapes_mesh* m)
{ {
const float epsilon = par_shapes__epsilon_welded_normals;
m->normals = PAR_MALLOC(float, m->npoints * 3); m->normals = PAR_MALLOC(float, m->npoints * 3);
PAR_SHAPES_T* weldmap = PAR_MALLOC(PAR_SHAPES_T, m->npoints); PAR_SHAPES_T* weldmap = PAR_MALLOC(PAR_SHAPES_T, m->npoints);
par_shapes_mesh* welded = par_shapes_weld(m, 0.01, weldmap); par_shapes_mesh* welded = par_shapes_weld(m, epsilon, weldmap);
par_shapes_compute_normals(welded); par_shapes_compute_normals(welded);
float* pdst = m->normals; float* pdst = m->normals;
for (int i = 0; i < m->npoints; i++, pdst += 3) { for (int i = 0; i < m->npoints; i++, pdst += 3) {
@ -325,6 +347,24 @@ par_shapes_mesh* par_shapes_create_cylinder(int slices, int stacks)
stacks, 0); stacks, 0);
} }
par_shapes_mesh* par_shapes_create_cone(int slices, int stacks)
{
if (slices < 3 || stacks < 1) {
return 0;
}
return par_shapes_create_parametric(par_shapes__cone, slices,
stacks, 0);
}
par_shapes_mesh* par_shapes_create_parametric_disk(int slices, int stacks)
{
par_shapes_mesh* m = par_shapes_create_cone(slices, stacks);
if (m) {
par_shapes_scale(m, 1.0f, 1.0f, 0.0f);
}
return m;
}
par_shapes_mesh* par_shapes_create_parametric_sphere(int slices, int stacks) par_shapes_mesh* par_shapes_create_parametric_sphere(int slices, int stacks)
{ {
if (slices < 3 || stacks < 3) { if (slices < 3 || stacks < 3) {
@ -332,7 +372,7 @@ par_shapes_mesh* par_shapes_create_parametric_sphere(int slices, int stacks)
} }
par_shapes_mesh* m = par_shapes_create_parametric(par_shapes__sphere, par_shapes_mesh* m = par_shapes_create_parametric(par_shapes__sphere,
slices, stacks, 0); slices, stacks, 0);
par_shapes_remove_degenerate(m, 0.0001); par_shapes_remove_degenerate(m, par_shapes__epsilon_degenerate_sphere);
return m; return m;
} }
@ -343,7 +383,7 @@ par_shapes_mesh* par_shapes_create_hemisphere(int slices, int stacks)
} }
par_shapes_mesh* m = par_shapes_create_parametric(par_shapes__hemisphere, par_shapes_mesh* m = par_shapes_create_parametric(par_shapes__hemisphere,
slices, stacks, 0); slices, stacks, 0);
par_shapes_remove_degenerate(m, 0.0001); par_shapes_remove_degenerate(m, par_shapes__epsilon_degenerate_sphere);
return m; return m;
} }
@ -579,6 +619,15 @@ static void par_shapes__cylinder(float const* uv, float* xyz, void* userdata)
xyz[2] = uv[0]; xyz[2] = uv[0];
} }
static void par_shapes__cone(float const* uv, float* xyz, void* userdata)
{
float r = 1.0f - uv[0];
float theta = uv[1] * 2 * PAR_PI;
xyz[0] = r * sinf(theta);
xyz[1] = r * cosf(theta);
xyz[2] = uv[0];
}
static void par_shapes__torus(float const* uv, float* xyz, void* userdata) static void par_shapes__torus(float const* uv, float* xyz, void* userdata)
{ {
float major = 1; float major = 1;
@ -620,6 +669,14 @@ static void par_shapes__trefoil(float const* uv, float* xyz, void* userdata)
xyz[2] = z + d * ww[2] * sin(v); xyz[2] = z + d * ww[2] * sin(v);
} }
void par_shapes_set_epsilon_welded_normals(float epsilon) {
par_shapes__epsilon_welded_normals = epsilon;
}
void par_shapes_set_epsilon_degenerate_sphere(float epsilon) {
par_shapes__epsilon_degenerate_sphere = epsilon;
}
void par_shapes_merge(par_shapes_mesh* dst, par_shapes_mesh const* src) void par_shapes_merge(par_shapes_mesh* dst, par_shapes_mesh const* src)
{ {
PAR_SHAPES_T offset = dst->npoints; PAR_SHAPES_T offset = dst->npoints;
@ -744,15 +801,15 @@ void par_shapes_rotate(par_shapes_mesh* mesh, float radians, float const* axis)
p[1] = y; p[1] = y;
p[2] = z; p[2] = z;
} }
p = mesh->normals; float* n = mesh->normals;
if (p) { if (n) {
for (int i = 0; i < mesh->npoints; i++, p += 3) { for (int i = 0; i < mesh->npoints; i++, n += 3) {
float x = col0[0] * p[0] + col1[0] * p[1] + col2[0] * p[2]; float x = col0[0] * n[0] + col1[0] * n[1] + col2[0] * n[2];
float y = col0[1] * p[0] + col1[1] * p[1] + col2[1] * p[2]; float y = col0[1] * n[0] + col1[1] * n[1] + col2[1] * n[2];
float z = col0[2] * p[0] + col1[2] * p[1] + col2[2] * p[2]; float z = col0[2] * n[0] + col1[2] * n[1] + col2[2] * n[2];
p[0] = x; n[0] = x;
p[1] = y; n[1] = y;
p[2] = z; n[2] = z;
} }
} }
} }
@ -765,6 +822,27 @@ void par_shapes_scale(par_shapes_mesh* m, float x, float y, float z)
*points++ *= y; *points++ *= y;
*points++ *= z; *points++ *= z;
} }
float* n = m->normals;
if (n && !(x == y && y == z)) {
bool x_zero = x == 0;
bool y_zero = y == 0;
bool z_zero = z == 0;
if (!x_zero && !y_zero && !z_zero) {
x = 1.0f / x;
y = 1.0f / y;
z = 1.0f / z;
} else {
x = x_zero && !y_zero && !z_zero;
y = y_zero && !x_zero && !z_zero;
z = z_zero && !x_zero && !y_zero;
}
for (int i = 0; i < m->npoints; i++, n += 3) {
n[0] *= x;
n[1] *= y;
n[2] *= z;
par_shapes__normalize3(n);
}
}
} }
void par_shapes_merge_and_free(par_shapes_mesh* dst, par_shapes_mesh* src) void par_shapes_merge_and_free(par_shapes_mesh* dst, par_shapes_mesh* src)
@ -1098,8 +1176,8 @@ static par_shapes_mesh* par_shapes__apply_turtle(par_shapes_mesh* mesh,
return m; return m;
} }
static void par_shapes__connect(par_shapes_mesh* scene, void par_shapes__connect(par_shapes_mesh* scene, par_shapes_mesh* cylinder,
par_shapes_mesh* cylinder, int slices) int slices)
{ {
int stacks = 1; int stacks = 1;
int npoints = (slices + 1) * (stacks + 1); int npoints = (slices + 1) * (stacks + 1);
@ -1118,7 +1196,8 @@ static void par_shapes__connect(par_shapes_mesh* scene,
// Create the new triangle list. // Create the new triangle list.
int ntriangles = scene->ntriangles + 2 * slices * stacks; int ntriangles = scene->ntriangles + 2 * slices * stacks;
PAR_SHAPES_T* triangles = PAR_MALLOC(PAR_SHAPES_T, ntriangles * 3); PAR_SHAPES_T* triangles = PAR_MALLOC(PAR_SHAPES_T, ntriangles * 3);
memcpy(triangles, scene->triangles, 2 * scene->ntriangles * 3); memcpy(triangles, scene->triangles,
sizeof(PAR_SHAPES_T) * scene->ntriangles * 3);
int v = scene->npoints - (slices + 1); int v = scene->npoints - (slices + 1);
PAR_SHAPES_T* face = triangles + scene->ntriangles * 3; PAR_SHAPES_T* face = triangles + scene->ntriangles * 3;
for (int stack = 0; stack < stacks; stack++) { for (int stack = 0; stack < stacks; stack++) {
@ -1154,7 +1233,7 @@ par_shapes_mesh* par_shapes_create_lsystem(char const* text, int slices,
while (cmd) { while (cmd) {
char *arg = strtok(0, " "); char *arg = strtok(0, " ");
if (!arg) { if (!arg) {
//puts("lsystem error: unexpected end of program."); puts("lsystem error: unexpected end of program.");
break; break;
} }
if (!strcmp(cmd, "rule")) { if (!strcmp(cmd, "rule")) {
@ -1208,7 +1287,6 @@ par_shapes_mesh* par_shapes_create_lsystem(char const* text, int slices,
// For testing purposes, dump out the parsed program. // For testing purposes, dump out the parsed program.
#ifdef TEST_PARSE #ifdef TEST_PARSE
/*
for (int i = 0; i < nrules; i++) { for (int i = 0; i < nrules; i++) {
par_shapes__rule rule = rules[i]; par_shapes__rule rule = rules[i];
printf("rule %s.%d\n", rule.name, rule.weight); printf("rule %s.%d\n", rule.name, rule.weight);
@ -1217,7 +1295,6 @@ par_shapes_mesh* par_shapes_create_lsystem(char const* text, int slices,
printf("\t%s %s\n", cmd.cmd, cmd.arg); printf("\t%s %s\n", cmd.cmd, cmd.arg);
} }
} }
*/
#endif #endif
// Instantiate the aggregated shape and the template shapes. // Instantiate the aggregated shape and the template shapes.
@ -1258,7 +1335,8 @@ par_shapes_mesh* par_shapes_create_lsystem(char const* text, int slices,
par_shapes__command* cmd = rule->commands + (frame->pc++); par_shapes__command* cmd = rule->commands + (frame->pc++);
#ifdef DUMP_TRACE #ifdef DUMP_TRACE
//printf("%5s %5s %5s:%d %03d\n", cmd->cmd, cmd->arg, rule->name, frame->pc - 1, stackptr); printf("%5s %5s %5s:%d %03d\n", cmd->cmd, cmd->arg, rule->name,
frame->pc - 1, stackptr);
#endif #endif
float value; float value;
@ -1620,7 +1698,7 @@ static void par_shapes__weld_points(par_shapes_mesh* mesh, int gridsize,
PAR_SHAPES_T binvalue = *(bins + binindex); PAR_SHAPES_T binvalue = *(bins + binindex);
if (binvalue > 0) { if (binvalue > 0) {
if (nbins == 8) { if (nbins == 8) {
//printf("Epsilon value is too large.\n"); printf("Epsilon value is too large.\n");
break; break;
} }
nearby[nbins++] = binindex; nearby[nbins++] = binindex;
@ -1632,8 +1710,9 @@ static void par_shapes__weld_points(par_shapes_mesh* mesh, int gridsize,
// Check for colocated points in each nearby bin. // Check for colocated points in each nearby bin.
for (int b = 0; b < nbins; b++) { for (int b = 0; b < nbins; b++) {
int binindex = nearby[b]; int binindex = nearby[b];
PAR_SHAPES_T binvalue = *(bins + binindex); PAR_SHAPES_T binvalue = bins[binindex];
PAR_SHAPES_T nindex = binvalue - 1; PAR_SHAPES_T nindex = binvalue - 1;
assert(nindex < mesh->npoints);
while (true) { while (true) {
// If this isn't "self" and it's colocated, then weld it! // If this isn't "self" and it's colocated, then weld it!
@ -1699,6 +1778,9 @@ static void par_shapes__weld_points(par_shapes_mesh* mesh, int gridsize,
PAR_SHAPES_T b = weldmap[tsrc[1]]; PAR_SHAPES_T b = weldmap[tsrc[1]];
PAR_SHAPES_T c = weldmap[tsrc[2]]; PAR_SHAPES_T c = weldmap[tsrc[2]];
if (a != b && a != c && b != c) { if (a != b && a != c && b != c) {
assert(a < mesh->npoints);
assert(b < mesh->npoints);
assert(c < mesh->npoints);
*tdst++ = a; *tdst++ = a;
*tdst++ = b; *tdst++ = b;
*tdst++ = c; *tdst++ = c;
@ -2049,3 +2131,25 @@ void par_shapes_remove_degenerate(par_shapes_mesh* mesh, float mintriarea)
#endif // PAR_SHAPES_IMPLEMENTATION #endif // PAR_SHAPES_IMPLEMENTATION
#endif // PAR_SHAPES_H #endif // PAR_SHAPES_H
// par_shapes is distributed under the MIT license:
//
// Copyright (c) 2019 Philip Rideout
//
// 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.

View File

@ -516,8 +516,8 @@ RAYGUIDEF bool GuiCheckIconPixel(int iconId, int x, int y); // Check icon pi
#endif #endif
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), vsprintf() #include <stdio.h> // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf(), vsprintf()
#include <string.h> // Required for: strlen() on GuiTextBox() #include <string.h> // Required for: strlen() [GuiTextBox()]
#include <math.h> // Required for: roundf() on GuiColorPicker() #include <math.h> // Required for: roundf() [GuiColorPicker()]
#if defined(RAYGUI_STANDALONE) #if defined(RAYGUI_STANDALONE)
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
@ -1373,7 +1373,7 @@ bool GuiDropdownBox(Rectangle bounds, const char *text, int *active, bool editMo
// NOTE 2: Returns if KEY_ENTER pressed (useful for data validation) // NOTE 2: Returns if KEY_ENTER pressed (useful for data validation)
bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode) bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
{ {
static int framesCounter = 0; // Required for blinking cursor static int framesCounter = 0; // Blinking cursor counter
GuiControlState state = guiState; GuiControlState state = guiState;
bool pressed = false; bool pressed = false;
@ -1561,7 +1561,7 @@ bool GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, i
#define VALUEBOX_MAX_CHARS 32 #define VALUEBOX_MAX_CHARS 32
#endif #endif
static int framesCounter = 0; // Required for blinking cursor static int framesCounter = 0; // Blinking cursor counter
GuiControlState state = guiState; GuiControlState state = guiState;
bool pressed = false; bool pressed = false;
@ -1678,7 +1678,7 @@ bool GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, i
// Text Box control with multiple lines // Text Box control with multiple lines
bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode) bool GuiTextBoxMulti(Rectangle bounds, char *text, int textSize, bool editMode)
{ {
static int framesCounter = 0; // Required for blinking cursor static int framesCounter = 0; // Blinking cursor counter
GuiControlState state = guiState; GuiControlState state = guiState;
bool pressed = false; bool pressed = false;
@ -3083,9 +3083,10 @@ char **GuiLoadIcons(const char *fileName, bool loadIconsName)
for (int i = 0; i < iconsCount; i++) for (int i = 0; i < iconsCount; i++)
{ {
guiIconsName[i] = (char *)RAYGUI_MALLOC(RICON_MAX_NAME_LENGTH); guiIconsName[i] = (char *)RAYGUI_MALLOC(RICON_MAX_NAME_LENGTH);
fread(guiIconsName[i], 32, 1, rgiFile); fread(guiIconsName[i], RICON_MAX_NAME_LENGTH, 1, rgiFile);
} }
} }
else fseek(rgiFile, iconsCount*RICON_MAX_NAME_LENGTH, SEEK_CUR);
// Read icons data directly over guiIcons data array // Read icons data directly over guiIcons data array
fread(guiIcons, iconsCount*(iconsSize*iconsSize/32), sizeof(unsigned int), rgiFile); fread(guiIcons, iconsCount*(iconsSize*iconsSize/32), sizeof(unsigned int), rgiFile);

View File

@ -22,7 +22,7 @@
// Icons data is defined by bit array (every bit represents one pixel) // Icons data is defined by bit array (every bit represents one pixel)
// Those arrays are stored as unsigned int data arrays, so every array // Those arrays are stored as unsigned int data arrays, so every array
// element defines 32 pixels (bits) of information // element defines 32 pixels (bits) of information
// Number of elemens depend on RICON_SIZE (by default 16x16 pixels) // Number of elemens depend on RICON_SIZE (by default 16x16 pixels)
#define RICON_DATA_ELEMENTS (RICON_SIZE*RICON_SIZE/32) #define RICON_DATA_ELEMENTS (RICON_SIZE*RICON_SIZE/32)
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -40,26 +40,18 @@
// Check if config flags have been externally provided on compilation line // Check if config flags have been externally provided on compilation line
#if !defined(EXTERNAL_CONFIG_FLAGS) #if !defined(EXTERNAL_CONFIG_FLAGS)
#include "config.h" // Defines module configuration flags #include "config.h" // Defines module configuration flags
#endif #endif
#include "utils.h" // Required for: LoadFileData(), LoadFileText(), SaveFileText() #include "utils.h" // Required for: TRACELOG(), LoadFileData(), LoadFileText(), SaveFileText()
#include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2
#include "raymath.h" // Required for: Vector3, Quaternion and Matrix functionality
#include <stdio.h> // Required for: sprintf() #include <stdio.h> // Required for: sprintf()
#include <stdlib.h> // Required for: malloc(), free() #include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for: memcmp(), strlen() #include <string.h> // Required for: memcmp(), strlen()
#include <math.h> // Required for: sinf(), cosf(), sqrtf(), fabsf() #include <math.h> // Required for: sinf(), cosf(), sqrtf(), fabsf()
#if defined(_WIN32)
#include <direct.h> // Required for: _chdir() [Used in LoadOBJ()]
#define CHDIR _chdir
#else
#include <unistd.h> // Required for: chdir() (POSIX) [Used in LoadOBJ()]
#define CHDIR chdir
#endif
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2
#if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL) #if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL)
#define TINYOBJ_MALLOC RL_MALLOC #define TINYOBJ_MALLOC RL_MALLOC
#define TINYOBJ_CALLOC RL_CALLOC #define TINYOBJ_CALLOC RL_CALLOC
@ -89,10 +81,23 @@
#include "external/par_shapes.h" // Shapes 3d parametric generation #include "external/par_shapes.h" // Shapes 3d parametric generation
#endif #endif
#if defined(_WIN32)
#include <direct.h> // Required for: _chdir() [Used in LoadOBJ()]
#define CHDIR _chdir
#else
#include <unistd.h> // Required for: chdir() (POSIX) [Used in LoadOBJ()]
#define CHDIR chdir
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// ... #ifndef MAX_MATERIAL_MAPS
#define MAX_MATERIAL_MAPS 12 // Maximum number of maps supported
#endif
#ifndef MAX_MESH_VERTEX_BUFFERS
#define MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
@ -819,6 +824,35 @@ void UnloadModelKeepMeshes(Model model)
TRACELOG(LOG_INFO, "MODEL: Unloaded model (but not meshes) from RAM and VRAM"); TRACELOG(LOG_INFO, "MODEL: Unloaded model (but not meshes) from RAM and VRAM");
} }
// Compute model bounding box limits (considers all meshes)
BoundingBox GetModelBoundingBox(Model model)
{
BoundingBox bounds = { 0 };
if (model.meshCount > 0)
{
Vector3 temp = { 0 };
bounds = GetMeshBoundingBox(model.meshes[0]);
for (int i = 1; i < model.meshCount; i++)
{
BoundingBox tempBounds = GetMeshBoundingBox(model.meshes[i]);
temp.x = (bounds.min.x < tempBounds.min.x)? bounds.min.x : tempBounds.min.x;
temp.y = (bounds.min.y < tempBounds.min.y)? bounds.min.y : tempBounds.min.y;
temp.z = (bounds.min.z < tempBounds.min.z)? bounds.min.z : tempBounds.min.z;
bounds.min = temp;
temp.x = (bounds.max.x > tempBounds.max.x)? bounds.max.x : tempBounds.max.x;
temp.y = (bounds.max.y > tempBounds.max.y)? bounds.max.y : tempBounds.max.y;
temp.z = (bounds.max.z > tempBounds.max.z)? bounds.max.z : tempBounds.max.z;
bounds.max = temp;
}
}
return bounds;
}
// Upload vertex data into a VAO (if supported) and VBO // Upload vertex data into a VAO (if supported) and VBO
void UploadMesh(Mesh *mesh, bool dynamic) void UploadMesh(Mesh *mesh, bool dynamic)
{ {
@ -1342,7 +1376,11 @@ Material *LoadMaterials(const char *fileName, int *materialCount)
// Set materials shader to default (DIFFUSE, SPECULAR, NORMAL) // Set materials shader to default (DIFFUSE, SPECULAR, NORMAL)
if (materials != NULL) if (materials != NULL)
{ {
for (unsigned int i = 0; i < count; i++) materials[i].shader = rlGetShaderDefault(); for (unsigned int i = 0; i < count; i++)
{
materials[i].shader.id = rlGetShaderIdDefault();
materials[i].shader.locs = rlGetShaderLocsDefault();
}
} }
*materialCount = count; *materialCount = count;
@ -1355,8 +1393,12 @@ Material LoadMaterialDefault(void)
Material material = { 0 }; Material material = { 0 };
material.maps = (MaterialMap *)RL_CALLOC(MAX_MATERIAL_MAPS, sizeof(MaterialMap)); material.maps = (MaterialMap *)RL_CALLOC(MAX_MATERIAL_MAPS, sizeof(MaterialMap));
material.shader = rlGetShaderDefault(); // Using rlgl default shader
material.maps[MATERIAL_MAP_DIFFUSE].texture = rlGetTextureDefault(); // White texture (1x1 pixel) material.shader.id = rlGetShaderIdDefault();
material.shader.locs = rlGetShaderLocsDefault();
// Using rlgl default texture (1x1 pixel, UNCOMPRESSED_R8G8B8A8, 1 mipmap)
material.maps[MATERIAL_MAP_DIFFUSE].texture = (Texture2D){ rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
//material.maps[MATERIAL_MAP_NORMAL].texture; // NOTE: By default, not set //material.maps[MATERIAL_MAP_NORMAL].texture; // NOTE: By default, not set
//material.maps[MATERIAL_MAP_SPECULAR].texture; // NOTE: By default, not set //material.maps[MATERIAL_MAP_SPECULAR].texture; // NOTE: By default, not set
@ -1370,12 +1412,12 @@ Material LoadMaterialDefault(void)
void UnloadMaterial(Material material) void UnloadMaterial(Material material)
{ {
// Unload material shader (avoid unloading default shader, managed by raylib) // Unload material shader (avoid unloading default shader, managed by raylib)
if (material.shader.id != rlGetShaderDefault().id) UnloadShader(material.shader); if (material.shader.id != rlGetShaderIdDefault()) UnloadShader(material.shader);
// Unload loaded texture maps (avoid unloading default texture, managed by raylib) // Unload loaded texture maps (avoid unloading default texture, managed by raylib)
for (int i = 0; i < MAX_MATERIAL_MAPS; i++) for (int i = 0; i < MAX_MATERIAL_MAPS; i++)
{ {
if (material.maps[i].texture.id != rlGetTextureDefault().id) rlUnloadTexture(material.maps[i].texture.id); if (material.maps[i].texture.id != rlGetTextureIdDefault()) rlUnloadTexture(material.maps[i].texture.id);
} }
RL_FREE(material.maps); RL_FREE(material.maps);
@ -2042,6 +2084,61 @@ Mesh GenMeshCylinder(float radius, float height, int slices)
return mesh; return mesh;
} }
// Generate cone/pyramid mesh
Mesh GenMeshCone(float radius, float height, int slices)
{
Mesh mesh = { 0 };
if (slices >= 3)
{
// Instance a cone that sits on the Z=0 plane using the given tessellation
// levels across the UV domain. Think of "slices" like a number of pizza
// slices, and "stacks" like a number of stacked rings.
// Height and radius are both 1.0, but they can easily be changed with par_shapes_scale
par_shapes_mesh *cone = par_shapes_create_cone(slices, 8);
par_shapes_scale(cone, radius, radius, height);
par_shapes_rotate(cone, -PI/2.0f, (float[]){ 1, 0, 0 });
par_shapes_rotate(cone, PI/2.0f, (float[]){ 0, 1, 0 });
// Generate an orientable disk shape (bottom cap)
par_shapes_mesh *capBottom = par_shapes_create_disk(radius, slices, (float[]){ 0, 0, 0 }, (float[]){ 0, 0, -1 });
capBottom->tcoords = PAR_MALLOC(float, 2*capBottom->npoints);
for (int i = 0; i < 2*capBottom->npoints; i++) capBottom->tcoords[i] = 0.95f;
par_shapes_rotate(capBottom, PI/2.0f, (float[]){ 1, 0, 0 });
par_shapes_merge_and_free(cone, capBottom);
mesh.vertices = (float *)RL_MALLOC(cone->ntriangles*3*3*sizeof(float));
mesh.texcoords = (float *)RL_MALLOC(cone->ntriangles*3*2*sizeof(float));
mesh.normals = (float *)RL_MALLOC(cone->ntriangles*3*3*sizeof(float));
mesh.vertexCount = cone->ntriangles*3;
mesh.triangleCount = cone->ntriangles;
for (int k = 0; k < mesh.vertexCount; k++)
{
mesh.vertices[k*3] = cone->points[cone->triangles[k]*3];
mesh.vertices[k*3 + 1] = cone->points[cone->triangles[k]*3 + 1];
mesh.vertices[k*3 + 2] = cone->points[cone->triangles[k]*3 + 2];
mesh.normals[k*3] = cone->normals[cone->triangles[k]*3];
mesh.normals[k*3 + 1] = cone->normals[cone->triangles[k]*3 + 1];
mesh.normals[k*3 + 2] = cone->normals[cone->triangles[k]*3 + 2];
mesh.texcoords[k*2] = cone->tcoords[cone->triangles[k]*2];
mesh.texcoords[k*2 + 1] = cone->tcoords[cone->triangles[k]*2 + 1];
}
par_shapes_free_mesh(cone);
// Upload vertex data to GPU (static mesh)
UploadMesh(&mesh, false);
}
else TRACELOG(LOG_WARNING, "MESH: Failed to generate mesh: cone");
return mesh;
}
// Generate torus mesh // Generate torus mesh
Mesh GenMeshTorus(float radius, float size, int radSeg, int sides) Mesh GenMeshTorus(float radius, float size, int radSeg, int sides)
{ {
@ -2652,19 +2749,15 @@ BoundingBox GetMeshBoundingBox(Mesh mesh)
// Implementation base don: https://answers.unity.com/questions/7789/calculating-tangents-vector4.html // Implementation base don: https://answers.unity.com/questions/7789/calculating-tangents-vector4.html
void GenMeshTangents(Mesh *mesh) void GenMeshTangents(Mesh *mesh)
{ {
if (mesh->tangents == NULL) mesh->tangents = (float *)RL_MALLOC(mesh->vertexCount*4*sizeof(float));
if (mesh->tangents == NULL) else
{ {
mesh->tangents = (float*)RL_MALLOC(mesh->vertexCount*4*sizeof(float));
}
else
{
RL_FREE(mesh->tangents); RL_FREE(mesh->tangents);
mesh->tangents = (float*)RL_MALLOC(mesh->vertexCount*4*sizeof(float)); mesh->tangents = (float *)RL_MALLOC(mesh->vertexCount*4*sizeof(float));
} }
Vector3* tan1 = (Vector3*)RL_MALLOC(mesh->vertexCount*sizeof(Vector3)); Vector3 *tan1 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
Vector3* tan2 = (Vector3*)RL_MALLOC(mesh->vertexCount*sizeof(Vector3)); Vector3 *tan2 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
for (int i = 0; i < mesh->vertexCount; i += 3) for (int i = 0; i < mesh->vertexCount; i += 3)
{ {
@ -2691,7 +2784,7 @@ void GenMeshTangents(Mesh *mesh)
float t2 = uv3.y - uv1.y; float t2 = uv3.y - uv1.y;
float div = s1*t2 - s2*t1; float div = s1*t2 - s2*t1;
float r = (div == 0.0f) ? 0.0f : 1.0f/div; float r = (div == 0.0f)? 0.0f : 1.0f/div;
Vector3 sdir = { (t2*x1 - t1*x2)*r, (t2*y1 - t1*y2)*r, (t2*z1 - t1*z2)*r }; Vector3 sdir = { (t2*x1 - t1*x2)*r, (t2*y1 - t1*y2)*r, (t2*z1 - t1*z2)*r };
Vector3 tdir = { (s1*x2 - s2*x1)*r, (s1*y2 - s2*y1)*r, (s1*z2 - s2*z1)*r }; Vector3 tdir = { (s1*x2 - s2*x1)*r, (s1*y2 - s2*y1)*r, (s1*z2 - s2*z1)*r };
@ -2706,53 +2799,51 @@ void GenMeshTangents(Mesh *mesh)
} }
// Compute tangents considering normals // Compute tangents considering normals
for (int i = 0; i < mesh->vertexCount; ++i) for (int i = 0; i < mesh->vertexCount; i++)
{ {
Vector3 normal = { mesh->normals[i*3 + 0], mesh->normals[i*3 + 1], mesh->normals[i*3 + 2] }; Vector3 normal = { mesh->normals[i*3 + 0], mesh->normals[i*3 + 1], mesh->normals[i*3 + 2] };
Vector3 tangent = tan1[i]; Vector3 tangent = tan1[i];
// TODO: Review, not sure if tangent computation is right, just used reference proposed maths... // TODO: Review, not sure if tangent computation is right, just used reference proposed maths...
#if defined(COMPUTE_TANGENTS_METHOD_01) #if defined(COMPUTE_TANGENTS_METHOD_01)
Vector3 tmp = Vector3Subtract(tangent, Vector3Scale(normal, Vector3DotProduct(normal, tangent))); Vector3 tmp = Vector3Subtract(tangent, Vector3Scale(normal, Vector3DotProduct(normal, tangent)));
tmp = Vector3Normalize(tmp); tmp = Vector3Normalize(tmp);
mesh->tangents[i*4 + 0] = tmp.x; mesh->tangents[i*4 + 0] = tmp.x;
mesh->tangents[i*4 + 1] = tmp.y; mesh->tangents[i*4 + 1] = tmp.y;
mesh->tangents[i*4 + 2] = tmp.z; mesh->tangents[i*4 + 2] = tmp.z;
mesh->tangents[i*4 + 3] = 1.0f; mesh->tangents[i*4 + 3] = 1.0f;
#else #else
Vector3OrthoNormalize(&normal, &tangent); Vector3OrthoNormalize(&normal, &tangent);
mesh->tangents[i*4 + 0] = tangent.x; mesh->tangents[i*4 + 0] = tangent.x;
mesh->tangents[i*4 + 1] = tangent.y; mesh->tangents[i*4 + 1] = tangent.y;
mesh->tangents[i*4 + 2] = tangent.z; mesh->tangents[i*4 + 2] = tangent.z;
mesh->tangents[i*4 + 3] = (Vector3DotProduct(Vector3CrossProduct(normal, tangent), tan2[i]) < 0.0f) ? -1.0f : 1.0f; mesh->tangents[i*4 + 3] = (Vector3DotProduct(Vector3CrossProduct(normal, tangent), tan2[i]) < 0.0f)? -1.0f : 1.0f;
#endif #endif
} }
RL_FREE(tan1); RL_FREE(tan1);
RL_FREE(tan2); RL_FREE(tan2);
if (mesh->vboId != NULL)
if (mesh->vboId != NULL) {
{ if (mesh->vboId[SHADER_LOC_VERTEX_TANGENT] != 0)
{
if (mesh->vboId[SHADER_LOC_VERTEX_TANGENT] != 0) // Upate existing vertex buffer
{ rlUpdateVertexBuffer(mesh->vboId[SHADER_LOC_VERTEX_TANGENT], mesh->tangents, mesh->vertexCount*4*sizeof(float), 0);
// Upate existing vertex buffer }
rlUpdateVertexBuffer(mesh->vboId[SHADER_LOC_VERTEX_TANGENT], mesh->tangents, mesh->vertexCount*4*sizeof(float), 0); else
} {
else // Load a new tangent attributes buffer
{ mesh->vboId[SHADER_LOC_VERTEX_TANGENT] = rlLoadVertexBuffer(mesh->tangents, mesh->vertexCount*4*sizeof(float), false);
// Load a new tangent attributes buffer }
mesh->vboId[SHADER_LOC_VERTEX_TANGENT] = rlLoadVertexBuffer(mesh->tangents, mesh->vertexCount*4*sizeof(float), false);
} rlEnableVertexArray(mesh->vaoId);
rlSetVertexAttribute(4, 4, RL_FLOAT, 0, 0, 0);
rlEnableVertexArray(mesh->vaoId); rlEnableVertexAttribute(4);
rlSetVertexAttribute(4, 4, RL_FLOAT, 0, 0, 0); rlDisableVertexArray();
rlEnableVertexAttribute(4); }
rlDisableVertexArray();
}
TRACELOG(LOG_INFO, "MESH: Tangents data computed for provided mesh"); TRACELOG(LOG_INFO, "MESH: Tangents data computed and uploaded for provided mesh");
} }
// Compute mesh binormals (aka bitangent) // Compute mesh binormals (aka bitangent)
@ -3087,11 +3178,10 @@ RayCollision GetRayCollisionBox(Ray ray, BoundingBox box)
collision.normal = Vector3Scale(collision.normal, 2.01f); collision.normal = Vector3Scale(collision.normal, 2.01f);
collision.normal = Vector3Divide(collision.normal, Vector3Subtract(box.max, box.min)); collision.normal = Vector3Divide(collision.normal, Vector3Subtract(box.max, box.min));
// The relevant elemets of the vector are now slightly larger than 1.0f (or smaller than -1.0f) // The relevant elemets of the vector are now slightly larger than 1.0f (or smaller than -1.0f)
// and the others are somewhere between -1.0 and 1.0 // and the others are somewhere between -1.0 and 1.0 casting to int is exactly our wanted normal!
// casting to int is exactly our wanted normal! collision.normal.x = (float)((int)collision.normal.x);
collision.normal.x = (int)collision.normal.x; collision.normal.y = (float)((int)collision.normal.y);
collision.normal.y = (int)collision.normal.y; collision.normal.z = (float)((int)collision.normal.z);
collision.normal.z = (int)collision.normal.z;
collision.normal = Vector3Normalize(collision.normal); collision.normal = Vector3Normalize(collision.normal);
@ -3377,10 +3467,11 @@ static Model LoadOBJ(const char *fileName)
// NOTE: Uses default shader, which only supports MATERIAL_MAP_DIFFUSE // NOTE: Uses default shader, which only supports MATERIAL_MAP_DIFFUSE
model.materials[m] = LoadMaterialDefault(); model.materials[m] = LoadMaterialDefault();
model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = rlGetTextureDefault(); // Get default texture, in case no texture is defined // Get default texture, in case no texture is defined
// NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8
model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = (Texture2D){ rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
if (materials[m].diffuse_texname != NULL) model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = LoadTexture(materials[m].diffuse_texname); //char *diffuse_texname; // map_Kd if (materials[m].diffuse_texname != NULL) model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = LoadTexture(materials[m].diffuse_texname); //char *diffuse_texname; // map_Kd
else model.materials[m].maps[MATERIAL_MAP_DIFFUSE].texture = rlGetTextureDefault();
model.materials[m].maps[MATERIAL_MAP_DIFFUSE].color = (Color){ (unsigned char)(materials[m].diffuse[0]*255.0f), (unsigned char)(materials[m].diffuse[1]*255.0f), (unsigned char)(materials[m].diffuse[2]*255.0f), 255 }; //float diffuse[3]; model.materials[m].maps[MATERIAL_MAP_DIFFUSE].color = (Color){ (unsigned char)(materials[m].diffuse[0]*255.0f), (unsigned char)(materials[m].diffuse[1]*255.0f), (unsigned char)(materials[m].diffuse[2]*255.0f), 255 }; //float diffuse[3];
model.materials[m].maps[MATERIAL_MAP_DIFFUSE].value = 0.0f; model.materials[m].maps[MATERIAL_MAP_DIFFUSE].value = 0.0f;
@ -4403,12 +4494,12 @@ static void *ReadGLTFValuesAs(cgltf_accessor* acc, cgltf_component_type type, bo
} break; } break;
case cgltf_component_type_r_32f: case cgltf_component_type_r_32f:
{ {
float* typedArray = (float*) array; float *typedArray = (float *)array;
for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (float)typedAdditionalArray[i]; for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (float)typedAdditionalArray[i];
} break; } break;
case cgltf_component_type_r_32u: case cgltf_component_type_r_32u:
{ {
unsigned int* typedArray = (unsigned int*) array; unsigned int *typedArray = (unsigned int *)array;
for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned int)typedAdditionalArray[i]; for (unsigned int i = 0; i < count*typeElements; i++) typedArray[i] = (unsigned int)typedAdditionalArray[i];
} break; } break;
default: default:
@ -4900,7 +4991,7 @@ static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCo
{ {
output->framePoses[frame] = RL_MALLOC(output->boneCount*sizeof(Transform)); output->framePoses[frame] = RL_MALLOC(output->boneCount*sizeof(Transform));
for (unsigned int i = 0; i < output->boneCount; i++) for (int i = 0; i < output->boneCount; i++)
{ {
if (data->nodes[i].has_translation) memcpy(&output->framePoses[frame][i].translation, data->nodes[i].translation, 3*sizeof(float)); if (data->nodes[i].has_translation) memcpy(&output->framePoses[frame][i].translation, data->nodes[i].translation, 3*sizeof(float));
else output->framePoses[frame][i].translation = Vector3Zero(); else output->framePoses[frame][i].translation = Vector3Zero();
@ -5093,7 +5184,7 @@ void LoadGLTFMesh(cgltf_data* data, cgltf_mesh* mesh, Model* outModel, Matrix cu
outModel->meshes[(*primitiveIndex)].vertices = ReadGLTFValuesAs(acc, cgltf_component_type_r_32f, false); outModel->meshes[(*primitiveIndex)].vertices = ReadGLTFValuesAs(acc, cgltf_component_type_r_32f, false);
// Transform using the nodes matrix attributes // Transform using the nodes matrix attributes
for (unsigned int v = 0; v < outModel->meshes[(*primitiveIndex)].vertexCount; v++) for (int v = 0; v < outModel->meshes[(*primitiveIndex)].vertexCount; v++)
{ {
Vector3 vertex = { Vector3 vertex = {
outModel->meshes[(*primitiveIndex)].vertices[(v*3 + 0)], outModel->meshes[(*primitiveIndex)].vertices[(v*3 + 0)],
@ -5119,7 +5210,7 @@ void LoadGLTFMesh(cgltf_data* data, cgltf_mesh* mesh, Model* outModel, Matrix cu
outModel->meshes[(*primitiveIndex)].normals = ReadGLTFValuesAs(acc, cgltf_component_type_r_32f, false); outModel->meshes[(*primitiveIndex)].normals = ReadGLTFValuesAs(acc, cgltf_component_type_r_32f, false);
// Transform using the nodes matrix attributes // Transform using the nodes matrix attributes
for (unsigned int v = 0; v < outModel->meshes[(*primitiveIndex)].vertexCount; v++) for (int v = 0; v < outModel->meshes[(*primitiveIndex)].vertexCount; v++)
{ {
Vector3 normal = { Vector3 normal = {
outModel->meshes[(*primitiveIndex)].normals[(v*3 + 0)], outModel->meshes[(*primitiveIndex)].normals[(v*3 + 0)],

View File

@ -70,11 +70,10 @@
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
#else #else
#include "raylib.h" // Declares module functions #include "raylib.h" // Declares module functions
// Check if config flags have been externally provided on compilation line
// Check if config flags have been externally provided on compilation line #if !defined(EXTERNAL_CONFIG_FLAGS)
#if !defined(EXTERNAL_CONFIG_FLAGS) #include "config.h" // Defines module configuration flags
#include "config.h" // Defines module configuration flags #endif
#endif
#include "utils.h" // Required for: fopen() Android mapping #include "utils.h" // Required for: fopen() Android mapping
#endif #endif
@ -173,7 +172,7 @@ typedef struct tagBITMAPINFOHEADER {
#if defined(RAUDIO_STANDALONE) #if defined(RAUDIO_STANDALONE)
#include <string.h> // Required for: strcmp() [Used in IsFileExtension()] #include <string.h> // Required for: strcmp() [Used in IsFileExtension()]
#if !defined(TRACELOG) #ifndef TRACELOG
#define TRACELOG(level, ...) (void)0 #define TRACELOG(level, ...) (void)0
#endif #endif
@ -1724,9 +1723,9 @@ void UpdateMusicStream(Music music)
case MUSIC_MODULE_XM: case MUSIC_MODULE_XM:
{ {
// NOTE: Internally we consider 2 channels generation, so samplesCount/2 // NOTE: Internally we consider 2 channels generation, so samplesCount/2
if (AUDIO_DEVICE_FORMAT == ma_format_f32) jar_xm_generate_samples((jar_xm_context_t*)music.ctxData, (float *)pcm, samplesCount/2); if (AUDIO_DEVICE_FORMAT == ma_format_f32) jar_xm_generate_samples((jar_xm_context_t *)music.ctxData, (float *)pcm, samplesCount/2);
else if (AUDIO_DEVICE_FORMAT == ma_format_s16) jar_xm_generate_samples_16bit((jar_xm_context_t*)music.ctxData, (short *)pcm, samplesCount/2); else if (AUDIO_DEVICE_FORMAT == ma_format_s16) jar_xm_generate_samples_16bit((jar_xm_context_t *)music.ctxData, (short *)pcm, samplesCount/2);
else if (AUDIO_DEVICE_FORMAT == ma_format_u8) jar_xm_generate_samples_8bit((jar_xm_context_t*)music.ctxData, (char *)pcm, samplesCount/2); else if (AUDIO_DEVICE_FORMAT == ma_format_u8) jar_xm_generate_samples_8bit((jar_xm_context_t *)music.ctxData, (char *)pcm, samplesCount/2);
} break; } break;
#endif #endif

View File

@ -22,7 +22,7 @@
* *
* NOTES: * NOTES:
* One default Font is loaded on InitWindow()->LoadFontDefault() [core, text] * One default Font is loaded on InitWindow()->LoadFontDefault() [core, text]
* One default Texture2D is loaded on rlglInit() [rlgl] (OpenGL 3.3 or ES2) * One default Texture2D is loaded on rlglInit(), 1x1 white pixel R8G8B8A8 [rlgl] (OpenGL 3.3 or ES2)
* One default Shader is loaded on rlglInit()->rlLoadShaderDefault() [rlgl] (OpenGL 3.3 or ES2) * One default Shader is loaded on rlglInit()->rlLoadShaderDefault() [rlgl] (OpenGL 3.3 or ES2)
* One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2) * One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2)
* *
@ -102,9 +102,12 @@
#ifndef PI #ifndef PI
#define PI 3.14159265358979323846f #define PI 3.14159265358979323846f
#endif #endif
#ifndef DEG2RAD
#define DEG2RAD (PI/180.0f) #define DEG2RAD (PI/180.0f)
#define RAD2DEG (180.0f/PI) #endif
#ifndef RAD2DEG
#define RAD2DEG (180.0f/PI)
#endif
// Allow custom memory allocators // Allow custom memory allocators
#ifndef RL_MALLOC #ifndef RL_MALLOC
@ -128,6 +131,16 @@
#define CLITERAL(type) (type) #define CLITERAL(type) (type)
#endif #endif
// NOTE: We set some defines with some data types declared by raylib
// Other modules (raymath, rlgl) also require some of those types, so,
// to be able to use those other modules as standalone (not depending on raylib)
// this defines are very useful for internal check and avoid type (re)definitions
#define RL_VECTOR2_TYPE
#define RL_VECTOR3_TYPE
#define RL_VECTOR4_TYPE
#define RL_QUATERNION_TYPE
#define RL_MATRIX_TYPE
// Some Basic Colors // Some Basic Colors
// NOTE: Custom raylib color palette for amazing visuals on WHITE background // NOTE: Custom raylib color palette for amazing visuals on WHITE background
#define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray #define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray
@ -174,6 +187,7 @@
#include <stdbool.h> #include <stdbool.h>
#elif !defined(__cplusplus) && !defined(bool) #elif !defined(__cplusplus) && !defined(bool)
typedef enum bool { false, true } bool; typedef enum bool { false, true } bool;
#define RL_BOOL_TYPE
#endif #endif
// Vector2, 2 components // Vector2, 2 components
@ -268,23 +282,23 @@ typedef struct NPatchInfo {
int layout; // Layout of the n-patch: 3x3, 1x3 or 3x1 int layout; // Layout of the n-patch: 3x3, 1x3 or 3x1
} NPatchInfo; } NPatchInfo;
// CharInfo, font character info // GlyphInfo, font characters glyphs info
typedef struct CharInfo { typedef struct GlyphInfo {
int value; // Character value (Unicode) int value; // Character value (Unicode)
int offsetX; // Character offset X when drawing int offsetX; // Character offset X when drawing
int offsetY; // Character offset Y when drawing int offsetY; // Character offset Y when drawing
int advanceX; // Character advance position X int advanceX; // Character advance position X
Image image; // Character image data Image image; // Character image data
} CharInfo; } GlyphInfo;
// Font, font texture and CharInfo array data // Font, font texture and GlyphInfo array data
typedef struct Font { typedef struct Font {
int baseSize; // Base size (default chars height) int baseSize; // Base size (default chars height)
int charsCount; // Number of characters int charsCount; // Number of characters
int charsPadding; // Padding around the chars int charsPadding; // Padding around the chars
Texture2D texture; // Characters texture atlas Texture2D texture; // Characters texture atlas
Rectangle *recs; // Characters rectangles in texture Rectangle *recs; // Characters rectangles in texture
CharInfo *chars; // Characters info data GlyphInfo *chars; // Characters glyphs info data
} Font; } Font;
// Camera, defines position/orientation in 3d space // Camera, defines position/orientation in 3d space
@ -334,7 +348,7 @@ typedef struct Mesh {
// Shader // Shader
typedef struct Shader { typedef struct Shader {
unsigned int id; // Shader program id unsigned int id; // Shader program id
int *locs; // Shader locations array (MAX_SHADER_LOCATIONS) int *locs; // Shader locations array (RL_MAX_SHADER_LOCATIONS)
} Shader; } Shader;
// MaterialMap // MaterialMap
@ -1063,8 +1077,8 @@ RLAPI bool IsKeyDown(int key); // Check if a key
RLAPI bool IsKeyReleased(int key); // Check if a key has been released once RLAPI bool IsKeyReleased(int key); // Check if a key has been released once
RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed RLAPI bool IsKeyUp(int key); // Check if a key is NOT being pressed
RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC) RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued RLAPI int GetKeyPressed(void); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty
RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued RLAPI int GetCharPressed(void); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty
// Input-related functions: gamepads // Input-related functions: gamepads
RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available
@ -1203,7 +1217,7 @@ RLAPI Image GenImageGradientRadial(int width, int height, float density, Color i
RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked
RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise
RLAPI Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale); // Generate image: perlin noise RLAPI Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale); // Generate image: perlin noise
RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm. Bigger tileSize means bigger cells RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm, bigger tileSize means bigger cells
// Image manipulation functions // Image manipulation functions
RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations) RLAPI Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
@ -1306,33 +1320,42 @@ RLAPI Font LoadFont(const char *fileName);
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 charsCount); // Load font from file with extended parameters
RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style) 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 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 CharInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *fontChars, int charsCount, int type); // Load font data for further use 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 CharInfo *chars, Rectangle **recs, int charsCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info 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(CharInfo *chars, int charsCount); // Unload font chars info data (RAM) RLAPI void UnloadFontData(GlyphInfo *chars, int charsCount); // Unload font chars info data (RAM)
RLAPI void UnloadFont(Font font); // Unload Font from GPU memory (VRAM) RLAPI void UnloadFont(Font font); // Unload Font from GPU memory (VRAM)
// Text drawing functions // Text drawing functions
RLAPI void DrawFPS(int posX, int posY); // Draw current FPS RLAPI void DrawFPS(int posX, int posY); // Draw current FPS
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
RLAPI void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters RLAPI void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters
RLAPI void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); // Draw text using font inside rectangle limits RLAPI void DrawTextPro(Font font, const char *text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint); // Draw text using Font and pro parameters (rotation)
RLAPI 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
RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint) RLAPI void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint)
// Text misc. functions // Text font info functions
RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
RLAPI Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font RLAPI Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing); // Measure string size for Font
RLAPI int GetGlyphIndex(Font font, int codepoint); // Get index position for a unicode character on font RLAPI int GetGlyphIndex(Font font, int codepoint); // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found
RLAPI GlyphInfo GetGlyphInfo(Font font, int codepoint); // Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found
RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found
// Text strings management functions (no utf8 strings, only byte chars) // 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 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 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)
// NOTE: Some strings allocate memory internally for returned strings, just be careful! // NOTE: Some strings allocate memory internally for returned strings, just be careful!
RLAPI int TextCopy(char *dst, const char *src); // Copy one string to another, returns bytes copied RLAPI int TextCopy(char *dst, const char *src); // Copy one string to another, returns bytes copied
RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal
RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending
RLAPI const char *TextFormat(const char *text, ...); // Text formatting with variables (sprintf style) RLAPI const char *TextFormat(const char *text, ...); // Text formatting with variables (sprintf() style)
RLAPI const char *TextSubtext(const char *text, int position, int length); // Get a piece of a text string RLAPI const char *TextSubtext(const char *text, int position, int length); // Get a piece of a text string
RLAPI char *TextReplace(char *text, const char *replace, const char *by); // Replace text string (memory must be freed!) RLAPI char *TextReplace(char *text, const char *replace, const char *by); // Replace text string (WARNING: memory must be freed!)
RLAPI char *TextInsert(const char *text, const char *insert, int position); // Insert text in a position (memory must be freed!) RLAPI char *TextInsert(const char *text, const char *insert, int position); // Insert text in a position (WARNING: memory must be freed!)
RLAPI const char *TextJoin(const char **textList, int count, const char *delimiter); // Join text strings with delimiter RLAPI const char *TextJoin(const char **textList, int count, const char *delimiter); // Join text strings with delimiter
RLAPI const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings RLAPI const char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings
RLAPI void TextAppend(char *text, const char *append, int *position); // Append text at specific position and move cursor! RLAPI void TextAppend(char *text, const char *append, int *position); // Append text at specific position and move cursor!
@ -1341,14 +1364,6 @@ RLAPI const char *TextToUpper(const char *text); // Get upp
RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string RLAPI const char *TextToLower(const char *text); // Get lower case version of provided string
RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string RLAPI const char *TextToPascal(const char *text); // Get Pascal case notation version of provided string
RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported) RLAPI int TextToInteger(const char *text); // Get integer value from text (negative values not supported)
RLAPI char *TextToUtf8(int *codepoints, int length); // Encode text codepoint into utf8 text (memory must be freed!)
// UTF8 text strings management functions
RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF8 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 characters (codepoints) in a UTF8 encoded string
RLAPI int GetCodepoint(const char *text, int *bytesProcessed); // Get next codepoint in a UTF8 encoded string, 0x3f('?') is returned on failure
RLAPI const char *CodepointToUtf8(int codepoint, int *byteLength); // Encode codepoint into utf8 text (char array length returned as parameter)
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Basic 3d Shapes Drawing Functions (Module: models) // Basic 3d Shapes Drawing Functions (Module: models)
@ -1378,19 +1393,46 @@ RLAPI void DrawGrid(int slices, float spacing);
// Model 3d Loading and Drawing Functions (Module: models) // Model 3d Loading and Drawing Functions (Module: models)
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Model loading/unloading functions // Model management functions
RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials) RLAPI Model LoadModel(const char *fileName); // Load model from files (meshes and materials)
RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material) RLAPI Model LoadModelFromMesh(Mesh mesh); // Load model from generated mesh (default material)
RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM) RLAPI void UnloadModel(Model model); // Unload model (including meshes) from memory (RAM and/or VRAM)
RLAPI void UnloadModelKeepMeshes(Model model); // Unload model (but not meshes) from memory (RAM and/or VRAM) RLAPI void UnloadModelKeepMeshes(Model model); // Unload model (but not meshes) from memory (RAM and/or VRAM)
RLAPI BoundingBox GetModelBoundingBox(Model model); // Compute model bounding box limits (considers all meshes)
// Mesh loading/unloading functions // Model drawing functions
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation
// Mesh management functions
RLAPI void UploadMesh(Mesh *mesh, bool dynamic); // Upload mesh vertex data in GPU and provide VAO/VBO ids RLAPI void UploadMesh(Mesh *mesh, bool dynamic); // Upload mesh vertex data in GPU and provide VAO/VBO ids
RLAPI void UpdateMeshBuffer(Mesh mesh, int index, void *data, int dataSize, int offset); // Update mesh vertex data in GPU for a specific buffer index RLAPI void UpdateMeshBuffer(Mesh mesh, int index, void *data, int dataSize, int offset); // Update mesh vertex data in GPU for a specific buffer index
RLAPI void UnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU
RLAPI void DrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform RLAPI void DrawMesh(Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform
RLAPI void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int instances); // Draw multiple mesh instances with material and different transforms RLAPI void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int instances); // Draw multiple mesh instances with material and different transforms
RLAPI void UnloadMesh(Mesh mesh); // Unload mesh data from CPU and GPU
RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success RLAPI bool ExportMesh(Mesh mesh, const char *fileName); // Export mesh data to file, returns true on success
RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents
RLAPI void GenMeshBinormals(Mesh *mesh); // Compute mesh binormals
// Mesh generation functions
RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh
RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions)
RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh
RLAPI Mesh GenMeshSphere(float radius, int rings, int slices); // Generate sphere mesh (standard sphere)
RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices); // Generate half-sphere mesh (no bottom cap)
RLAPI Mesh GenMeshCylinder(float radius, float height, int slices); // Generate cylinder mesh
RLAPI Mesh GenMeshCone(float radius, float height, int slices); // Generate cone/pyramid mesh
RLAPI Mesh GenMeshTorus(float radius, float size, int radSeg, int sides); // Generate torus mesh
RLAPI Mesh GenMeshKnot(float radius, float size, int radSeg, int sides); // Generate trefoil knot mesh
RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data
RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data
// Material loading/unloading functions // Material loading/unloading functions
RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file RLAPI Material *LoadMaterials(const char *fileName, int *materialCount); // Load materials from model file
@ -1406,33 +1448,6 @@ RLAPI void UnloadModelAnimation(ModelAnimation anim);
RLAPI void UnloadModelAnimations(ModelAnimation* animations, unsigned int count); // Unload animation array data RLAPI void UnloadModelAnimations(ModelAnimation* animations, unsigned int count); // Unload animation array data
RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match RLAPI bool IsModelAnimationValid(Model model, ModelAnimation anim); // Check model animation skeleton match
// Mesh generation functions
RLAPI Mesh GenMeshPoly(int sides, float radius); // Generate polygonal mesh
RLAPI Mesh GenMeshPlane(float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions)
RLAPI Mesh GenMeshCube(float width, float height, float length); // Generate cuboid mesh
RLAPI Mesh GenMeshSphere(float radius, int rings, int slices); // Generate sphere mesh (standard sphere)
RLAPI Mesh GenMeshHemiSphere(float radius, int rings, int slices); // Generate half-sphere mesh (no bottom cap)
RLAPI Mesh GenMeshCylinder(float radius, float height, int slices); // Generate cylinder mesh
RLAPI Mesh GenMeshTorus(float radius, float size, int radSeg, int sides); // Generate torus mesh
RLAPI Mesh GenMeshKnot(float radius, float size, int radSeg, int sides); // Generate trefoil knot mesh
RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size); // Generate heightmap mesh from image data
RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data
// Mesh manipulation functions
RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents
RLAPI void GenMeshBinormals(Mesh *mesh); // Compute mesh binormals
// Model drawing functions
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source
RLAPI void DrawBillboardPro(Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation
// Collision detection functions // Collision detection functions
RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres RLAPI bool CheckCollisionSpheres(Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes

View File

@ -1,6 +1,6 @@
/********************************************************************************************** /**********************************************************************************************
* *
* raymath v1.2 - Math functions to work with Vector3, Matrix and Quaternions * raymath v1.3 - Math functions to work with Vector3, Matrix and Quaternions
* *
* CONFIGURATION: * CONFIGURATION:
* *
@ -9,14 +9,10 @@
* If not defined, the library is in header only mode and can be included in other headers * If not defined, the library is in header only mode and can be included in other headers
* or source files without problems. But only ONE file should hold the implementation. * or source files without problems. But only ONE file should hold the implementation.
* *
* #define RAYMATH_HEADER_ONLY * #define RAYMATH_STATIC_INLINE
* Define static inline functions code, so #include header suffices for use. * Define static inline functions code, so #include header suffices for use.
* This may use up lots of memory. * This may use up lots of memory.
* *
* #define RAYMATH_STANDALONE
* Avoid raylib.h header inclusion in this file.
* Vector3 and Matrix data types are defined internally in raymath module.
*
* *
* LICENSE: zlib/libpng * LICENSE: zlib/libpng
* *
@ -42,15 +38,8 @@
#ifndef RAYMATH_H #ifndef RAYMATH_H
#define RAYMATH_H #define RAYMATH_H
//#define RAYMATH_STANDALONE // NOTE: To use raymath as standalone lib, just uncomment this line #if defined(RAYMATH_IMPLEMENTATION) && defined(RAYMATH_STATIC_INLINE)
//#define RAYMATH_HEADER_ONLY // NOTE: To compile functions as static inline, uncomment this line #error "Specifying both RAYMATH_IMPLEMENTATION and RAYMATH_STATIC_INLINE is contradictory"
#ifndef RAYMATH_STANDALONE
#include "raylib.h" // Required for: Vector3, Matrix structs definition
#endif
#if defined(RAYMATH_IMPLEMENTATION) && defined(RAYMATH_HEADER_ONLY)
#error "Specifying both RAYMATH_IMPLEMENTATION and RAYMATH_HEADER_ONLY is contradictory"
#endif #endif
#if defined(RAYMATH_IMPLEMENTATION) #if defined(RAYMATH_IMPLEMENTATION)
@ -61,7 +50,7 @@
#else #else
#define RMDEF extern inline // Provide external definition #define RMDEF extern inline // Provide external definition
#endif #endif
#elif defined(RAYMATH_HEADER_ONLY) #elif defined(RAYMATH_STATIC_INLINE)
#define RMDEF static inline // Functions may be inlined, no external out-of-line definition #define RMDEF static inline // Functions may be inlined, no external out-of-line definition
#else #else
#if defined(__TINYC__) #if defined(__TINYC__)
@ -100,43 +89,61 @@
// Types and Structures Definition // Types and Structures Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#if defined(RAYMATH_STANDALONE) #if !defined(RL_VECTOR2_TYPE)
// Vector2 type // Vector2 type
typedef struct Vector2 { typedef struct Vector2 {
float x; float x;
float y; float y;
} Vector2; } Vector2;
#define RL_VECTOR2_TYPE
#endif
// Vector3 type #if !defined(RL_VECTOR3_TYPE)
typedef struct Vector3 { // Vector3 type
float x; typedef struct Vector3 {
float y; float x;
float z; float y;
} Vector3; float z;
} Vector3;
#define RL_VECTOR3_TYPE
#endif
// Vector4 type #if !defined(RL_VECTOR4_TYPE)
typedef struct Vector4 { // Vector4 type
float x; typedef struct Vector4 {
float y; float x;
float z; float y;
float w; float z;
} Vector4; float w;
} Vector4;
#define RL_VECTOR4_TYPE
#endif
// Quaternion type #if !defined(RL_QUATERNION_TYPE)
typedef Vector4 Quaternion; // Quaternion type
typedef Vector4 Quaternion;
#define RL_QUATERNION_TYPE
#endif
// Matrix type (OpenGL style 4x4 - right handed, column major) #if !defined(RL_MATRIX_TYPE)
typedef struct Matrix { // Matrix type (OpenGL style 4x4 - right handed, column major)
float m0, m4, m8, m12; typedef struct Matrix {
float m1, m5, m9, m13; float m0, m4, m8, m12; // Matrix first row (4 components)
float m2, m6, m10, m14; float m1, m5, m9, m13; // Matrix second row (4 components)
float m3, m7, m11, m15; float m2, m6, m10, m14; // Matrix third row (4 components)
} Matrix; float m3, m7, m11, m15; // Matrix fourth row (4 components)
} Matrix;
#define RL_MATRIX_TYPE
#endif #endif
// NOTE: Helper types to be used instead of array return types for *ToFloat functions // NOTE: Helper types to be used instead of array return types for *ToFloat functions
typedef struct float3 { float v[3]; } float3; typedef struct float3 {
typedef struct float16 { float v[16]; } float16; float v[3];
} float3;
typedef struct float16 {
float v[16];
} float16;
#include <math.h> // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), fminf(), fmaxf(), fabs() #include <math.h> // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), fminf(), fmaxf(), fabs()
@ -282,7 +289,11 @@ RMDEF Vector2 Vector2Divide(Vector2 v1, Vector2 v2)
// Normalize provided vector // Normalize provided vector
RMDEF Vector2 Vector2Normalize(Vector2 v) RMDEF Vector2 Vector2Normalize(Vector2 v)
{ {
Vector2 result = Vector2Scale(v, 1/Vector2Length(v)); float length = Vector2Length(v);
if (length <= 0)
return v;
Vector2 result = Vector2Scale(v, 1/length);
return result; return result;
} }
@ -479,14 +490,14 @@ RMDEF Vector3 Vector3Normalize(Vector3 v)
{ {
Vector3 result = v; Vector3 result = v;
float length, ilength; float length, inverseLength;
length = Vector3Length(v); length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
if (length == 0.0f) length = 1.0f; if (length == 0.0f) length = 1.0f;
ilength = 1.0f/length; inverseLength = 1.0f/length;
result.x *= ilength; result.x *= inverseLength;
result.y *= ilength; result.y *= inverseLength;
result.z *= ilength; result.z *= inverseLength;
return result; return result;
} }
@ -1420,22 +1431,24 @@ RMDEF Matrix QuaternionToMatrix(Quaternion q)
RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle) RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
{ {
Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f }; Quaternion result = { 0.0f, 0.0f, 0.0f, 1.0f };
float axisLength = sqrtf(axis.x*axis.x + axis.y*axis.y + axis.z*axis.z);
if (axisLength != 0.0f)
{
angle *= 0.5f;
if (Vector3Length(axis) != 0.0f) axis = Vector3Normalize(axis);
angle *= 0.5f; float sinres = sinf(angle);
float cosres = cosf(angle);
axis = Vector3Normalize(axis); result.x = axis.x*sinres;
result.y = axis.y*sinres;
result.z = axis.z*sinres;
result.w = cosres;
float sinres = sinf(angle); result = QuaternionNormalize(result);
float cosres = cosf(angle); }
result.x = axis.x*sinres;
result.y = axis.y*sinres;
result.z = axis.z*sinres;
result.w = cosres;
result = QuaternionNormalize(result);
return result; return result;
} }

1546
src/rlgl.h

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@
#include "config.h" // Defines module configuration flags #include "config.h" // Defines module configuration flags
#endif #endif
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 #include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2
#include <math.h> // Required for: sinf(), asinf(), cosf(), acosf(), sqrtf(), fabsf() #include <math.h> // Required for: sinf(), asinf(), cosf(), acosf(), sqrtf(), fabsf()

View File

@ -53,14 +53,15 @@
#include "config.h" // Defines module configuration flags #include "config.h" // Defines module configuration flags
#endif #endif
#include "utils.h" // Required for: LoadFileText()
#include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 -> Only DrawTextPro()
#include <stdlib.h> // Required for: malloc(), free() #include <stdlib.h> // Required for: malloc(), free()
#include <stdio.h> // Required for: vsprintf() #include <stdio.h> // Required for: vsprintf()
#include <string.h> // Required for: strcmp(), strstr(), strcpy(), strncpy() [Used in TextReplace()], sscanf() [Used in LoadBMFont()] #include <string.h> // Required for: strcmp(), strstr(), strcpy(), strncpy() [Used in TextReplace()], sscanf() [Used in LoadBMFont()]
#include <stdarg.h> // Required for: va_list, va_start(), vsprintf(), va_end() [Used in TextFormat()] #include <stdarg.h> // Required for: va_list, va_start(), vsprintf(), va_end() [Used in TextFormat()]
#include <ctype.h> // Requried for: toupper(), tolower() [Used in TextToUpper(), TextToLower()] #include <ctype.h> // Requried for: toupper(), tolower() [Used in TextToUpper(), TextToLower()]
#include "utils.h" // Required for: LoadFileText()
#if defined(SUPPORT_FILEFORMAT_TTF) #if defined(SUPPORT_FILEFORMAT_TTF)
#define STB_RECT_PACK_IMPLEMENTATION #define STB_RECT_PACK_IMPLEMENTATION
#include "external/stb_rect_pack.h" // Required for: ttf font rectangles packaging #include "external/stb_rect_pack.h" // Required for: ttf font rectangles packaging
@ -125,7 +126,7 @@ extern void LoadFontDefault(void)
{ {
#define BIT_CHECK(a,b) ((a) & (1u << (b))) #define BIT_CHECK(a,b) ((a) & (1u << (b)))
// NOTE: Using UTF8 encoding table for Unicode U+0000..U+00FF Basic Latin + Latin-1 Supplement // 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 // Ref: http://www.utf8-chartable.de/unicode-utf8-table.pl
defaultFont.charsCount = 224; // Number of chars included in our default font defaultFont.charsCount = 224; // Number of chars included in our default font
@ -224,7 +225,7 @@ extern void LoadFontDefault(void)
// Allocate space for our characters info data // Allocate space for our characters info data
// NOTE: This memory should be freed at end! --> CloseWindow() // NOTE: This memory should be freed at end! --> CloseWindow()
defaultFont.chars = (CharInfo *)RL_MALLOC(defaultFont.charsCount*sizeof(CharInfo)); defaultFont.chars = (GlyphInfo *)RL_MALLOC(defaultFont.charsCount*sizeof(GlyphInfo));
defaultFont.recs = (Rectangle *)RL_MALLOC(defaultFont.charsCount*sizeof(Rectangle)); defaultFont.recs = (Rectangle *)RL_MALLOC(defaultFont.charsCount*sizeof(Rectangle));
int currentLine = 0; int currentLine = 0;
@ -266,7 +267,7 @@ extern void LoadFontDefault(void)
defaultFont.baseSize = (int)defaultFont.recs[0].height; defaultFont.baseSize = (int)defaultFont.recs[0].height;
TRACELOG(LOG_INFO, "FONT: Default font loaded successfully"); TRACELOG(LOG_INFO, "FONT: [ID %i] Default font texture loaded successfully", defaultFont.texture.id);
} }
// Unload raylib default font // Unload raylib default font
@ -453,7 +454,7 @@ Font LoadFontFromImage(Image image, Color key, int firstChar)
// We got tempCharValues and tempCharsRecs populated with chars data // We got tempCharValues and tempCharsRecs populated with chars data
// Now we move temp data to sized charValues and charRecs arrays // Now we move temp data to sized charValues and charRecs arrays
font.chars = (CharInfo *)RL_MALLOC(font.charsCount*sizeof(CharInfo)); font.chars = (GlyphInfo *)RL_MALLOC(font.charsCount*sizeof(GlyphInfo));
font.recs = (Rectangle *)RL_MALLOC(font.charsCount*sizeof(Rectangle)); font.recs = (Rectangle *)RL_MALLOC(font.charsCount*sizeof(Rectangle));
for (int i = 0; i < font.charsCount; i++) for (int i = 0; i < font.charsCount; i++)
@ -523,7 +524,7 @@ Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int
// Load font data for further use // Load font data for further use
// NOTE: Requires TTF font memory data and can generate SDF data // NOTE: Requires TTF font memory data and can generate SDF data
CharInfo *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 charsCount, int type)
{ {
// NOTE: Using some SDF generation default values, // NOTE: Using some SDF generation default values,
// trades off precision with ability to handle *smaller* sizes // trades off precision with ability to handle *smaller* sizes
@ -540,7 +541,7 @@ CharInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize
#define FONT_BITMAP_ALPHA_THRESHOLD 80 // Bitmap (B&W) font generation alpha threshold #define FONT_BITMAP_ALPHA_THRESHOLD 80 // Bitmap (B&W) font generation alpha threshold
#endif #endif
CharInfo *chars = NULL; GlyphInfo *chars = NULL;
#if defined(SUPPORT_FILEFORMAT_TTF) #if defined(SUPPORT_FILEFORMAT_TTF)
// Load font data (including pixel data) from TTF memory file // Load font data (including pixel data) from TTF memory file
@ -573,7 +574,7 @@ CharInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize
genFontChars = true; genFontChars = true;
} }
chars = (CharInfo *)RL_MALLOC(charsCount*sizeof(CharInfo)); chars = (GlyphInfo *)RL_MALLOC(charsCount*sizeof(GlyphInfo));
// NOTE: Using simple packaging, one char after another // NOTE: Using simple packaging, one char after another
for (int i = 0; i < charsCount; i++) for (int i = 0; i < charsCount; i++)
@ -649,7 +650,7 @@ CharInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize
// Generate image font atlas using chars info // Generate image font atlas using chars info
// NOTE: Packing method: 0-Default, 1-Skyline // NOTE: Packing method: 0-Default, 1-Skyline
#if defined(SUPPORT_FILEFORMAT_TTF) #if defined(SUPPORT_FILEFORMAT_TTF)
Image GenImageFontAtlas(const CharInfo *chars, Rectangle **charRecs, int charsCount, int fontSize, int padding, int packMethod) Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int charsCount, int fontSize, int padding, int packMethod)
{ {
Image atlas = { 0 }; Image atlas = { 0 };
@ -792,7 +793,7 @@ Image GenImageFontAtlas(const CharInfo *chars, Rectangle **charRecs, int charsCo
#endif #endif
// Unload font chars info data (RAM) // Unload font chars info data (RAM)
void UnloadFontData(CharInfo *chars, int charsCount) void UnloadFontData(GlyphInfo *chars, int charsCount)
{ {
for (int i = 0; i < charsCount; i++) UnloadImage(chars[i].image); for (int i = 0; i < charsCount; i++) UnloadImage(chars[i].image);
@ -890,140 +891,18 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f
} }
} }
// Draw text using font inside rectangle limits // Draw text using Font and pro parameters (rotation)
void DrawTextRec(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint) void DrawTextPro(Font font, const char *text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint)
{ {
DrawTextRecEx(font, text, rec, fontSize, spacing, wordWrap, tint, 0, 0, WHITE, WHITE); rlPushMatrix();
}
// Draw text using font inside rectangle limits with support for text selection rlTranslatef(position.x, position.y, 0.0f);
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) rlRotatef(rotation, 0.0f, 0.0f, 1.0f);
{ rlTranslatef(-origin.x, -origin.y, 0.0f);
int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop
DrawTextEx(font, text, (Vector2){ 0.0f, 0.0f }, fontSize, spacing, tint);
float textOffsetY = 0; // Offset between lines (on line break '\n')
float textOffsetX = 0.0f; // Offset X to next character to draw rlPopMatrix();
float scaleFactor = fontSize/(float)font.baseSize; // Character quad scaling factor
// Word/character wrapping mechanism variables
enum { MEASURE_STATE = 0, DRAW_STATE = 1 };
int state = wordWrap? MEASURE_STATE : DRAW_STATE;
int startLine = -1; // Index where to begin drawing (where a line begins)
int endLine = -1; // Index where to stop drawing (where a line ends)
int lastk = -1; // Holds last value of the character position
for (int i = 0, k = 0; i < length; i++, k++)
{
// Get next codepoint from byte string and glyph index in font
int codepointByteCount = 0;
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
int index = GetGlyphIndex(font, codepoint);
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
// but we need to draw all of the bad bytes using the '?' symbol moving one byte
if (codepoint == 0x3f) codepointByteCount = 1;
i += (codepointByteCount - 1);
float glyphWidth = 0;
if (codepoint != '\n')
{
glyphWidth = (font.chars[index].advanceX == 0) ? font.recs[index].width*scaleFactor : font.chars[index].advanceX*scaleFactor;
if (i + 1 < length) glyphWidth = glyphWidth + spacing;
}
// NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside of the rec container
// We store this info in startLine and endLine, then we change states, draw the text between those two variables
// and change states again and again recursively until the end of the text (or until we get outside of the container).
// When wordWrap is OFF we don't need the measure state so we go to the drawing state immediately
// and begin drawing on the next line before we can get outside the container.
if (state == MEASURE_STATE)
{
// TODO: There are multiple types of spaces in UNICODE, maybe it's a good idea to add support for more
// Ref: http://jkorpela.fi/chars/spaces.html
if ((codepoint == ' ') || (codepoint == '\t') || (codepoint == '\n')) endLine = i;
if ((textOffsetX + glyphWidth) > rec.width)
{
endLine = (endLine < 1)? i : endLine;
if (i == endLine) endLine -= codepointByteCount;
if ((startLine + codepointByteCount) == endLine) endLine = (i - codepointByteCount);
state = !state;
}
else if ((i + 1) == length)
{
endLine = i;
state = !state;
}
else if (codepoint == '\n') state = !state;
if (state == DRAW_STATE)
{
textOffsetX = 0;
i = startLine;
glyphWidth = 0;
// Save character position when we switch states
int tmp = lastk;
lastk = k - 1;
k = tmp;
}
}
else
{
if (codepoint == '\n')
{
if (!wordWrap)
{
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
textOffsetX = 0;
}
}
else
{
if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width))
{
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
textOffsetX = 0;
}
// When text overflows rectangle height limit, just stop drawing
if ((textOffsetY + font.baseSize*scaleFactor) > rec.height) break;
// Draw selection background
bool isGlyphSelected = false;
if ((selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength)))
{
DrawRectangleRec((Rectangle){ rec.x + textOffsetX - 1, rec.y + textOffsetY, glyphWidth, (float)font.baseSize*scaleFactor }, selectBackTint);
isGlyphSelected = true;
}
// Draw current character glyph
if ((codepoint != ' ') && (codepoint != '\t'))
{
DrawTextCodepoint(font, codepoint, (Vector2){ rec.x + textOffsetX, rec.y + textOffsetY }, fontSize, isGlyphSelected? selectTint : tint);
}
}
if (wordWrap && (i == endLine))
{
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
textOffsetX = 0;
startLine = endLine;
endLine = -1;
glyphWidth = 0;
selectStart += lastk - k;
k = lastk;
state = !state;
}
}
textOffsetX += glyphWidth;
}
} }
// Draw one character (codepoint) // Draw one character (codepoint)
@ -1123,6 +1002,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
} }
// Get index position for a unicode character on font // Get index position for a unicode character on font
// NOTE: If codepoint is not found in the font it fallbacks to '?'
int GetGlyphIndex(Font font, int codepoint) int GetGlyphIndex(Font font, int codepoint)
{ {
#ifndef GLYPH_NOTFOUND_CHAR_FALLBACK #ifndef GLYPH_NOTFOUND_CHAR_FALLBACK
@ -1149,6 +1029,28 @@ int GetGlyphIndex(Font font, int codepoint)
#endif #endif
} }
// Get glyph font info data for a codepoint (unicode character)
// NOTE: If codepoint is not found in the font it fallbacks to '?'
GlyphInfo GetGlyphInfo(Font font, int codepoint)
{
GlyphInfo info = { 0 };
info = font.chars[GetGlyphIndex(font, codepoint)];
return info;
}
// Get glyph rectangle in font atlas for a codepoint (unicode character)
// NOTE: If codepoint is not found in the font it fallbacks to '?'
Rectangle GetGlyphAtlasRec(Font font, int codepoint)
{
Rectangle rec = { 0 };
rec = font.recs[GetGlyphIndex(font, codepoint)];
return rec;
}
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Text strings management functions // Text strings management functions
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -1446,7 +1348,7 @@ const char *TextToUpper(const char *text)
buffer[i] = (char)toupper(text[i]); buffer[i] = (char)toupper(text[i]);
//if ((text[i] >= 'a') && (text[i] <= 'z')) buffer[i] = text[i] - 32; //if ((text[i] >= 'a') && (text[i] <= 'z')) buffer[i] = text[i] - 32;
// TODO: Support Utf8 diacritics! // TODO: Support UTF-8 diacritics!
//if ((text[i] >= 'à') && (text[i] <= 'ý')) buffer[i] = text[i] - 32; //if ((text[i] >= 'à') && (text[i] <= 'ý')) buffer[i] = text[i] - 32;
} }
else { buffer[i] = '\0'; break; } else { buffer[i] = '\0'; break; }
@ -1499,10 +1401,10 @@ const char *TextToPascal(const char *text)
return buffer; return buffer;
} }
// Encode text codepoint into utf8 text // Encode text codepoint into UTF-8 text
// REQUIRES: memcpy() // REQUIRES: memcpy()
// WARNING: Allocated memory should be manually freed // WARNING: Allocated memory should be manually freed
char *TextToUtf8(int *codepoints, int length) char *TextCodepointsToUTF8(int *codepoints, int length)
{ {
// We allocate enough memory fo fit all possible codepoints // We allocate enough memory fo fit all possible codepoints
// NOTE: 5 bytes for every codepoint should be enough // NOTE: 5 bytes for every codepoint should be enough
@ -1512,7 +1414,7 @@ char *TextToUtf8(int *codepoints, int length)
for (int i = 0, bytes = 0; i < length; i++) for (int i = 0, bytes = 0; i < length; i++)
{ {
utf8 = CodepointToUtf8(codepoints[i], &bytes); utf8 = CodepointToUTF8(codepoints[i], &bytes);
memcpy(text + size, utf8, bytes); memcpy(text + size, utf8, bytes);
size += bytes; size += bytes;
} }
@ -1526,7 +1428,8 @@ char *TextToUtf8(int *codepoints, int length)
} }
// Encode codepoint into utf8 text (char array length returned as parameter) // Encode codepoint into utf8 text (char array length returned as parameter)
RLAPI const char *CodepointToUtf8(int codepoint, int *byteLength) // NOTE: It uses a static array to store UTF-8 bytes
RLAPI const char *CodepointToUTF8(int codepoint, int *byteLength)
{ {
static char utf8[6] = { 0 }; static char utf8[6] = { 0 };
int length = 0; int length = 0;
@ -1563,7 +1466,7 @@ RLAPI const char *CodepointToUtf8(int codepoint, int *byteLength)
return utf8; return utf8;
} }
// Load all codepoints from a UTF8 text string, codepoints count returned by parameter // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
int *LoadCodepoints(const char *text, int *count) int *LoadCodepoints(const char *text, int *count)
{ {
int textLength = TextLength(text); int textLength = TextLength(text);
@ -1595,8 +1498,8 @@ void UnloadCodepoints(int *codepoints)
RL_FREE(codepoints); RL_FREE(codepoints);
} }
// Get total number of characters(codepoints) in a UTF8 encoded text, until '\0' is found // Get total number of characters(codepoints) in a UTF-8 encoded text, until '\0' is found
// NOTE: If an invalid UTF8 sequence is encountered a '?'(0x3f) codepoint is counted instead // NOTE: If an invalid UTF-8 sequence is encountered a '?'(0x3f) codepoint is counted instead
int GetCodepointsCount(const char *text) int GetCodepointsCount(const char *text)
{ {
unsigned int len = 0; unsigned int len = 0;
@ -1617,8 +1520,8 @@ int GetCodepointsCount(const char *text)
} }
#endif // SUPPORT_TEXT_MANIPULATION #endif // SUPPORT_TEXT_MANIPULATION
// Get next codepoint in a UTF8 encoded text, scanning until '\0' is found // Get next codepoint in a UTF-8 encoded text, scanning until '\0' is found
// When a invalid UTF8 byte is encountered we exit as soon as possible and a '?'(0x3f) codepoint is returned // When a invalid UTF-8 byte is encountered we exit as soon as possible and a '?'(0x3f) codepoint is returned
// Total number of bytes processed are returned as a parameter // Total number of bytes processed are returned as a parameter
// NOTE: the standard says U+FFFD should be returned in case of errors // NOTE: the standard says U+FFFD should be returned in case of errors
// but that character is not supported by the default font in raylib // but that character is not supported by the default font in raylib
@ -1626,7 +1529,7 @@ int GetCodepointsCount(const char *text)
int GetCodepoint(const char *text, int *bytesProcessed) int GetCodepoint(const char *text, int *bytesProcessed)
{ {
/* /*
UTF8 specs from https://www.ietf.org/rfc/rfc3629.txt UTF-8 specs from https://www.ietf.org/rfc/rfc3629.txt
Char. number range | UTF-8 octet sequence Char. number range | UTF-8 octet sequence
(hexadecimal) | (binary) (hexadecimal) | (binary)
@ -1845,7 +1748,7 @@ static Font LoadBMFont(const char *fileName)
font.baseSize = fontSize; font.baseSize = fontSize;
font.charsCount = charsCount; font.charsCount = charsCount;
font.charsPadding = 0; font.charsPadding = 0;
font.chars = (CharInfo *)RL_MALLOC(charsCount*sizeof(CharInfo)); font.chars = (GlyphInfo *)RL_MALLOC(charsCount*sizeof(GlyphInfo));
font.recs = (Rectangle *)RL_MALLOC(charsCount*sizeof(Rectangle)); font.recs = (Rectangle *)RL_MALLOC(charsCount*sizeof(Rectangle));
int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX; int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX;

View File

@ -64,17 +64,14 @@
#include "config.h" // Defines module configuration flags #include "config.h" // Defines module configuration flags
#endif #endif
#include "utils.h" // Required for: TRACELOG() and fopen() Android mapping
#include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2
#include <stdlib.h> // Required for: malloc(), free() #include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for: strlen() [Used in ImageTextEx()] #include <string.h> // Required for: strlen() [Used in ImageTextEx()]
#include <math.h> // Required for: fabsf() #include <math.h> // Required for: fabsf()
#include <stdio.h> // Required for: sprintf() [Used in ExportImageAsCode()] #include <stdio.h> // Required for: sprintf() [Used in ExportImageAsCode()]
#include "utils.h" // Required for: fopen() Android mapping
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2
// Required for: rlLoadTexture() rlUnloadTexture(),
// rlGenerateMipmaps(), some funcs for DrawTexturePro()
// Support only desired texture formats on stb_image // Support only desired texture formats on stb_image
#if !defined(SUPPORT_FILEFORMAT_BMP) #if !defined(SUPPORT_FILEFORMAT_BMP)
#define STBI_NO_BMP #define STBI_NO_BMP
@ -331,12 +328,15 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
int comp = 0; int comp = 0;
image.data = stbi_load_from_memory(fileData, dataSize, &image.width, &image.height, &comp, 0); image.data = stbi_load_from_memory(fileData, dataSize, &image.width, &image.height, &comp, 0);
image.mipmaps = 1; if (image.data != NULL)
{
image.mipmaps = 1;
if (comp == 1) image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; if (comp == 1) image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
else if (comp == 2) image.format = PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA; else if (comp == 2) image.format = PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA;
else if (comp == 3) image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8; else if (comp == 3) image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8;
else if (comp == 4) image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; else if (comp == 4) image.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
}
} }
#endif #endif
} }
@ -380,8 +380,9 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
#endif #endif
else TRACELOG(LOG_WARNING, "IMAGE: Data format not supported"); else TRACELOG(LOG_WARNING, "IMAGE: Data format not supported");
TRACELOG(LOG_INFO, "IMAGE: Data loaded successfully (%ix%i | %s | %i mipmaps)", image.width, image.height, rlGetPixelFormatName(image.format), image.mipmaps); if (image.data != NULL) TRACELOG(LOG_INFO, "IMAGE: Data loaded successfully (%ix%i | %s | %i mipmaps)", image.width, image.height, rlGetPixelFormatName(image.format), image.mipmaps);
else TRACELOG(LOG_WARNING, "IMAGE: Failed to load image data");
return image; return image;
} }
@ -393,7 +394,7 @@ Image LoadImageFromTexture(Texture2D texture)
if (texture.format < PIXELFORMAT_COMPRESSED_DXT1_RGB) if (texture.format < PIXELFORMAT_COMPRESSED_DXT1_RGB)
{ {
image.data = rlReadTexturePixels(texture); image.data = rlReadTexturePixels(texture.id, texture.width, texture.height, texture.format);
if (image.data != NULL) if (image.data != NULL)
{ {
@ -2344,7 +2345,7 @@ void ImageDrawPixel(Image *dst, int x, int y, Color color)
unsigned char r = (unsigned char)(round(coln.x*31.0f)); unsigned char r = (unsigned char)(round(coln.x*31.0f));
unsigned char g = (unsigned char)(round(coln.y*31.0f)); unsigned char g = (unsigned char)(round(coln.y*31.0f));
unsigned char b = (unsigned char)(round(coln.z*31.0f)); unsigned char b = (unsigned char)(round(coln.z*31.0f));
unsigned char a = (coln.w > ((float)PIXELFORMAT_UNCOMPRESSED_R5G5B5A1_ALPHA_THRESHOLD/255.0f))? 1 : 0;; unsigned char a = (coln.w > ((float)PIXELFORMAT_UNCOMPRESSED_R5G5B5A1_ALPHA_THRESHOLD/255.0f))? 1 : 0;
((unsigned short *)dst->data)[y*dst->width + x] = (unsigned short)r << 11 | (unsigned short)g << 6 | (unsigned short)b << 1 | (unsigned short)a; ((unsigned short *)dst->data)[y*dst->width + x] = (unsigned short)r << 11 | (unsigned short)g << 6 | (unsigned short)b << 1 | (unsigned short)a;
@ -2418,19 +2419,91 @@ void ImageDrawPixelV(Image *dst, Vector2 position, Color color)
// Draw line within an image // Draw line within an image
void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color) void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color)
{ {
int m = 2*(endPosY - startPosY); // Using Bresenham's algorithm as described in
int slopeError = m - (endPosX - startPosX); // Drawing Lines with Pixels - Joshua Scott - March 2012
// https://classic.csunplugged.org/wp-content/uploads/2014/12/Lines.pdf
for (int x = startPosX, y = startPosY; x <= endPosX; x++)
int changeInX = (endPosX - startPosX);
int absChangeInX = (changeInX < 0)? -changeInX : changeInX;
int changeInY = (endPosY - startPosY);
int absChangeInY = (changeInY < 0)? -changeInY : changeInY;
int startU, startV, endU, stepV; // Substitutions, either U = X, V = Y or vice versa. See loop at end of function
//int endV; // Not needed but left for better understanding, check code below
int A, B, P; // See linked paper above, explained down in the main loop
int reversedXY = (absChangeInY < absChangeInX);
if (reversedXY)
{ {
ImageDrawPixel(dst, x, y, color); A = 2*absChangeInY;
slopeError += m; B = A - 2*absChangeInX;
P = A - absChangeInX;
if (slopeError >= 0) if (changeInX > 0)
{ {
y++; startU = startPosX;
slopeError -= 2*(endPosX - startPosX); startV = startPosY;
endU = endPosX;
//endV = endPosY;
} }
else
{
startU = endPosX;
startV = endPosY;
endU = startPosX;
//endV = startPosY;
// Since start and end are reversed
changeInX = -changeInX;
changeInY = -changeInY;
}
stepV = (changeInY < 0)? -1 : 1;
ImageDrawPixel(dst, startU, startV, color); // At this point they are correctly ordered...
}
else
{
A = 2*absChangeInX;
B = A - 2*absChangeInY;
P = A - absChangeInY;
if (changeInY > 0)
{
startU = startPosY;
startV = startPosX;
endU = endPosY;
//endV = endPosX;
}
else
{
startU = endPosY;
startV = endPosX;
endU = startPosY;
//endV = startPosX;
// Since start and end are reversed
changeInX = -changeInX;
changeInY = -changeInY;
}
stepV = (changeInX < 0)? -1 : 1;
ImageDrawPixel(dst, startV, startU, color); // ... but need to be reversed here. Repeated in the main loop below
}
// We already drew the start point. If we started at startU + 0, the line would be crooked and too short
for (int u = startU + 1, v = startV; u <= endU; u++)
{
if (P >= 0)
{
v += stepV; // Adjusts whenever we stray too far from the direct line. Details in the linked paper above
P += B; // Remembers that we corrected our path
}
else P += A; // Remembers how far we are from the direct line
if (reversedXY) ImageDrawPixel(dst, u, v, color);
else ImageDrawPixel(dst, v, u, color);
} }
} }
@ -2858,7 +2931,7 @@ void GenTextureMipmaps(Texture2D *texture)
{ {
// NOTE: NPOT textures support check inside function // NOTE: NPOT textures support check inside function
// On WebGL (OpenGL ES 2.0) NPOT textures support is limited // On WebGL (OpenGL ES 2.0) NPOT textures support is limited
rlGenerateMipmaps(texture); rlGenTextureMipmaps(texture->id, texture->width, texture->height, texture->format, &texture->mipmaps);
} }
// Set texture scaling filter mode // Set texture scaling filter mode
@ -3734,7 +3807,7 @@ void SetPixelColor(void *dstPtr, Color color, int format)
unsigned char r = (unsigned char)(round(coln.x*31.0f)); unsigned char r = (unsigned char)(round(coln.x*31.0f));
unsigned char g = (unsigned char)(round(coln.y*31.0f)); unsigned char g = (unsigned char)(round(coln.y*31.0f));
unsigned char b = (unsigned char)(round(coln.z*31.0f)); unsigned char b = (unsigned char)(round(coln.z*31.0f));
unsigned char a = (coln.w > ((float)PIXELFORMAT_UNCOMPRESSED_R5G5B5A1_ALPHA_THRESHOLD/255.0f))? 1 : 0;; unsigned char a = (coln.w > ((float)PIXELFORMAT_UNCOMPRESSED_R5G5B5A1_ALPHA_THRESHOLD/255.0f))? 1 : 0;
((unsigned short *)dstPtr)[0] = (unsigned short)r << 11 | (unsigned short)g << 6 | (unsigned short)b << 1 | (unsigned short)a; ((unsigned short *)dstPtr)[0] = (unsigned short)r << 11 | (unsigned short)g << 6 | (unsigned short)b << 1 | (unsigned short)a;

View File

@ -56,9 +56,6 @@
#ifndef MAX_TRACELOG_MSG_LENGTH #ifndef MAX_TRACELOG_MSG_LENGTH
#define MAX_TRACELOG_MSG_LENGTH 128 // Max length of one trace-log message #define MAX_TRACELOG_MSG_LENGTH 128 // Max length of one trace-log message
#endif #endif
#ifndef MAX_UWP_MESSAGES
#define MAX_UWP_MESSAGES 512 // Max UWP messages to process
#endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global Variables Definition // Global Variables Definition