Merge branch 'raysan5:master' into master
This commit is contained in:
commit
7d2eee484f
12
.gitignore
vendored
12
.gitignore
vendored
|
|
@ -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*
|
||||||
|
|
|
||||||
18
BINDINGS.md
18
BINDINGS.md
|
|
@ -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
|
||||||
|
|
||||||
Missing some language? Feel free to create a new binding! :)
|
| 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 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}`
|
||||||
|
|
||||||
|
|
|
||||||
11
CHANGELOG
11
CHANGELOG
|
|
@ -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)
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -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`
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
|
|
||||||
// And back to raylib again
|
glUseProgram(0);
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
DrawFPS(screenWidth - 100, 10);
|
DrawFPS(screenWidth - 100, 10);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
@ -124,7 +137,8 @@ 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
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 263 KiB After Width: | Height: | Size: 263 KiB |
|
|
@ -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();
|
||||||
//-----------------------------------------------
|
//-----------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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) |
|
||||||
|
|
|
||||||
BIN
examples/shaders/resources/egg.png
Normal file
BIN
examples/shaders/resources/egg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 316 B |
35
examples/shaders/resources/shaders/glsl100/outline.fs
Normal file
35
examples/shaders/resources/shaders/glsl100/outline.fs
Normal 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));
|
||||||
|
}
|
||||||
36
examples/shaders/resources/shaders/glsl330/outline.fs
Normal file
36
examples/shaders/resources/shaders/glsl330/outline.fs
Normal 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));
|
||||||
|
}
|
||||||
BIN
examples/shaders/resources/torus.png
Normal file
BIN
examples/shaders/resources/torus.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 446 B |
|
|
@ -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;
|
||||||
|
|
|
||||||
84
examples/shaders/shaders_shapes_outline.c
Normal file
84
examples/shaders/shaders_shapes_outline.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -120,3 +124,143 @@ 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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" />
|
||||||
|
|
|
||||||
52
src/config.h
52
src/config.h
|
|
@ -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
|
|
||||||
|
|
|
||||||
73
src/core.c
73
src/core.c
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
162
src/external/par_shapes.h
vendored
162
src/external/par_shapes.h
vendored
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
183
src/models.c
183
src/models.c
|
|
@ -43,23 +43,15 @@
|
||||||
#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)
|
|
||||||
{
|
|
||||||
mesh->tangents = (float*)RL_MALLOC(mesh->vertexCount*4*sizeof(float));
|
|
||||||
}
|
|
||||||
else
|
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,35 +2799,33 @@ 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
|
// Upate existing vertex buffer
|
||||||
|
|
@ -2752,7 +2843,7 @@ void GenMeshTangents(Mesh *mesh)
|
||||||
rlDisableVertexArray();
|
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)],
|
||||||
|
|
|
||||||
15
src/raudio.c
15
src/raudio.c
|
|
@ -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
|
||||||
|
|
|
||||||
139
src/raylib.h
139
src/raylib.h
|
|
@ -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
|
||||||
|
|
|
||||||
105
src/raymath.h
105
src/raymath.h
|
|
@ -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
|
||||||
|
typedef struct Vector3 {
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
float z;
|
float z;
|
||||||
} Vector3;
|
} Vector3;
|
||||||
|
#define RL_VECTOR3_TYPE
|
||||||
|
#endif
|
||||||
|
|
||||||
// Vector4 type
|
#if !defined(RL_VECTOR4_TYPE)
|
||||||
typedef struct Vector4 {
|
// Vector4 type
|
||||||
|
typedef struct Vector4 {
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
float z;
|
float z;
|
||||||
float w;
|
float w;
|
||||||
} Vector4;
|
} 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,9 +1431,10 @@ 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 (Vector3Length(axis) != 0.0f)
|
if (axisLength != 0.0f)
|
||||||
|
{
|
||||||
angle *= 0.5f;
|
angle *= 0.5f;
|
||||||
|
|
||||||
axis = Vector3Normalize(axis);
|
axis = Vector3Normalize(axis);
|
||||||
|
|
@ -1436,6 +1448,7 @@ RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
|
||||||
result.w = cosres;
|
result.w = cosres;
|
||||||
|
|
||||||
result = QuaternionNormalize(result);
|
result = QuaternionNormalize(result);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1502
src/rlgl.h
1502
src/rlgl.h
File diff suppressed because it is too large
Load Diff
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
||||||
209
src/text.c
209
src/text.c
|
|
@ -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
|
|
||||||
|
|
||||||
float textOffsetY = 0; // Offset between lines (on line break '\n')
|
DrawTextEx(font, text, (Vector2){ 0.0f, 0.0f }, fontSize, spacing, tint);
|
||||||
float textOffsetX = 0.0f; // Offset X to next character to draw
|
|
||||||
|
|
||||||
float scaleFactor = fontSize/(float)font.baseSize; // Character quad scaling factor
|
rlPopMatrix();
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
|
||||||
113
src/textures.c
113
src/textures.c
|
|
@ -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,6 +328,8 @@ 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);
|
||||||
|
|
||||||
|
if (image.data != NULL)
|
||||||
|
{
|
||||||
image.mipmaps = 1;
|
image.mipmaps = 1;
|
||||||
|
|
||||||
if (comp == 1) image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
|
if (comp == 1) image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
|
||||||
|
|
@ -338,6 +337,7 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
|
||||||
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
|
||||||
}
|
}
|
||||||
#if defined(SUPPORT_FILEFORMAT_HDR)
|
#if defined(SUPPORT_FILEFORMAT_HDR)
|
||||||
|
|
@ -380,7 +380,8 @@ 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;
|
||||||
ImageDrawPixel(dst, x, y, color);
|
int changeInY = (endPosY - startPosY);
|
||||||
slopeError += m;
|
int absChangeInY = (changeInY < 0)? -changeInY : changeInY;
|
||||||
|
|
||||||
if (slopeError >= 0)
|
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)
|
||||||
{
|
{
|
||||||
y++;
|
A = 2*absChangeInY;
|
||||||
slopeError -= 2*(endPosX - startPosX);
|
B = A - 2*absChangeInX;
|
||||||
|
P = A - absChangeInX;
|
||||||
|
|
||||||
|
if (changeInX > 0)
|
||||||
|
{
|
||||||
|
startU = 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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user