Merged
This commit is contained in:
commit
9a1816bc5b
14
.gitignore
vendored
14
.gitignore
vendored
|
|
@ -53,17 +53,6 @@ packages/
|
||||||
*.bc
|
*.bc
|
||||||
*.so
|
*.so
|
||||||
|
|
||||||
# Ignore all examples files
|
|
||||||
examples/*
|
|
||||||
# Unignore all examples files with extension
|
|
||||||
!examples/*.c
|
|
||||||
!examples/*.png
|
|
||||||
# Unignore examples Makefile
|
|
||||||
!examples/Makefile
|
|
||||||
!examples/Makefile.Android
|
|
||||||
!examples/raylib_compile_execute.bat
|
|
||||||
!examples/raylib_makefile_example.bat
|
|
||||||
|
|
||||||
# Ignore files build by xcode
|
# Ignore files build by xcode
|
||||||
*.mode*v*
|
*.mode*v*
|
||||||
*.pbxuser
|
*.pbxuser
|
||||||
|
|
@ -93,9 +82,6 @@ compile_commands.json
|
||||||
CTestTestfile.cmake
|
CTestTestfile.cmake
|
||||||
build
|
build
|
||||||
|
|
||||||
# Unignore These makefiles...
|
|
||||||
!examples/CMakeLists.txt
|
|
||||||
|
|
||||||
# Ignore GNU global tags
|
# Ignore GNU global tags
|
||||||
GPATH
|
GPATH
|
||||||
GRTAGS
|
GRTAGS
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ Here it is a list with the ones I'm aware of:
|
||||||
| raylib-factor | 3.5 | [Factor](https://factorcode.org/) | https://github.com/ArnautDaniel/raylib-factor |
|
| raylib-factor | 3.5 | [Factor](https://factorcode.org/) | https://github.com/ArnautDaniel/raylib-factor |
|
||||||
| gforth-raylib | 3.5 | [Gforth](https://gforth.org/) | https://github.com/ArnautDaniel/gforth-raylib |
|
| gforth-raylib | 3.5 | [Gforth](https://gforth.org/) | https://github.com/ArnautDaniel/gforth-raylib |
|
||||||
| raylib-haxe | 2.4 | [Haxe](https://haxe.org/) | https://github.com/ibilon/raylib-haxe |
|
| raylib-haxe | 2.4 | [Haxe](https://haxe.org/) | https://github.com/ibilon/raylib-haxe |
|
||||||
|
| hxRaylib | 3.7 | [Haxe](https://haxe.org/) | https://github.com/ForeignSasquatch/hxRaylib |
|
||||||
| ringraylib | 2.6 | [Ring](http://ring-lang.sourceforge.net/) | https://github.com/ringpackages/ringraylib |
|
| ringraylib | 2.6 | [Ring](http://ring-lang.sourceforge.net/) | https://github.com/ringpackages/ringraylib |
|
||||||
| cl-raylib | 3.0 | [Common Lisp](https://common-lisp.net/) | https://github.com/longlene/cl-raylib |
|
| cl-raylib | 3.0 | [Common Lisp](https://common-lisp.net/) | https://github.com/longlene/cl-raylib |
|
||||||
| raylib-scm | 2.5 | [Chicken Scheme](https://www.call-cc.org/) | https://github.com/yashrk/raylib-scm |
|
| raylib-scm | 2.5 | [Chicken Scheme](https://www.call-cc.org/) | https://github.com/yashrk/raylib-scm |
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,16 @@
|
||||||
* This example has been created using raylib 3.7 (www.raylib.com)
|
* This example has been created using raylib 3.7 (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 Giancamillo Alessandroni ([discord]NotManyIdeas#9972 - [github]NotManyIdeasDev) and
|
* Example contributed by Giancamillo Alessandroni (@NotManyIdeasDev) and
|
||||||
* reviewed by Ramon Santamaria (@raysan5)
|
* reviewed by Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2021 Giancamillo Alessandroni (NotManyIdeas#9972) and Ramon Santamaria (@raysan5)
|
* Copyright (c) 2021 Giancamillo Alessandroni (@NotManyIdeasDev) and Ramon Santamaria (@raysan5)
|
||||||
*
|
*
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
#include <math.h>
|
|
||||||
|
#include <math.h> // Required for: sinf(), cosf()
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
|
@ -22,33 +23,32 @@ int main(void)
|
||||||
const int screenWidth = 800;
|
const int screenWidth = 800;
|
||||||
const int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
const int virualScreenWidth = 160;
|
const int virtualScreenWidth = 160;
|
||||||
const int virtualScreenHeight = 90;
|
const int virtualScreenHeight = 90;
|
||||||
|
|
||||||
const float virtualRatio = (float)screenWidth/(float)virualScreenWidth;
|
const float virtualRatio = (float)screenWidth/(float)virtualScreenWidth;
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - smooth pixel-perfect camera");
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - smooth pixel-perfect camera");
|
||||||
|
|
||||||
Camera2D worldSpaceCamera = { 0 }; // Game world camera
|
Camera2D worldSpaceCamera = { 0 }; // Game world camera
|
||||||
worldSpaceCamera.zoom = 1.0f;
|
worldSpaceCamera.zoom = 1.0f;
|
||||||
|
|
||||||
Camera2D screenSpaceCamera = { 0 }; //Smoothing camera
|
Camera2D screenSpaceCamera = { 0 }; // Smoothing camera
|
||||||
screenSpaceCamera.zoom = 1.0f;
|
screenSpaceCamera.zoom = 1.0f;
|
||||||
|
|
||||||
RenderTexture2D renderTexture = LoadRenderTexture(virualScreenWidth, virtualScreenHeight); //This is where we'll draw all our objects.
|
RenderTexture2D target = LoadRenderTexture(virtualScreenWidth, virtualScreenHeight); // This is where we'll draw all our objects.
|
||||||
|
|
||||||
Rectangle firstRectangle = { 70.0f, 35.0f, 20.0f, 20.0f };
|
Rectangle rec01 = { 70.0f, 35.0f, 20.0f, 20.0f };
|
||||||
Rectangle secondRectangle = { 90.0f, 55.0f, 30.0f, 10.0f };
|
Rectangle rec02 = { 90.0f, 55.0f, 30.0f, 10.0f };
|
||||||
Rectangle thirdRectangle = { 80.0f, 65.0f, 15.0f, 25.0f };
|
Rectangle rec03 = { 80.0f, 65.0f, 15.0f, 25.0f };
|
||||||
|
|
||||||
//The renderTexture's height is flipped (in the source Rectangle), due to OpenGL reasons.
|
// The target's height is flipped (in the source Rectangle), due to OpenGL reasons
|
||||||
Rectangle renderTextureSource = { 0.0f, 0.0f, (float)renderTexture.texture.width, (float)-renderTexture.texture.height };
|
Rectangle sourceRec = { 0.0f, 0.0f, (float)target.texture.width, -(float)target.texture.height };
|
||||||
Rectangle renderTextureDest = { -virtualRatio, -virtualRatio, screenWidth + (virtualRatio*2), screenHeight + (virtualRatio*2) };
|
Rectangle destRec = { -virtualRatio, -virtualRatio, screenWidth + (virtualRatio*2), screenHeight + (virtualRatio*2) };
|
||||||
|
|
||||||
Vector2 origin = { 0.0f, 0.0f };
|
Vector2 origin = { 0.0f, 0.0f };
|
||||||
|
|
||||||
float rotation = 0.0f;
|
float rotation = 0.0f;
|
||||||
float degreesPerSecond = 60.0f;
|
|
||||||
|
|
||||||
float cameraX = 0.0f;
|
float cameraX = 0.0f;
|
||||||
float cameraY = 0.0f;
|
float cameraY = 0.0f;
|
||||||
|
|
@ -61,16 +61,16 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
rotation += degreesPerSecond*GetFrameTime(); // Rotate the rectangles.
|
rotation += 60.0f*GetFrameTime(); // Rotate the rectangles, 60 degrees per second
|
||||||
|
|
||||||
// Make the camera move to demonstrate the effect.
|
// Make the camera move to demonstrate the effect
|
||||||
cameraX = (sinf(GetTime())*50.0f) - 10.0f;
|
cameraX = (sinf(GetTime())*50.0f) - 10.0f;
|
||||||
cameraY = cosf(GetTime())*30.0f;
|
cameraY = cosf(GetTime())*30.0f;
|
||||||
|
|
||||||
// Set the camera's target to the values computed above.
|
// Set the camera's target to the values computed above
|
||||||
screenSpaceCamera.target = (Vector2){ cameraX, cameraY };
|
screenSpaceCamera.target = (Vector2){ cameraX, cameraY };
|
||||||
|
|
||||||
//Round worldSpace coordinates, keep decimals into screenSpace coordinates.
|
// Round worldSpace coordinates, keep decimals into screenSpace coordinates
|
||||||
worldSpaceCamera.target.x = (int)screenSpaceCamera.target.x;
|
worldSpaceCamera.target.x = (int)screenSpaceCamera.target.x;
|
||||||
screenSpaceCamera.target.x -= worldSpaceCamera.target.x;
|
screenSpaceCamera.target.x -= worldSpaceCamera.target.x;
|
||||||
screenSpaceCamera.target.x *= virtualRatio;
|
screenSpaceCamera.target.x *= virtualRatio;
|
||||||
|
|
@ -83,47 +83,35 @@ int main(void)
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
BeginDrawing();
|
BeginTextureMode(target);
|
||||||
ClearBackground(RED); // This is for debug purposes. If you see red, then you've probably done something wrong.
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
BeginTextureMode(renderTexture);
|
BeginMode2D(worldSpaceCamera);
|
||||||
BeginMode2D(worldSpaceCamera);
|
DrawRectanglePro(rec01, origin, rotation, BLACK);
|
||||||
ClearBackground(RAYWHITE); // This is the color you should see as background color.
|
DrawRectanglePro(rec02, origin, -rotation, RED);
|
||||||
|
DrawRectanglePro(rec03, origin, rotation + 45.0f, BLUE);
|
||||||
// Draw the rectangles
|
EndMode2D();
|
||||||
DrawRectanglePro(firstRectangle, origin, rotation, BLACK);
|
|
||||||
DrawRectanglePro(secondRectangle, origin, -rotation, RED);
|
|
||||||
DrawRectanglePro(thirdRectangle, origin, rotation + 45.0f, BLUE);
|
|
||||||
|
|
||||||
EndMode2D();
|
|
||||||
EndTextureMode();
|
EndTextureMode();
|
||||||
|
|
||||||
BeginMode2D(screenSpaceCamera);
|
BeginDrawing();
|
||||||
|
ClearBackground(RED);
|
||||||
|
|
||||||
// Draw the render texture with an offset of 1 worldSpace unit/pixel, so that the content behind the renderTexture is not shown.
|
BeginMode2D(screenSpaceCamera);
|
||||||
DrawTexturePro(
|
DrawTexturePro(target.texture, sourceRec, destRec, origin, 0.0f, WHITE);
|
||||||
renderTexture.texture,
|
EndMode2D();
|
||||||
renderTextureSource,
|
|
||||||
renderTextureDest,
|
|
||||||
origin,
|
|
||||||
0.0f,
|
|
||||||
WHITE
|
|
||||||
);
|
|
||||||
|
|
||||||
EndMode2D();
|
DrawText(TextFormat("Screen resolution: %ix%i", screenWidth, screenHeight), 10, 10, 20, DARKBLUE);
|
||||||
|
DrawText(TextFormat("World resolution: %ix%i", virtualScreenWidth, virtualScreenHeight), 10, 40, 20, DARKGREEN);
|
||||||
//Debug info
|
DrawFPS(GetScreenWidth() - 95, 10);
|
||||||
DrawText("Screen resolution: 800x450", 5, 0, 20, DARKBLUE);
|
|
||||||
DrawText("World resolution: 160x90", 5, 20, 20, DARKGREEN);
|
|
||||||
DrawFPS(screenWidth - 75, 0);
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadRenderTexture(renderTexture); // RenderTexture unloading
|
UnloadRenderTexture(target); // Unload render texture
|
||||||
CloseWindow(); // Close window and OpenGL context
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 16 KiB |
125
examples/core/core_custom_frame_control.c
Normal file
125
examples/core/core_custom_frame_control.c
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [core] example - custom frame control
|
||||||
|
*
|
||||||
|
* WARNING: This is an example for advance users willing to have full control over
|
||||||
|
* the frame processes. By default, EndDrawing() calls the following processes:
|
||||||
|
* 1. Draw remaining batch data: rlDrawRenderBatchActive()
|
||||||
|
* 2. SwapScreenBuffer()
|
||||||
|
* 3. Frame time control: WaitTime()
|
||||||
|
* 4. PollInputEvents()
|
||||||
|
*
|
||||||
|
* To avoid steps 2, 3 and 4, flag SUPPORT_CUSTOM_FRAME_CONTROL can be enabled in
|
||||||
|
* config.h (it requires recompiling raylib). This way those steps are up to the user.
|
||||||
|
*
|
||||||
|
* Note that enabling this flag invalidates some functions:
|
||||||
|
* - GetFrameTime()
|
||||||
|
* - SetTargetFPS()
|
||||||
|
* - GetFPS()
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [core] example - custom frame control");
|
||||||
|
|
||||||
|
// Custom timming variables
|
||||||
|
double previousTime = GetTime(); // Previous time measure
|
||||||
|
double currentTime = 0.0; // Current time measure
|
||||||
|
double updateDrawTime = 0.0; // Update + Draw time
|
||||||
|
double waitTime = 0.0; // Wait time (if target fps required)
|
||||||
|
float deltaTime = 0.0f; // Frame time (Update + Draw + Wait time)
|
||||||
|
|
||||||
|
float timeCounter = 0.0f; // Accumulative time counter (seconds)
|
||||||
|
float position = 0.0f; // Circle position
|
||||||
|
bool pause = false; // Pause control flag
|
||||||
|
|
||||||
|
int targetFPS = 60; // Our initial target fps
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
PollInputEvents(); // Poll input events (SUPPORT_CUSTOM_FRAME_CONTROL)
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_SPACE)) pause = !pause;
|
||||||
|
|
||||||
|
if (IsKeyPressed(KEY_UP)) targetFPS += 20;
|
||||||
|
else if (IsKeyPressed(KEY_DOWN)) targetFPS -= 20;
|
||||||
|
|
||||||
|
if (targetFPS < 0) targetFPS = 0;
|
||||||
|
|
||||||
|
if (!pause)
|
||||||
|
{
|
||||||
|
position += 200*deltaTime; // We move at 200 pixels per second
|
||||||
|
if (position >= GetScreenWidth()) position = 0;
|
||||||
|
timeCounter += deltaTime; // We count time (seconds)
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
for (int i = 0; i < GetScreenWidth()/200; i++) DrawRectangle(200*i, 0, 1, GetScreenHeight(), SKYBLUE);
|
||||||
|
|
||||||
|
DrawCircle((int)position, GetScreenHeight()/2 - 25, 50, RED);
|
||||||
|
|
||||||
|
DrawText(FormatText("%03.0f ms", timeCounter*1000.0f), position - 40, GetScreenHeight()/2 - 100, 20, MAROON);
|
||||||
|
DrawText(FormatText("PosX: %03.0f", position), position - 50, GetScreenHeight()/2 + 40, 20, BLACK);
|
||||||
|
|
||||||
|
DrawText("Circle is moving at a constant 200 pixels/sec,\nindependently of the frame rate.", 10, 10, 20, DARKGRAY);
|
||||||
|
DrawText("PRESS SPACE to PAUSE MOVEMENT", 10, GetScreenHeight() - 60, 20, GRAY);
|
||||||
|
DrawText("PRESS UP | DOWN to CHANGE TARGET FPS", 10, GetScreenHeight() - 30, 20, GRAY);
|
||||||
|
DrawText(FormatText("TARGET FPS: %i", targetFPS), GetScreenWidth() - 220, 10, 20, LIME);
|
||||||
|
DrawText(FormatText("CURRENT FPS: %i", (int)(1.0f/deltaTime)), GetScreenWidth() - 220, 40, 20, GREEN);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
|
||||||
|
// NOTE: In case raylib is configured to SUPPORT_CUSTOM_FRAME_CONTROL,
|
||||||
|
// Events polling, screen buffer swap and frame time control must be managed by the user
|
||||||
|
|
||||||
|
SwapScreenBuffer(); // Flip the back buffer to screen (front buffer)
|
||||||
|
|
||||||
|
currentTime = GetTime();
|
||||||
|
updateDrawTime = currentTime - previousTime;
|
||||||
|
|
||||||
|
if (targetFPS > 0) // We want a fixed frame rate
|
||||||
|
{
|
||||||
|
waitTime = (1.0f/(float)targetFPS) - updateDrawTime;
|
||||||
|
if (waitTime > 0.0)
|
||||||
|
{
|
||||||
|
WaitTime((float)waitTime*1000.0f);
|
||||||
|
currentTime = GetTime();
|
||||||
|
deltaTime = (float)(currentTime - previousTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else deltaTime = updateDrawTime; // Framerate could be variable
|
||||||
|
|
||||||
|
previousTime = currentTime;
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
BIN
examples/core/core_custom_frame_control.png
Normal file
BIN
examples/core/core_custom_frame_control.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
83
examples/core/core_rotate_by_quat.c
Normal file
83
examples/core/core_rotate_by_quat.c
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "rlgl.h" // just to change line width
|
||||||
|
#include "raymath.h"
|
||||||
|
|
||||||
|
#define windowWidth 1280
|
||||||
|
#define windowHeight 720
|
||||||
|
|
||||||
|
Vector3 Vector3MultiplyQuaternion(Vector3 v, Quaternion q)
|
||||||
|
{
|
||||||
|
Vector3 r, qv, uv, uuv;
|
||||||
|
|
||||||
|
qv.x = q.x;
|
||||||
|
qv.y = q.y;
|
||||||
|
qv.z = q.z;
|
||||||
|
|
||||||
|
uv = Vector3CrossProduct(qv, v);
|
||||||
|
uuv = Vector3CrossProduct(qv, uv);
|
||||||
|
|
||||||
|
uv = Vector3Scale(uv, 2.f*q.w);
|
||||||
|
uuv = Vector3Scale(uuv, 2.0f);
|
||||||
|
|
||||||
|
r = Vector3Add(v, uv);
|
||||||
|
r = Vector3Add(r, uuv);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
SetTraceLogLevel( LOG_ALL );
|
||||||
|
SetConfigFlags( FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT );
|
||||||
|
InitWindow( windowWidth, windowHeight, "Raylib - template" );
|
||||||
|
|
||||||
|
Camera camera = { 0 };
|
||||||
|
camera.position = (Vector3){ 0.0f, 1.0f, 4.0f };
|
||||||
|
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
|
||||||
|
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||||
|
camera.fovy = 45.0f;
|
||||||
|
camera.projection = CAMERA_PERSPECTIVE;
|
||||||
|
|
||||||
|
Vector3 ang = { 0 };
|
||||||
|
Vector3 qv = { 0 };
|
||||||
|
Vector3 mv = { 0 };
|
||||||
|
Vector3 bv = { 0 };
|
||||||
|
Quaternion q;
|
||||||
|
|
||||||
|
float dT = 0;
|
||||||
|
|
||||||
|
rlSetLineWidth(4);
|
||||||
|
while ( !WindowShouldClose() )
|
||||||
|
{
|
||||||
|
dT = GetFrameTime();
|
||||||
|
|
||||||
|
ang.x += .7f * dT;
|
||||||
|
ang.y += .55 * dT;
|
||||||
|
ang.z -= 2.75 * dT;
|
||||||
|
|
||||||
|
q = QuaternionFromEuler(ang.x, ang.y, ang.z);
|
||||||
|
qv = Vector3MultiplyQuaternion((Vector3){0,0,1}, q);
|
||||||
|
|
||||||
|
Matrix m = QuaternionToMatrix(q);
|
||||||
|
mv = Vector3Transform((Vector3){0,0,1},m);
|
||||||
|
|
||||||
|
bv = Vector3RotateByQuaternion((Vector3){0,0,1}, q);
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground( (Color){64,128,255,255} );
|
||||||
|
|
||||||
|
BeginMode3D( camera );
|
||||||
|
DrawLine3D((Vector3){0,0,0}, qv, GREEN);
|
||||||
|
DrawLine3D((Vector3){-.1,0,0}, mv, YELLOW);
|
||||||
|
DrawLine3D((Vector3){.1,0,0}, bv, RED);
|
||||||
|
|
||||||
|
DrawGrid( 10, 1.0f );
|
||||||
|
|
||||||
|
EndMode3D();
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseWindow();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -89,7 +89,7 @@ int main(void)
|
||||||
// this moves thigns at 10 world units per second, regardless of the actual FPS
|
// this moves thigns at 10 world units per second, regardless of the actual FPS
|
||||||
float offsetThisFrame = 10.0f*GetFrameTime();
|
float offsetThisFrame = 10.0f*GetFrameTime();
|
||||||
|
|
||||||
// Move player 1 forward and backwards (no turning)
|
// Move Player1 forward and backwards (no turning)
|
||||||
if (IsKeyDown(KEY_W))
|
if (IsKeyDown(KEY_W))
|
||||||
{
|
{
|
||||||
cameraPlayer1.position.z += offsetThisFrame;
|
cameraPlayer1.position.z += offsetThisFrame;
|
||||||
|
|
@ -101,7 +101,7 @@ int main(void)
|
||||||
cameraPlayer1.target.z -= offsetThisFrame;
|
cameraPlayer1.target.z -= offsetThisFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move player 2 forward and backwards (no turning)
|
// Move Player2 forward and backwards (no turning)
|
||||||
if (IsKeyDown(KEY_UP))
|
if (IsKeyDown(KEY_UP))
|
||||||
{
|
{
|
||||||
cameraPlayer2.position.x += offsetThisFrame;
|
cameraPlayer2.position.x += offsetThisFrame;
|
||||||
|
|
@ -116,7 +116,7 @@ int main(void)
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Draw player 1's view to the render texture
|
// Draw Player1 view to the render texture
|
||||||
BeginTextureMode(screenPlayer1);
|
BeginTextureMode(screenPlayer1);
|
||||||
ClearBackground(SKYBLUE);
|
ClearBackground(SKYBLUE);
|
||||||
BeginMode3D(cameraPlayer1);
|
BeginMode3D(cameraPlayer1);
|
||||||
|
|
@ -125,7 +125,7 @@ int main(void)
|
||||||
DrawText("PLAYER1 W/S to move", 0, 0, 20, RED);
|
DrawText("PLAYER1 W/S to move", 0, 0, 20, RED);
|
||||||
EndTextureMode();
|
EndTextureMode();
|
||||||
|
|
||||||
// Draw player 2's view to the render texture
|
// Draw Player2 view to the render texture
|
||||||
BeginTextureMode(screenPlayer2);
|
BeginTextureMode(screenPlayer2);
|
||||||
ClearBackground(SKYBLUE);
|
ClearBackground(SKYBLUE);
|
||||||
BeginMode3D(cameraPlayer2);
|
BeginMode3D(cameraPlayer2);
|
||||||
|
|
@ -134,21 +134,21 @@ int main(void)
|
||||||
DrawText("PLAYER2 UP/DOWN to move", 0, 0, 20, BLUE);
|
DrawText("PLAYER2 UP/DOWN to move", 0, 0, 20, BLUE);
|
||||||
EndTextureMode();
|
EndTextureMode();
|
||||||
|
|
||||||
// Draw both view render textures to the screen side by side
|
// Draw both views render textures to the screen side by side
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
ClearBackground(BLACK);
|
ClearBackground(BLACK);
|
||||||
DrawTextureRec(screenPlayer1.texture, splitScreenRect, (Vector2) { 0, 0 }, WHITE);
|
DrawTextureRec(screenPlayer1.texture, splitScreenRect, (Vector2){ 0, 0 }, WHITE);
|
||||||
DrawTextureRec(screenPlayer2.texture, splitScreenRect, (Vector2) { screenWidth/2.0f, 0 }, WHITE);
|
DrawTextureRec(screenPlayer2.texture, splitScreenRect, (Vector2){ screenWidth/2.0f, 0 }, WHITE);
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadRenderTexture(screenPlayer1);
|
UnloadRenderTexture(screenPlayer1); // Unload render texture
|
||||||
UnloadRenderTexture(screenPlayer2);
|
UnloadRenderTexture(screenPlayer2); // Unload render texture
|
||||||
UnloadTexture(textureGrid);
|
UnloadTexture(textureGrid); // Unload texture
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -105,30 +105,26 @@ int main(void)
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
BeginDrawing();
|
BeginTextureMode(target);
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
BeginVrStereoMode(config);
|
||||||
|
BeginMode3D(camera);
|
||||||
|
|
||||||
BeginTextureMode(target);
|
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
|
||||||
ClearBackground(RAYWHITE);
|
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
|
||||||
BeginVrStereoMode(config);
|
DrawGrid(40, 1.0f);
|
||||||
BeginMode3D(camera);
|
|
||||||
|
|
||||||
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
|
EndMode3D();
|
||||||
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
|
EndVrStereoMode();
|
||||||
DrawGrid(40, 1.0f);
|
EndTextureMode();
|
||||||
|
|
||||||
EndMode3D();
|
|
||||||
EndVrStereoMode();
|
|
||||||
EndTextureMode();
|
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
BeginShaderMode(distortion);
|
BeginShaderMode(distortion);
|
||||||
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width,
|
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width,
|
||||||
(float)-target.texture.height }, (Vector2){ 0.0f, 0.0f }, WHITE);
|
(float)-target.texture.height }, (Vector2){ 0.0f, 0.0f }, WHITE);
|
||||||
EndShaderMode();
|
EndShaderMode();
|
||||||
|
|
||||||
DrawFPS(10, 10);
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,11 @@ int main(void)
|
||||||
Color colors[10] = { 0 };
|
Color colors[10] = { 0 };
|
||||||
for (int i = 0; i < 10; i++) colors[i] = (Color){ GetRandomValue(100, 250), GetRandomValue(50, 150), GetRandomValue(10, 100), 255 };
|
for (int i = 0; i < 10; i++) colors[i] = (Color){ GetRandomValue(100, 250), GetRandomValue(50, 150), GetRandomValue(10, 100), 255 };
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -79,37 +79,33 @@ int main(void)
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
// Draw everything in the render texture, note this will not be rendered on screen, yet
|
||||||
|
BeginTextureMode(target);
|
||||||
|
ClearBackground(RAYWHITE); // Clear render texture background color
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++) DrawRectangle(0, (gameScreenHeight/10)*i, gameScreenWidth, gameScreenHeight/10, colors[i]);
|
||||||
|
|
||||||
|
DrawText("If executed inside a window,\nyou can resize the window,\nand see the screen scaling!", 10, 25, 20, WHITE);
|
||||||
|
DrawText(TextFormat("Default Mouse: [%i , %i]", (int)mouse.x, (int)mouse.y), 350, 25, 20, GREEN);
|
||||||
|
DrawText(TextFormat("Virtual Mouse: [%i , %i]", (int)virtualMouse.x, (int)virtualMouse.y), 350, 55, 20, YELLOW);
|
||||||
|
EndTextureMode();
|
||||||
|
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
ClearBackground(BLACK);
|
ClearBackground(BLACK); // Clear screen background
|
||||||
|
|
||||||
// Draw everything in the render texture, note this will not be rendered on screen, yet
|
// Draw render texture to screen, properly scaled
|
||||||
BeginTextureMode(target);
|
|
||||||
|
|
||||||
ClearBackground(RAYWHITE); // Clear render texture background color
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) DrawRectangle(0, (gameScreenHeight/10)*i, gameScreenWidth, gameScreenHeight/10, colors[i]);
|
|
||||||
|
|
||||||
DrawText("If executed inside a window,\nyou can resize the window,\nand see the screen scaling!", 10, 25, 20, WHITE);
|
|
||||||
|
|
||||||
DrawText(TextFormat("Default Mouse: [%i , %i]", (int)mouse.x, (int)mouse.y), 350, 25, 20, GREEN);
|
|
||||||
DrawText(TextFormat("Virtual Mouse: [%i , %i]", (int)virtualMouse.x, (int)virtualMouse.y), 350, 55, 20, YELLOW);
|
|
||||||
|
|
||||||
EndTextureMode();
|
|
||||||
|
|
||||||
// Draw RenderTexture2D to window, properly scaled
|
|
||||||
DrawTexturePro(target.texture, (Rectangle){ 0.0f, 0.0f, (float)target.texture.width, (float)-target.texture.height },
|
DrawTexturePro(target.texture, (Rectangle){ 0.0f, 0.0f, (float)target.texture.width, (float)-target.texture.height },
|
||||||
(Rectangle){ (GetScreenWidth() - ((float)gameScreenWidth*scale))*0.5f, (GetScreenHeight() - ((float)gameScreenHeight*scale))*0.5f,
|
(Rectangle){ (GetScreenWidth() - ((float)gameScreenWidth*scale))*0.5f, (GetScreenHeight() - ((float)gameScreenHeight*scale))*0.5f,
|
||||||
(float)gameScreenWidth*scale, (float)gameScreenHeight*scale }, (Vector2){ 0, 0 }, 0.0f, WHITE);
|
(float)gameScreenWidth*scale, (float)gameScreenHeight*scale }, (Vector2){ 0, 0 }, 0.0f, WHITE);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadRenderTexture(target); // Unload render texture
|
UnloadRenderTexture(target); // Unload render texture
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -41,16 +41,18 @@
|
||||||
*
|
*
|
||||||
* raylib [core] example - Basic window
|
* raylib [core] example - Basic window
|
||||||
*
|
*
|
||||||
* This example has been created using raylib 2.5 (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)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019 Ramon Santamaria (@raysan5)
|
* Example contributed by <user_name> (@<user_github>) and reviewed by Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 <user_name> (@<user_github>)
|
||||||
*
|
*
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
int main()
|
int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ int main(void)
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
for(int i = 0; i < MAX_MODELS; i++) UnloadModel(model[i]); // Unload models
|
for (int i = 0; i < MAX_MODELS; i++) UnloadModel(model[i]); // Unload models
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,14 @@
|
||||||
#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
|
||||||
|
|
||||||
|
// Color, 4 components, R8G8B8A8 (32bit)
|
||||||
|
typedef struct Color {
|
||||||
|
unsigned char r; // Color red value
|
||||||
|
unsigned char g; // Color green value
|
||||||
|
unsigned char b; // Color blue value
|
||||||
|
unsigned char a; // Color alpha value
|
||||||
|
} Color;
|
||||||
|
|
||||||
// Camera type, defines a camera position/orientation in 3d space
|
// Camera type, defines a camera position/orientation in 3d space
|
||||||
typedef struct Camera {
|
typedef struct Camera {
|
||||||
Vector3 position; // Camera position
|
Vector3 position; // Camera position
|
||||||
|
|
@ -271,7 +279,7 @@ static void DrawGrid(int slices, float spacing)
|
||||||
int halfSlices = slices / 2;
|
int halfSlices = slices / 2;
|
||||||
|
|
||||||
rlBegin(RL_LINES);
|
rlBegin(RL_LINES);
|
||||||
for(int i = -halfSlices; i <= halfSlices; i++)
|
for (int i = -halfSlices; i <= halfSlices; i++)
|
||||||
{
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -65,11 +65,11 @@ int main(void)
|
||||||
// Setup orbital camera
|
// Setup orbital camera
|
||||||
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
|
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -81,55 +81,46 @@ int main(void)
|
||||||
// Send new value to the shader to be used on drawing
|
// Send new value to the shader to be used on drawing
|
||||||
SetShaderValue(shader, swirlCenterLoc, swirlCenter, SHADER_UNIFORM_VEC2);
|
SetShaderValue(shader, swirlCenterLoc, swirlCenter, SHADER_UNIFORM_VEC2);
|
||||||
|
|
||||||
UpdateCamera(&camera); // Update camera
|
UpdateCamera(&camera); // Update camera
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginTextureMode(target); // Enable drawing to texture
|
||||||
|
ClearBackground(RAYWHITE); // Clear texture background
|
||||||
|
|
||||||
|
BeginMode3D(camera); // Begin 3d mode drawing
|
||||||
|
DrawModel(model, position, 0.5f, WHITE); // Draw 3d model with texture
|
||||||
|
DrawGrid(10, 1.0f); // Draw a grid
|
||||||
|
EndMode3D(); // End 3d mode drawing, returns to orthographic 2d mode
|
||||||
|
|
||||||
|
DrawText("TEXT DRAWN IN RENDER TEXTURE", 200, 10, 30, RED);
|
||||||
|
EndTextureMode(); // End drawing to texture (now we have a texture available for next passes)
|
||||||
|
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE); // Clear screen background
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
// Enable shader using the custom uniform
|
||||||
|
|
||||||
BeginTextureMode(target); // Enable drawing to texture
|
|
||||||
|
|
||||||
ClearBackground(RAYWHITE); // Clear texture background
|
|
||||||
|
|
||||||
BeginMode3D(camera); // Begin 3d mode drawing
|
|
||||||
|
|
||||||
DrawModel(model, position, 0.5f, WHITE); // Draw 3d model with texture
|
|
||||||
|
|
||||||
DrawGrid(10, 1.0f); // Draw a grid
|
|
||||||
|
|
||||||
EndMode3D(); // End 3d mode drawing, returns to orthographic 2d mode
|
|
||||||
|
|
||||||
DrawText("TEXT DRAWN IN RENDER TEXTURE", 200, 10, 30, RED);
|
|
||||||
|
|
||||||
EndTextureMode(); // End drawing to texture (now we have a texture available for next passes)
|
|
||||||
|
|
||||||
BeginShaderMode(shader);
|
BeginShaderMode(shader);
|
||||||
|
|
||||||
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
|
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
|
||||||
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0, 0 }, WHITE);
|
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0, 0 }, WHITE);
|
||||||
|
|
||||||
EndShaderMode();
|
EndShaderMode();
|
||||||
|
|
||||||
// Draw some 2d text over drawn texture
|
// Draw some 2d text over drawn texture
|
||||||
DrawText("(c) Barracks 3D model by Alberto Cano", screenWidth - 220, screenHeight - 20, 10, GRAY);
|
DrawText("(c) Barracks 3D model by Alberto Cano", screenWidth - 220, screenHeight - 20, 10, GRAY);
|
||||||
|
|
||||||
DrawFPS(10, 10);
|
DrawFPS(10, 10);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadShader(shader); // Unload shader
|
UnloadShader(shader); // Unload shader
|
||||||
UnloadTexture(texture); // Unload texture
|
UnloadTexture(texture); // Unload texture
|
||||||
UnloadModel(model); // Unload model
|
UnloadModel(model); // Unload model
|
||||||
UnloadRenderTexture(target); // Unload render texture
|
UnloadRenderTexture(target); // Unload render texture
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,11 @@ int main(void)
|
||||||
// NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
|
// NOTE: Defining 0 (NULL) for vertex shader forces usage of internal default vertex shader
|
||||||
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/eratosthenes.fs", GLSL_VERSION));
|
Shader shader = LoadShader(0, TextFormat("resources/shaders/glsl%i/eratosthenes.fs", GLSL_VERSION));
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -59,35 +59,33 @@ int main(void)
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginTextureMode(target); // Enable drawing to texture
|
||||||
|
ClearBackground(BLACK); // Clear the render texture
|
||||||
|
|
||||||
|
// Draw a rectangle in shader mode to be used as shader canvas
|
||||||
|
// NOTE: Rectangle uses font white character texture coordinates,
|
||||||
|
// so shader can not be applied here directly because input vertexTexCoord
|
||||||
|
// do not represent full screen coordinates (space where want to apply shader)
|
||||||
|
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK);
|
||||||
|
EndTextureMode(); // End drawing to texture (now we have a blank texture available for the shader)
|
||||||
|
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE); // Clear screen background
|
||||||
ClearBackground(RAYWHITE);
|
|
||||||
|
|
||||||
BeginTextureMode(target); // Enable drawing to texture
|
|
||||||
ClearBackground(BLACK); // Clear the render texture
|
|
||||||
|
|
||||||
// Draw a rectangle in shader mode to be used as shader canvas
|
|
||||||
// NOTE: Rectangle uses font white character texture coordinates,
|
|
||||||
// so shader can not be applied here directly because input vertexTexCoord
|
|
||||||
// do not represent full screen coordinates (space where want to apply shader)
|
|
||||||
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK);
|
|
||||||
EndTextureMode(); // End drawing to texture (now we have a blank texture available for the shader)
|
|
||||||
|
|
||||||
BeginShaderMode(shader);
|
BeginShaderMode(shader);
|
||||||
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
|
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
|
||||||
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0.0f, 0.0f }, WHITE);
|
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0.0f, 0.0f }, WHITE);
|
||||||
EndShaderMode();
|
EndShaderMode();
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadShader(shader); // Unload shader
|
UnloadShader(shader); // Unload shader
|
||||||
UnloadRenderTexture(target); // Unload texture
|
UnloadRenderTexture(target); // Unload render texture
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -75,15 +75,15 @@ int main(void)
|
||||||
SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
|
SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
|
||||||
SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
|
SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
|
||||||
|
|
||||||
int incrementSpeed = 0; // Multiplier of speed to change c value
|
int incrementSpeed = 0; // Multiplier of speed to change c value
|
||||||
bool showControls = true; // Show controls
|
bool showControls = true; // Show controls
|
||||||
bool pause = false; // Pause animation
|
bool pause = false; // Pause animation
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Main game loop
|
// Main game loop
|
||||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -145,20 +145,19 @@ int main(void)
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
// Using a render texture to draw Julia set
|
||||||
|
BeginTextureMode(target); // Enable drawing to texture
|
||||||
|
ClearBackground(BLACK); // Clear the render texture
|
||||||
|
|
||||||
|
// Draw a rectangle in shader mode to be used as shader canvas
|
||||||
|
// NOTE: Rectangle uses font white character texture coordinates,
|
||||||
|
// so shader can not be applied here directly because input vertexTexCoord
|
||||||
|
// do not represent full screen coordinates (space where want to apply shader)
|
||||||
|
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK);
|
||||||
|
EndTextureMode();
|
||||||
|
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
ClearBackground(BLACK); // Clear screen background
|
||||||
ClearBackground(BLACK); // Clear the screen of the previous frame.
|
|
||||||
|
|
||||||
// Using a render texture to draw Julia set
|
|
||||||
BeginTextureMode(target); // Enable drawing to texture
|
|
||||||
ClearBackground(BLACK); // Clear the render texture
|
|
||||||
|
|
||||||
// Draw a rectangle in shader mode to be used as shader canvas
|
|
||||||
// NOTE: Rectangle uses font white character texture coordinates,
|
|
||||||
// so shader can not be applied here directly because input vertexTexCoord
|
|
||||||
// do not represent full screen coordinates (space where want to apply shader)
|
|
||||||
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), BLACK);
|
|
||||||
EndTextureMode();
|
|
||||||
|
|
||||||
// Draw the saved texture and rendered julia set with shader
|
// Draw the saved texture and rendered julia set with shader
|
||||||
// NOTE: We do not invert texture on Y, already considered inside shader
|
// NOTE: We do not invert texture on Y, already considered inside shader
|
||||||
|
|
@ -176,17 +175,16 @@ int main(void)
|
||||||
DrawText("Press KEY_LEFT | KEY_RIGHT to change speed", 10, 60, 10, RAYWHITE);
|
DrawText("Press KEY_LEFT | KEY_RIGHT to change speed", 10, 60, 10, RAYWHITE);
|
||||||
DrawText("Press KEY_SPACE to pause movement animation", 10, 75, 10, RAYWHITE);
|
DrawText("Press KEY_SPACE to pause movement animation", 10, 75, 10, RAYWHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
UnloadShader(shader); // Unload shader
|
UnloadShader(shader); // Unload shader
|
||||||
UnloadRenderTexture(target); // Unload render texture
|
UnloadRenderTexture(target); // Unload render texture
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -124,50 +124,38 @@ int main(void)
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginTextureMode(target); // Enable drawing to texture
|
||||||
|
ClearBackground(RAYWHITE); // Clear texture background
|
||||||
|
|
||||||
|
BeginMode3D(camera); // Begin 3d mode drawing
|
||||||
|
DrawModel(model, position, 0.1f, WHITE); // Draw 3d model with texture
|
||||||
|
DrawGrid(10, 1.0f); // Draw a grid
|
||||||
|
EndMode3D(); // End 3d mode drawing, returns to orthographic 2d mode
|
||||||
|
EndTextureMode(); // End drawing to texture (now we have a texture available for next passes)
|
||||||
|
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
|
ClearBackground(RAYWHITE); // Clear screen background
|
||||||
|
|
||||||
ClearBackground(RAYWHITE);
|
// Render generated texture using selected postprocessing shader
|
||||||
|
|
||||||
BeginTextureMode(target); // Enable drawing to texture
|
|
||||||
|
|
||||||
ClearBackground(RAYWHITE); // Clear texture background
|
|
||||||
|
|
||||||
BeginMode3D(camera); // Begin 3d mode drawing
|
|
||||||
|
|
||||||
DrawModel(model, position, 0.1f, WHITE); // Draw 3d model with texture
|
|
||||||
|
|
||||||
DrawGrid(10, 1.0f); // Draw a grid
|
|
||||||
|
|
||||||
EndMode3D(); // End 3d mode drawing, returns to orthographic 2d mode
|
|
||||||
|
|
||||||
EndTextureMode(); // End drawing to texture (now we have a texture available for next passes)
|
|
||||||
|
|
||||||
// Render previously generated texture using selected postpro shader
|
|
||||||
BeginShaderMode(shaders[currentShader]);
|
BeginShaderMode(shaders[currentShader]);
|
||||||
|
|
||||||
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
|
// NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
|
||||||
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0, 0 }, WHITE);
|
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width, (float)-target.texture.height }, (Vector2){ 0, 0 }, WHITE);
|
||||||
|
|
||||||
EndShaderMode();
|
EndShaderMode();
|
||||||
|
|
||||||
// Draw 2d shapes and text over drawn texture
|
// Draw 2d shapes and text over drawn texture
|
||||||
DrawRectangle(0, 9, 580, 30, Fade(LIGHTGRAY, 0.7f));
|
DrawRectangle(0, 9, 580, 30, Fade(LIGHTGRAY, 0.7f));
|
||||||
|
|
||||||
DrawText("(c) Church 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY);
|
DrawText("(c) Church 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY);
|
||||||
|
|
||||||
DrawText("CURRENT POSTPRO SHADER:", 10, 15, 20, BLACK);
|
DrawText("CURRENT POSTPRO SHADER:", 10, 15, 20, BLACK);
|
||||||
DrawText(postproShaderText[currentShader], 330, 15, 20, RED);
|
DrawText(postproShaderText[currentShader], 330, 15, 20, RED);
|
||||||
DrawText("< >", 540, 10, 30, DARKBLUE);
|
DrawText("< >", 540, 10, 30, DARKBLUE);
|
||||||
|
|
||||||
DrawFPS(700, 15);
|
DrawFPS(700, 15);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Unload all postpro shaders
|
// Unload all postpro shaders
|
||||||
for (int i = 0; i < MAX_POSTPRO_SHADERS; i++) UnloadShader(shaders[i]);
|
for (int i = 0; i < MAX_POSTPRO_SHADERS; i++) UnloadShader(shaders[i]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ int main(void)
|
||||||
for (int i = 0; i < layers; ++i)
|
for (int i = 0; i < layers; ++i)
|
||||||
{
|
{
|
||||||
Color clr = light;
|
Color clr = light;
|
||||||
if(multicolor) clr = multi[i];
|
if (multicolor) clr = multi[i];
|
||||||
DrawTextWave3D(font, text, (Vector3){ -tbox.x/2.0f, layerDistance*i, -4.5f }, fontSize, fontSpacing, lineSpacing, true, &wcfg, time, clr);
|
DrawTextWave3D(font, text, (Vector3){ -tbox.x/2.0f, layerDistance*i, -4.5f }, fontSize, fontSpacing, lineSpacing, true, &wcfg, time, clr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -465,7 +465,7 @@ void DrawTextCodepoint3D(Font font, int codepoint, Vector3 position, float fontS
|
||||||
float width = (float)(font.recs[index].width + 2.0f*font.charsPadding)/(float)font.baseSize*scale;
|
float width = (float)(font.recs[index].width + 2.0f*font.charsPadding)/(float)font.baseSize*scale;
|
||||||
float height = (float)(font.recs[index].height + 2.0f*font.charsPadding)/(float)font.baseSize*scale;
|
float height = (float)(font.recs[index].height + 2.0f*font.charsPadding)/(float)font.baseSize*scale;
|
||||||
|
|
||||||
if(font.texture.id > 0)
|
if (font.texture.id > 0)
|
||||||
{
|
{
|
||||||
const float x = 0.0f;
|
const float x = 0.0f;
|
||||||
const float y = 0.0f;
|
const float y = 0.0f;
|
||||||
|
|
@ -477,7 +477,7 @@ void DrawTextCodepoint3D(Font font, int codepoint, Vector3 position, float fontS
|
||||||
const float tw = (srcRec.x+srcRec.width)/font.texture.width;
|
const float tw = (srcRec.x+srcRec.width)/font.texture.width;
|
||||||
const float th = (srcRec.y+srcRec.height)/font.texture.height;
|
const float th = (srcRec.y+srcRec.height)/font.texture.height;
|
||||||
|
|
||||||
if(SHOW_LETTER_BOUNDRY)
|
if (SHOW_LETTER_BOUNDRY)
|
||||||
DrawCubeWiresV((Vector3){ position.x + width/2, position.y, position.z + height/2}, (Vector3){ width, LETTER_BOUNDRY_SIZE, height }, LETTER_BOUNDRY_COLOR);
|
DrawCubeWiresV((Vector3){ position.x + width/2, position.y, position.z + height/2}, (Vector3){ width, LETTER_BOUNDRY_SIZE, height }, LETTER_BOUNDRY_COLOR);
|
||||||
|
|
||||||
#if defined(RAYLIB_NEW_RLGL)
|
#if defined(RAYLIB_NEW_RLGL)
|
||||||
|
|
@ -533,7 +533,7 @@ void DrawText3D(Font font, const char *text, Vector3 position, float fontSize, f
|
||||||
{
|
{
|
||||||
// Get next codepoint from byte string and glyph index in font
|
// Get next codepoint from byte string and glyph index in font
|
||||||
int codepointByteCount = 0;
|
int codepointByteCount = 0;
|
||||||
int codepoint = GetNextCodepoint(&text[i], &codepointByteCount);
|
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
||||||
int index = GetGlyphIndex(font, codepoint);
|
int index = GetGlyphIndex(font, codepoint);
|
||||||
|
|
||||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||||
|
|
@ -582,7 +582,7 @@ Vector3 MeasureText3D(Font font, const char* text, float fontSize, float fontSpa
|
||||||
lenCounter++;
|
lenCounter++;
|
||||||
|
|
||||||
int next = 0;
|
int next = 0;
|
||||||
letter = GetNextCodepoint(&text[i], &next);
|
letter = GetCodepoint(&text[i], &next);
|
||||||
index = GetGlyphIndex(font, letter);
|
index = GetGlyphIndex(font, letter);
|
||||||
|
|
||||||
// NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
// NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||||
|
|
@ -632,7 +632,7 @@ void DrawTextWave3D(Font font, const char *text, Vector3 position, float fontSiz
|
||||||
{
|
{
|
||||||
// Get next codepoint from byte string and glyph index in font
|
// Get next codepoint from byte string and glyph index in font
|
||||||
int codepointByteCount = 0;
|
int codepointByteCount = 0;
|
||||||
int codepoint = GetNextCodepoint(&text[i], &codepointByteCount);
|
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
||||||
int index = GetGlyphIndex(font, codepoint);
|
int index = GetGlyphIndex(font, codepoint);
|
||||||
|
|
||||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||||
|
|
@ -649,7 +649,7 @@ void DrawTextWave3D(Font font, const char *text, Vector3 position, float fontSiz
|
||||||
}
|
}
|
||||||
else if (codepoint == '~')
|
else if (codepoint == '~')
|
||||||
{
|
{
|
||||||
if (GetNextCodepoint(&text[i+1], &codepointByteCount) == '~')
|
if (GetCodepoint(&text[i+1], &codepointByteCount) == '~')
|
||||||
{
|
{
|
||||||
codepointByteCount += 1;
|
codepointByteCount += 1;
|
||||||
wave = !wave;
|
wave = !wave;
|
||||||
|
|
@ -698,7 +698,7 @@ Vector3 MeasureTextWave3D(Font font, const char* text, float fontSize, float fon
|
||||||
lenCounter++;
|
lenCounter++;
|
||||||
|
|
||||||
int next = 0;
|
int next = 0;
|
||||||
letter = GetNextCodepoint(&text[i], &next);
|
letter = GetCodepoint(&text[i], &next);
|
||||||
index = GetGlyphIndex(font, letter);
|
index = GetGlyphIndex(font, letter);
|
||||||
|
|
||||||
// NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
// NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||||
|
|
@ -708,7 +708,7 @@ Vector3 MeasureTextWave3D(Font font, const char* text, float fontSize, float fon
|
||||||
|
|
||||||
if (letter != '\n')
|
if (letter != '\n')
|
||||||
{
|
{
|
||||||
if(letter == '~' && GetNextCodepoint(&text[i+1], &next) == '~')
|
if (letter == '~' && GetCodepoint(&text[i+1], &next) == '~')
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -298,7 +298,7 @@ GenMeshTorus|Mesh|(float radius, float size, int radSeg, int sides);|
|
||||||
GenMeshKnot|Mesh|(float radius, float size, int radSeg, int sides);|
|
GenMeshKnot|Mesh|(float radius, float size, int radSeg, int sides);|
|
||||||
GenMeshHeightmap|Mesh|(Image heightmap, Vector3 size);|
|
GenMeshHeightmap|Mesh|(Image heightmap, Vector3 size);|
|
||||||
GenMeshCubicmap|Mesh|(Image cubicmap, Vector3 cubeSize);|
|
GenMeshCubicmap|Mesh|(Image cubicmap, Vector3 cubeSize);|
|
||||||
MeshBoundingBox|BoundingBox|(Mesh mesh);|
|
GetMeshBoundingBox|BoundingBox|(Mesh mesh);|
|
||||||
MeshTangents|void|(Mesh *mesh);|
|
MeshTangents|void|(Mesh *mesh);|
|
||||||
MeshBinormals|void|(Mesh *mesh);|
|
MeshBinormals|void|(Mesh *mesh);|
|
||||||
DrawModel|void|(Model model, Vector3 position, float scale, Color tint);|
|
DrawModel|void|(Model model, Vector3 position, float scale, Color tint);|
|
||||||
|
|
|
||||||
|
|
@ -1549,7 +1549,7 @@
|
||||||
</KeyWord>
|
</KeyWord>
|
||||||
|
|
||||||
<!-- Mesh manipulation functions -->
|
<!-- Mesh manipulation functions -->
|
||||||
<KeyWord name="MeshBoundingBox" func="yes">
|
<KeyWord name="GetMeshBoundingBox" func="yes">
|
||||||
<Overload retVal="BoundingBox" descr="Compute mesh bounding box limits">
|
<Overload retVal="BoundingBox" descr="Compute mesh bounding box limits">
|
||||||
<Param name="Mesh mesh" />
|
<Param name="Mesh mesh" />
|
||||||
</Overload>
|
</Overload>
|
||||||
|
|
|
||||||
|
|
@ -2495,7 +2495,7 @@
|
||||||
</KeyWord>
|
</KeyWord>
|
||||||
|
|
||||||
<!-- Mesh manipulation functions -->
|
<!-- Mesh manipulation functions -->
|
||||||
<KeyWord name="MeshBoundingBox" func="yes">
|
<KeyWord name="GetMeshBoundingBox" func="yes">
|
||||||
<Overload retVal="BoundingBox" descr="Compute mesh bounding box limits">
|
<Overload retVal="BoundingBox" descr="Compute mesh bounding box limits">
|
||||||
<Param name="Mesh mesh" />
|
<Param name="Mesh mesh" />
|
||||||
</Overload>
|
</Overload>
|
||||||
|
|
|
||||||
|
|
@ -515,7 +515,7 @@ RLAPI Mesh GenMeshHeightmap(Image heightmap, Vector3 size);
|
||||||
RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data
|
RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data
|
||||||
|
|
||||||
// Mesh manipulation functions
|
// Mesh manipulation functions
|
||||||
RLAPI BoundingBox MeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
|
RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
|
||||||
RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents
|
RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents
|
||||||
RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals
|
RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
// Reconfigure standard input to receive key inputs, works with SSH connection.
|
// Reconfigure standard input to receive key inputs, works with SSH connection.
|
||||||
#define SUPPORT_SSH_KEYBOARD_RPI 1
|
#define SUPPORT_SSH_KEYBOARD_RPI 1
|
||||||
// Draw a mouse pointer on screen
|
// Draw a mouse pointer on screen
|
||||||
#define SUPPORT_MOUSE_CURSOR_NATIVE 1
|
//#define SUPPORT_MOUSE_CURSOR_POINT 1
|
||||||
// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions.
|
// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions.
|
||||||
// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.
|
// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.
|
||||||
#define SUPPORT_WINMM_HIGHRES_TIMER 1
|
#define SUPPORT_WINMM_HIGHRES_TIMER 1
|
||||||
|
|
@ -56,7 +56,11 @@
|
||||||
// Support saving binary data automatically to a generated storage.data file. This file is managed internally.
|
// Support saving binary data automatically to a generated storage.data file. This file is managed internally.
|
||||||
#define SUPPORT_DATA_STORAGE 1
|
#define SUPPORT_DATA_STORAGE 1
|
||||||
// Support automatic generated events, loading and recording of those events when required
|
// Support automatic generated events, loading and recording of those events when required
|
||||||
#define SUPPORT_EVENTS_AUTOMATION 1
|
//#define SUPPORT_EVENTS_AUTOMATION 1
|
||||||
|
// Support custom frame control, only for advance users
|
||||||
|
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timming + PollInputEvents()
|
||||||
|
// Enabling this flag allows manual control of the frame processes, use at your own risk
|
||||||
|
//#define SUPPORT_CUSTOM_FRAME_CONTROL 1
|
||||||
|
|
||||||
// core: Configuration values
|
// core: Configuration values
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
|
@ -161,7 +165,6 @@
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
#define MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions:
|
#define MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions:
|
||||||
// TextFormat(), TextSubtext(), TextToUpper(), TextToLower(), TextToPascal(), TextSplit()
|
// TextFormat(), TextSubtext(), TextToUpper(), TextToLower(), TextToPascal(), TextSplit()
|
||||||
#define MAX_TEXT_UNICODE_CHARS 512 // Maximum number of unicode codepoints: GetCodepoints()
|
|
||||||
#define MAX_TEXTSPLIT_COUNT 128 // Maximum number of substrings to split: TextSplit()
|
#define MAX_TEXTSPLIT_COUNT 128 // Maximum number of substrings to split: TextSplit()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
255
src/core.c
255
src/core.c
|
|
@ -56,7 +56,7 @@
|
||||||
* WARNING: Reconfiguring standard input could lead to undesired effects, like breaking other running processes or
|
* WARNING: Reconfiguring standard input could lead to undesired effects, like breaking other running processes or
|
||||||
* blocking the device is not restored properly. Use with care.
|
* blocking the device is not restored properly. Use with care.
|
||||||
*
|
*
|
||||||
* #define SUPPORT_MOUSE_CURSOR_NATIVE (Raspberry Pi and DRM only)
|
* #define SUPPORT_MOUSE_CURSOR_POINT
|
||||||
* Draw a mouse pointer on screen
|
* Draw a mouse pointer on screen
|
||||||
*
|
*
|
||||||
* #define SUPPORT_BUSY_WAIT_LOOP
|
* #define SUPPORT_BUSY_WAIT_LOOP
|
||||||
|
|
@ -387,7 +387,7 @@ typedef struct CoreData {
|
||||||
Point position; // Window position on screen (required on fullscreen toggle)
|
Point position; // Window position on screen (required on fullscreen toggle)
|
||||||
Size display; // Display width and height (monitor, device-screen, LCD, ...)
|
Size display; // Display width and height (monitor, device-screen, LCD, ...)
|
||||||
Size screen; // Screen width and height (used render area)
|
Size screen; // Screen width and height (used render area)
|
||||||
Size currentFbo; // Current render width and height, it could change on BeginTextureMode()
|
Size currentFbo; // Current render width and height (depends on active fbo)
|
||||||
Size render; // Framebuffer width and height (render area, including black bars if required)
|
Size render; // Framebuffer width and height (render area, including black bars if required)
|
||||||
Point renderOffset; // Offset from render area (must be divided by 2)
|
Point renderOffset; // Offset from render area (must be divided by 2)
|
||||||
Matrix screenScale; // Matrix to scale screen (framebuffer rendering)
|
Matrix screenScale; // Matrix to scale screen (framebuffer rendering)
|
||||||
|
|
@ -599,15 +599,10 @@ extern void UnloadFontDefault(void); // [Module: text] Unloads default fo
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Declaration
|
// Module specific Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
static void InitTimer(void); // Initialize timer (hi-resolution if available)
|
||||||
static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
|
static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
|
||||||
static void SetupFramebuffer(int width, int height); // Setup main framebuffer
|
static void SetupFramebuffer(int width, int height); // Setup main framebuffer
|
||||||
static void SetupViewport(int width, int height); // Set viewport for a provided width and height
|
static void SetupViewport(int width, int height); // Set viewport for a provided width and height
|
||||||
static void SwapBuffers(void); // Copy back buffer to front buffer
|
|
||||||
|
|
||||||
static void InitTimer(void); // Initialize timer
|
|
||||||
static void Wait(float ms); // Wait for some milliseconds (stop program execution)
|
|
||||||
|
|
||||||
static void PollInputEvents(void); // Register user events
|
|
||||||
|
|
||||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||||
static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
|
static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
|
||||||
|
|
@ -636,6 +631,8 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
||||||
#if defined(PLATFORM_WEB)
|
#if defined(PLATFORM_WEB)
|
||||||
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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
|
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
|
||||||
|
|
@ -673,7 +670,7 @@ static void PlayAutomationEvent(unsigned int frame);
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
// NOTE: We include Sleep() function signature here to avoid windows.h inclusion (kernel32 lib)
|
// NOTE: We include Sleep() function signature here to avoid windows.h inclusion (kernel32 lib)
|
||||||
void __stdcall Sleep(unsigned long msTimeout); // Required for Wait()
|
void __stdcall Sleep(unsigned long msTimeout); // Required for WaitTime()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -844,6 +841,9 @@ void InitWindow(int width, int height, const char *title)
|
||||||
// Init hi-res timer
|
// Init hi-res timer
|
||||||
InitTimer();
|
InitTimer();
|
||||||
|
|
||||||
|
// Initialize random seed
|
||||||
|
srand((unsigned int)time(NULL));
|
||||||
|
|
||||||
#if defined(SUPPORT_DEFAULT_FONT)
|
#if defined(SUPPORT_DEFAULT_FONT)
|
||||||
// Load default font
|
// Load default font
|
||||||
// NOTE: External functions (defined in module: text)
|
// NOTE: External functions (defined in module: text)
|
||||||
|
|
@ -875,10 +875,14 @@ void InitWindow(int width, int height, const char *title)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(PLATFORM_WEB)
|
#if defined(PLATFORM_WEB)
|
||||||
// Check fullscreen change events
|
// Check fullscreen change events(note this is done on the window since most
|
||||||
//emscripten_set_fullscreenchange_callback("#canvas", NULL, 1, EmscriptenFullscreenChangeCallback);
|
// browsers don't support this on #canvas)
|
||||||
//emscripten_set_resize_callback("#canvas", NULL, 1, EmscriptenResizeCallback);
|
emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback);
|
||||||
|
// Check Resize event (note this is done on the window since most browsers
|
||||||
|
// don't support this on #canvas)
|
||||||
|
emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 1, EmscriptenResizeCallback);
|
||||||
|
// Trigger this once to get initial window sizing
|
||||||
|
EmscriptenResizeCallback(EMSCRIPTEN_EVENT_RESIZE, NULL, NULL);
|
||||||
// Support keyboard events
|
// Support keyboard events
|
||||||
//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);
|
||||||
|
|
@ -1556,7 +1560,7 @@ void SetWindowMinSize(int width, int height)
|
||||||
// TODO: Issues on HighDPI scaling
|
// TODO: Issues on HighDPI scaling
|
||||||
void SetWindowSize(int width, int height)
|
void SetWindowSize(int width, int height)
|
||||||
{
|
{
|
||||||
#if defined(PLATFORM_DESKTOP)
|
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||||
glfwSetWindowSize(CORE.Window.handle, width, height);
|
glfwSetWindowSize(CORE.Window.handle, width, height);
|
||||||
#endif
|
#endif
|
||||||
#if defined(PLATFORM_WEB)
|
#if defined(PLATFORM_WEB)
|
||||||
|
|
@ -1938,7 +1942,10 @@ void ClearBackground(Color color)
|
||||||
// Setup canvas (framebuffer) to start drawing
|
// Setup canvas (framebuffer) to start drawing
|
||||||
void BeginDrawing(void)
|
void BeginDrawing(void)
|
||||||
{
|
{
|
||||||
CORE.Time.current = GetTime(); // Number of elapsed seconds since InitTimer()
|
// WARNING: Previously to BeginDrawing() other render textures drawing could happen,
|
||||||
|
// consequently the measure for update vs draw is not accurate (only the total frame time is accurate)
|
||||||
|
|
||||||
|
CORE.Time.current = GetTime(); // Number of elapsed seconds since InitTimer()
|
||||||
CORE.Time.update = CORE.Time.current - CORE.Time.previous;
|
CORE.Time.update = CORE.Time.current - CORE.Time.previous;
|
||||||
CORE.Time.previous = CORE.Time.current;
|
CORE.Time.previous = CORE.Time.current;
|
||||||
|
|
||||||
|
|
@ -1952,22 +1959,22 @@ void BeginDrawing(void)
|
||||||
// End canvas drawing and swap buffers (double buffering)
|
// End canvas drawing and swap buffers (double buffering)
|
||||||
void EndDrawing(void)
|
void EndDrawing(void)
|
||||||
{
|
{
|
||||||
#if (defined(PLATFORM_RPI) || defined(PLATFORM_DRM)) && defined(SUPPORT_MOUSE_CURSOR_NATIVE)
|
rlDrawRenderBatchActive(); // Update and draw internal render batch
|
||||||
// On native mode we have no system mouse cursor, so,
|
|
||||||
// we draw a small rectangle for user reference
|
#if defined(SUPPORT_MOUSE_CURSOR_POINT)
|
||||||
|
// Draw a small rectangle on mouse position for user reference
|
||||||
if (!CORE.Input.Mouse.cursorHidden)
|
if (!CORE.Input.Mouse.cursorHidden)
|
||||||
{
|
{
|
||||||
DrawRectangle(CORE.Input.Mouse.currentPosition.x, CORE.Input.Mouse.currentPosition.y, 3, 3, MAROON);
|
DrawRectangle(CORE.Input.Mouse.currentPosition.x, CORE.Input.Mouse.currentPosition.y, 3, 3, MAROON);
|
||||||
|
rlDrawRenderBatchActive(); // Update and draw internal render batch
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rlDrawRenderBatchActive(); // Update and draw internal render batch
|
|
||||||
|
|
||||||
#if defined(SUPPORT_GIF_RECORDING)
|
#if defined(SUPPORT_GIF_RECORDING)
|
||||||
#define GIF_RECORD_FRAMERATE 10
|
// Draw record indicator
|
||||||
|
|
||||||
if (gifRecording)
|
if (gifRecording)
|
||||||
{
|
{
|
||||||
|
#define GIF_RECORD_FRAMERATE 10
|
||||||
gifFramesCounter++;
|
gifFramesCounter++;
|
||||||
|
|
||||||
// NOTE: We record one gif frame every 10 game frames
|
// NOTE: We record one gif frame every 10 game frames
|
||||||
|
|
@ -1992,6 +1999,7 @@ void EndDrawing(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||||
|
// Draw record/play indicator
|
||||||
if (eventsRecording)
|
if (eventsRecording)
|
||||||
{
|
{
|
||||||
gifFramesCounter++;
|
gifFramesCounter++;
|
||||||
|
|
@ -2018,7 +2026,8 @@ void EndDrawing(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SwapBuffers(); // Copy back buffer to front buffer
|
#if !defined(SUPPORT_CUSTOM_FRAME_CONTROL)
|
||||||
|
SwapScreenBuffer(); // Copy back buffer to front buffer (screen)
|
||||||
|
|
||||||
// Frame time control system
|
// Frame time control system
|
||||||
CORE.Time.current = GetTime();
|
CORE.Time.current = GetTime();
|
||||||
|
|
@ -2030,7 +2039,7 @@ void EndDrawing(void)
|
||||||
// Wait for some milliseconds...
|
// Wait for some milliseconds...
|
||||||
if (CORE.Time.frame < CORE.Time.target)
|
if (CORE.Time.frame < CORE.Time.target)
|
||||||
{
|
{
|
||||||
Wait((float)(CORE.Time.target - CORE.Time.frame)*1000.0f);
|
WaitTime((float)(CORE.Time.target - CORE.Time.frame)*1000.0f);
|
||||||
|
|
||||||
CORE.Time.current = GetTime();
|
CORE.Time.current = GetTime();
|
||||||
double waitTime = CORE.Time.current - CORE.Time.previous;
|
double waitTime = CORE.Time.current - CORE.Time.previous;
|
||||||
|
|
@ -2039,14 +2048,15 @@ void EndDrawing(void)
|
||||||
CORE.Time.frame += waitTime; // Total frame time: update + draw + wait
|
CORE.Time.frame += waitTime; // Total frame time: update + draw + wait
|
||||||
}
|
}
|
||||||
|
|
||||||
PollInputEvents(); // Poll user events
|
PollInputEvents(); // Poll user events (before next frame update)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||||
|
// Events recording and playing logic
|
||||||
if (eventsRecording) RecordAutomationEvent(CORE.Time.frameCounter);
|
if (eventsRecording) RecordAutomationEvent(CORE.Time.frameCounter);
|
||||||
|
else if (eventsPlaying)
|
||||||
// TODO: When should we play? After/before/replace PollInputEvents()?
|
|
||||||
if (eventsPlaying)
|
|
||||||
{
|
{
|
||||||
|
// TODO: When should we play? After/before/replace PollInputEvents()?
|
||||||
if (CORE.Time.frameCounter >= eventCount) eventsPlaying = false;
|
if (CORE.Time.frameCounter >= eventCount) eventsPlaying = false;
|
||||||
PlayAutomationEvent(CORE.Time.frameCounter);
|
PlayAutomationEvent(CORE.Time.frameCounter);
|
||||||
}
|
}
|
||||||
|
|
@ -2638,6 +2648,9 @@ void SetTargetFPS(int fps)
|
||||||
// NOTE: We calculate an average framerate
|
// NOTE: We calculate an average framerate
|
||||||
int GetFPS(void)
|
int GetFPS(void)
|
||||||
{
|
{
|
||||||
|
int fps = 0;
|
||||||
|
|
||||||
|
#if !defined(SUPPORT_CUSTOM_FRAME_CONTROL)
|
||||||
#define FPS_CAPTURE_FRAMES_COUNT 30 // 30 captures
|
#define FPS_CAPTURE_FRAMES_COUNT 30 // 30 captures
|
||||||
#define FPS_AVERAGE_TIME_SECONDS 0.5f // 500 millisecondes
|
#define FPS_AVERAGE_TIME_SECONDS 0.5f // 500 millisecondes
|
||||||
#define FPS_STEP (FPS_AVERAGE_TIME_SECONDS/FPS_CAPTURE_FRAMES_COUNT)
|
#define FPS_STEP (FPS_AVERAGE_TIME_SECONDS/FPS_CAPTURE_FRAMES_COUNT)
|
||||||
|
|
@ -2658,7 +2671,10 @@ int GetFPS(void)
|
||||||
average += history[index];
|
average += history[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)roundf(1.0f/average);
|
fps = (int)roundf(1.0f/average);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get time in seconds for last frame drawn (delta time)
|
// Get time in seconds for last frame drawn (delta time)
|
||||||
|
|
@ -3540,6 +3556,17 @@ Vector2 GetMousePosition(void)
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get mouse delta between frames
|
||||||
|
Vector2 GetMouseDelta(void)
|
||||||
|
{
|
||||||
|
Vector2 delta = {0};
|
||||||
|
|
||||||
|
delta.x = CORE.Input.Mouse.currentPosition.x - CORE.Input.Mouse.previousPosition.x;
|
||||||
|
delta.y = CORE.Input.Mouse.currentPosition.y - CORE.Input.Mouse.previousPosition.y;
|
||||||
|
|
||||||
|
return delta;
|
||||||
|
}
|
||||||
|
|
||||||
// Set mouse position XY
|
// Set mouse position XY
|
||||||
void SetMousePosition(int x, int y)
|
void SetMousePosition(int x, int y)
|
||||||
{
|
{
|
||||||
|
|
@ -4661,8 +4688,6 @@ static void SetupFramebuffer(int width, int height)
|
||||||
// Initialize hi-resolution timer
|
// Initialize hi-resolution timer
|
||||||
static void InitTimer(void)
|
static void InitTimer(void)
|
||||||
{
|
{
|
||||||
srand((unsigned int)time(NULL)); // Initialize random seed
|
|
||||||
|
|
||||||
// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions.
|
// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions.
|
||||||
// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.
|
// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.
|
||||||
// High resolutions can also prevent the CPU power management system from entering power-saving modes.
|
// High resolutions can also prevent the CPU power management system from entering power-saving modes.
|
||||||
|
|
@ -4689,7 +4714,7 @@ static void InitTimer(void)
|
||||||
// take longer than expected... for that reason we use the busy wait loop
|
// take longer than expected... for that reason we use the busy wait loop
|
||||||
// Ref: http://stackoverflow.com/questions/43057578/c-programming-win32-games-sleep-taking-longer-than-expected
|
// Ref: http://stackoverflow.com/questions/43057578/c-programming-win32-games-sleep-taking-longer-than-expected
|
||||||
// Ref: http://www.geisswerks.com/ryan/FAQS/timing.html --> All about timming on Win32!
|
// Ref: http://www.geisswerks.com/ryan/FAQS/timing.html --> All about timming on Win32!
|
||||||
static void Wait(float ms)
|
void WaitTime(float ms)
|
||||||
{
|
{
|
||||||
#if defined(PLATFORM_UWP)
|
#if defined(PLATFORM_UWP)
|
||||||
UWPGetSleepFunc()(ms/1000);
|
UWPGetSleepFunc()(ms/1000);
|
||||||
|
|
@ -4737,8 +4762,70 @@ static void Wait(float ms)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Poll (store) all input events
|
// Swap back buffer with front buffer (screen drawing)
|
||||||
static void PollInputEvents(void)
|
void SwapScreenBuffer(void)
|
||||||
|
{
|
||||||
|
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||||
|
glfwSwapBuffers(CORE.Window.handle);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) || defined(PLATFORM_UWP)
|
||||||
|
eglSwapBuffers(CORE.Window.device, CORE.Window.surface);
|
||||||
|
|
||||||
|
#if defined(PLATFORM_DRM)
|
||||||
|
if (!CORE.Window.gbmSurface || (-1 == CORE.Window.fd) || !CORE.Window.connector || !CORE.Window.crtc)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gbm_bo *bo = gbm_surface_lock_front_buffer(CORE.Window.gbmSurface);
|
||||||
|
if (!bo)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_ERROR, "DISPLAY: Failed GBM to lock front buffer");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fb = 0;
|
||||||
|
int result = drmModeAddFB(CORE.Window.fd, CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay,
|
||||||
|
CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay, 24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &fb);
|
||||||
|
if (0 != result)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d", result);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
result = drmModeSetCrtc(CORE.Window.fd, CORE.Window.crtc->crtc_id, fb, 0, 0,
|
||||||
|
&CORE.Window.connector->connector_id, 1, &CORE.Window.connector->modes[CORE.Window.modeIndex]);
|
||||||
|
if (0 != result)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d", result);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CORE.Window.prevFB)
|
||||||
|
{
|
||||||
|
result = drmModeRmFB(CORE.Window.fd, CORE.Window.prevFB);
|
||||||
|
if (0 != result)
|
||||||
|
{
|
||||||
|
TRACELOG(LOG_ERROR, "DISPLAY: drmModeRmFB() failed with result: %d", result);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CORE.Window.prevFB = fb;
|
||||||
|
|
||||||
|
if (CORE.Window.prevBO)
|
||||||
|
{
|
||||||
|
gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO);
|
||||||
|
}
|
||||||
|
|
||||||
|
CORE.Window.prevBO = bo;
|
||||||
|
#endif // PLATFORM_DRM
|
||||||
|
#endif // PLATFORM_ANDROID || PLATFORM_RPI || PLATFORM_DRM || PLATFORM_UWP
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register all input events
|
||||||
|
void PollInputEvents(void)
|
||||||
{
|
{
|
||||||
#if defined(SUPPORT_GESTURES_SYSTEM)
|
#if defined(SUPPORT_GESTURES_SYSTEM)
|
||||||
// NOTE: Gestures update must be called every frame to reset gestures correctly
|
// NOTE: Gestures update must be called every frame to reset gestures correctly
|
||||||
|
|
@ -5014,68 +5101,6 @@ static void PollInputEvents(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy back buffer to front buffers
|
|
||||||
static void SwapBuffers(void)
|
|
||||||
{
|
|
||||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
|
||||||
glfwSwapBuffers(CORE.Window.handle);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM) || defined(PLATFORM_UWP)
|
|
||||||
eglSwapBuffers(CORE.Window.device, CORE.Window.surface);
|
|
||||||
|
|
||||||
#if defined(PLATFORM_DRM)
|
|
||||||
if (!CORE.Window.gbmSurface || (-1 == CORE.Window.fd) || !CORE.Window.connector || !CORE.Window.crtc)
|
|
||||||
{
|
|
||||||
TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gbm_bo *bo = gbm_surface_lock_front_buffer(CORE.Window.gbmSurface);
|
|
||||||
if (!bo)
|
|
||||||
{
|
|
||||||
TRACELOG(LOG_ERROR, "DISPLAY: Failed GBM to lock front buffer");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t fb = 0;
|
|
||||||
int result = drmModeAddFB(CORE.Window.fd, CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay,
|
|
||||||
CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay, 24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &fb);
|
|
||||||
if (0 != result)
|
|
||||||
{
|
|
||||||
TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d", result);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
result = drmModeSetCrtc(CORE.Window.fd, CORE.Window.crtc->crtc_id, fb, 0, 0,
|
|
||||||
&CORE.Window.connector->connector_id, 1, &CORE.Window.connector->modes[CORE.Window.modeIndex]);
|
|
||||||
if (0 != result)
|
|
||||||
{
|
|
||||||
TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d", result);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CORE.Window.prevFB)
|
|
||||||
{
|
|
||||||
result = drmModeRmFB(CORE.Window.fd, CORE.Window.prevFB);
|
|
||||||
if (0 != result)
|
|
||||||
{
|
|
||||||
TRACELOG(LOG_ERROR, "DISPLAY: drmModeRmFB() failed with result: %d", result);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CORE.Window.prevFB = fb;
|
|
||||||
|
|
||||||
if (CORE.Window.prevBO)
|
|
||||||
{
|
|
||||||
gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO);
|
|
||||||
}
|
|
||||||
|
|
||||||
CORE.Window.prevBO = bo;
|
|
||||||
#endif // PLATFORM_DRM
|
|
||||||
#endif // PLATFORM_ANDROID || PLATFORM_RPI || PLATFORM_DRM || PLATFORM_UWP
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||||
// GLFW3 Error Callback, runs on GLFW3 error
|
// GLFW3 Error Callback, runs on GLFW3 error
|
||||||
static void ErrorCallback(int error, const char *description)
|
static void ErrorCallback(int error, const char *description)
|
||||||
|
|
@ -5083,6 +5108,36 @@ static void ErrorCallback(int error, const char *description)
|
||||||
TRACELOG(LOG_WARNING, "GLFW: Error: %i Description: %s", error, description);
|
TRACELOG(LOG_WARNING, "GLFW: Error: %i Description: %s", error, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(PLATFORM_WEB)
|
||||||
|
EM_JS(int, GetCanvasWidth, (), { return canvas.clientWidth; });
|
||||||
|
EM_JS(int, GetCanvasHeight, (), { return canvas.clientHeight; });
|
||||||
|
|
||||||
|
static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *e, void *userData)
|
||||||
|
{
|
||||||
|
// Don't resize non-resizeable windows
|
||||||
|
if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) == 0) return true;
|
||||||
|
|
||||||
|
// This event is called whenever the window changes sizes,
|
||||||
|
// so the size of the canvas object is explicitly retrieved below
|
||||||
|
int width = GetCanvasWidth();
|
||||||
|
int height = GetCanvasHeight();
|
||||||
|
emscripten_set_canvas_element_size("#canvas",width,height);
|
||||||
|
|
||||||
|
SetupViewport(width, height); // Reset viewport and projection matrix for new size
|
||||||
|
|
||||||
|
CORE.Window.currentFbo.width = width;
|
||||||
|
CORE.Window.currentFbo.height = height;
|
||||||
|
CORE.Window.resizedLastFrame = true;
|
||||||
|
|
||||||
|
if (IsWindowFullscreen()) return true;
|
||||||
|
|
||||||
|
// Set current screen size
|
||||||
|
CORE.Window.screen.width = width;
|
||||||
|
CORE.Window.screen.height = height;
|
||||||
|
|
||||||
|
// NOTE: Postprocessing texture is not scaled to new size
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// GLFW3 WindowSize Callback, runs when window is resizedLastFrame
|
// GLFW3 WindowSize Callback, runs when window is resizedLastFrame
|
||||||
// NOTE: Window resizing not allowed by default
|
// NOTE: Window resizing not allowed by default
|
||||||
|
|
@ -5375,6 +5430,9 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
||||||
// Init hi-res timer
|
// Init hi-res timer
|
||||||
InitTimer();
|
InitTimer();
|
||||||
|
|
||||||
|
// Initialize random seed
|
||||||
|
srand((unsigned int)time(NULL));
|
||||||
|
|
||||||
#if defined(SUPPORT_DEFAULT_FONT)
|
#if defined(SUPPORT_DEFAULT_FONT)
|
||||||
// Load default font
|
// Load default font
|
||||||
// NOTE: External function (defined in module: text)
|
// NOTE: External function (defined in module: text)
|
||||||
|
|
@ -6327,7 +6385,8 @@ static void *EventThread(void *arg)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Wait(5); // Sleep for 5ms to avoid hogging CPU time
|
|
||||||
|
WaitTime(5); // Sleep for 5ms to avoid hogging CPU time
|
||||||
}
|
}
|
||||||
|
|
||||||
close(worker->fd);
|
close(worker->fd);
|
||||||
|
|
@ -6415,7 +6474,7 @@ static void *GamepadThread(void *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else Wait(1); // Sleep for 1 ms to avoid hogging CPU time
|
else WaitTime(1); // Sleep for 1 ms to avoid hogging CPU time
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
2
src/external/tinyobj_loader_c.h
vendored
2
src/external/tinyobj_loader_c.h
vendored
|
|
@ -948,6 +948,8 @@ static int tinyobj_parse_and_index_mtl_file(tinyobj_material_t **materials_out,
|
||||||
/* @todo { unknown parameter } */
|
/* @todo { unknown parameter } */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
if (material.name) {
|
if (material.name) {
|
||||||
/* Flush last material element */
|
/* Flush last material element */
|
||||||
materials = tinyobj_material_add(materials, num_materials, &material);
|
materials = tinyobj_material_add(materials, num_materials, &material);
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,7 @@ static unsigned int usedMemory = 0; // Total allocated d
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
|
#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
|
||||||
// Timming measure functions
|
// Timming measure functions
|
||||||
static void InitTimer(void); // Initializes hi-resolution MONOTONIC timer
|
static void InitTimerHiRes(void); // Initializes hi-resolution MONOTONIC timer
|
||||||
static unsigned long long int GetClockTicks(void); // Get hi-res MONOTONIC time measure in mseconds
|
static unsigned long long int GetClockTicks(void); // Get hi-res MONOTONIC time measure in mseconds
|
||||||
static double GetCurrentTime(void); // Get current time measure in milliseconds
|
static double GetCurrentTime(void); // Get current time measure in milliseconds
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -370,7 +370,7 @@ PHYSACDEF void InitPhysics(void)
|
||||||
{
|
{
|
||||||
#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
|
#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
|
||||||
// Initialize high resolution timer
|
// Initialize high resolution timer
|
||||||
InitTimer();
|
InitTimerHiRes();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TRACELOG("[PHYSAC] Physics module initialized successfully\n");
|
TRACELOG("[PHYSAC] Physics module initialized successfully\n");
|
||||||
|
|
@ -1848,7 +1848,7 @@ static Vector2 MathTriangleBarycenter(Vector2 v1, Vector2 v2, Vector2 v3)
|
||||||
|
|
||||||
#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
|
#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
|
||||||
// Initializes hi-resolution MONOTONIC timer
|
// Initializes hi-resolution MONOTONIC timer
|
||||||
static void InitTimer(void)
|
static void InitTimerHiRes(void)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
QueryPerformanceFrequency((unsigned long long int *) &frequency);
|
QueryPerformanceFrequency((unsigned long long int *) &frequency);
|
||||||
|
|
|
||||||
10
src/models.c
10
src/models.c
|
|
@ -1105,10 +1105,6 @@ void DrawMeshInstanced(Mesh mesh, Material material, Matrix *transforms, int ins
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0);
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
|
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
|
||||||
|
|
||||||
rlEnableVertexBuffer(mesh.vboId[0]);
|
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION], 3, RL_FLOAT, 0, 0, 0);
|
|
||||||
rlEnableVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_POSITION]);
|
|
||||||
|
|
||||||
// Bind mesh VBO data: vertex texcoords (shader-location = 1)
|
// Bind mesh VBO data: vertex texcoords (shader-location = 1)
|
||||||
rlEnableVertexBuffer(mesh.vboId[1]);
|
rlEnableVertexBuffer(mesh.vboId[1]);
|
||||||
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, RL_FLOAT, 0, 0, 0);
|
rlSetVertexAttribute(material.shader.locs[SHADER_LOC_VERTEX_TEXCOORD01], 2, RL_FLOAT, 0, 0, 0);
|
||||||
|
|
@ -2652,7 +2648,7 @@ BoundingBox GetMeshBoundingBox(Mesh mesh)
|
||||||
// Compute mesh tangents
|
// Compute mesh tangents
|
||||||
// NOTE: To calculate mesh tangents and binormals we need mesh vertex positions and texture coordinates
|
// NOTE: To calculate mesh tangents and binormals we need mesh vertex positions and texture coordinates
|
||||||
// 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 MeshTangents(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 TRACELOG(LOG_WARNING, "MESH: Tangents data already available, re-writting");
|
else TRACELOG(LOG_WARNING, "MESH: Tangents data already available, re-writting");
|
||||||
|
|
@ -2732,7 +2728,7 @@ void MeshTangents(Mesh *mesh)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute mesh binormals (aka bitangent)
|
// Compute mesh binormals (aka bitangent)
|
||||||
void MeshBinormals(Mesh *mesh)
|
void GenMeshBinormals(Mesh *mesh)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < mesh->vertexCount; i++)
|
for (int i = 0; i < mesh->vertexCount; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -4996,7 +4992,7 @@ static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCo
|
||||||
// output->framerate = // TODO: Use framerate instead of const timestep
|
// output->framerate = // TODO: Use framerate instead of const timestep
|
||||||
|
|
||||||
// Name and parent bones
|
// Name and parent bones
|
||||||
for (unsigned int j = 0; j < output->boneCount; j++)
|
for (int j = 0; j < output->boneCount; j++)
|
||||||
{
|
{
|
||||||
strcpy(output->bones[j].name, data->nodes[j].name == 0 ? "ANIMJOINT" : data->nodes[j].name);
|
strcpy(output->bones[j].name, data->nodes[j].name == 0 ? "ANIMJOINT" : data->nodes[j].name);
|
||||||
output->bones[j].parent = (data->nodes[j].parent != NULL) ? (int)(data->nodes[j].parent - data->nodes) : -1;
|
output->bones[j].parent = (data->nodes[j].parent != NULL) ? (int)(data->nodes[j].parent - data->nodes) : -1;
|
||||||
|
|
|
||||||
18
src/raylib.h
18
src/raylib.h
|
|
@ -960,6 +960,14 @@ RLAPI const char *GetMonitorName(int monitor); // Get the hum
|
||||||
RLAPI void SetClipboardText(const char *text); // Set clipboard text content
|
RLAPI void SetClipboardText(const char *text); // Set clipboard text content
|
||||||
RLAPI const char *GetClipboardText(void); // Get clipboard text content
|
RLAPI const char *GetClipboardText(void); // Get clipboard text content
|
||||||
|
|
||||||
|
// Custom frame control functions
|
||||||
|
// NOTE: Those functions are intended for advance users that want full control over the frame processing
|
||||||
|
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timming + PollInputEvents()
|
||||||
|
// To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL
|
||||||
|
RLAPI void SwapScreenBuffer(void); // Swap back buffer with front buffer (screen drawing)
|
||||||
|
RLAPI void PollInputEvents(void); // Register all input events
|
||||||
|
RLAPI void WaitTime(float ms); // Wait for some milliseconds (halt program execution)
|
||||||
|
|
||||||
// Cursor-related functions
|
// Cursor-related functions
|
||||||
RLAPI void ShowCursor(void); // Shows cursor
|
RLAPI void ShowCursor(void); // Shows cursor
|
||||||
RLAPI void HideCursor(void); // Hides cursor
|
RLAPI void HideCursor(void); // Hides cursor
|
||||||
|
|
@ -1104,6 +1112,7 @@ RLAPI bool IsMouseButtonUp(int button); // Check if a mous
|
||||||
RLAPI int GetMouseX(void); // Get mouse position X
|
RLAPI int GetMouseX(void); // Get mouse position X
|
||||||
RLAPI int GetMouseY(void); // Get mouse position Y
|
RLAPI int GetMouseY(void); // Get mouse position Y
|
||||||
RLAPI Vector2 GetMousePosition(void); // Get mouse position XY
|
RLAPI Vector2 GetMousePosition(void); // Get mouse position XY
|
||||||
|
RLAPI Vector2 GetMouseDelta(void); // Get mouse delta between frames
|
||||||
RLAPI void SetMousePosition(int x, int y); // Set mouse position XY
|
RLAPI void SetMousePosition(int x, int y); // Set mouse position XY
|
||||||
RLAPI void SetMouseOffset(int offsetX, int offsetY); // Set mouse offset
|
RLAPI void SetMouseOffset(int offsetX, int offsetY); // Set mouse offset
|
||||||
RLAPI void SetMouseScale(float scaleX, float scaleY); // Set mouse scaling
|
RLAPI void SetMouseScale(float scaleX, float scaleY); // Set mouse scaling
|
||||||
|
|
@ -1360,9 +1369,10 @@ RLAPI int TextToInteger(const char *text); // Get int
|
||||||
RLAPI char *TextToUtf8(int *codepoints, int length); // Encode text codepoint into utf8 text (memory must be freed!)
|
RLAPI char *TextToUtf8(int *codepoints, int length); // Encode text codepoint into utf8 text (memory must be freed!)
|
||||||
|
|
||||||
// UTF8 text strings management functions
|
// UTF8 text strings management functions
|
||||||
RLAPI int *GetCodepoints(const char *text, int *count); // Get all codepoints in a string, codepoints count returned by parameters
|
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 GetCodepointsCount(const char *text); // Get total number of characters (codepoints) in a UTF8 encoded string
|
||||||
RLAPI int GetNextCodepoint(const char *text, int *bytesProcessed); // Get next codepoint in a UTF8 encoded string; 0x3f('?') is returned on failure
|
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)
|
RLAPI const char *CodepointToUtf8(int codepoint, int *byteLength); // Encode codepoint into utf8 text (char array length returned as parameter)
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
|
@ -1435,8 +1445,8 @@ RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
|
||||||
|
|
||||||
// Mesh manipulation functions
|
// Mesh manipulation functions
|
||||||
RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
|
RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
|
||||||
RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents
|
RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents
|
||||||
RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals
|
RLAPI void GenMeshBinormals(Mesh *mesh); // Compute mesh binormals
|
||||||
|
|
||||||
// Model drawing functions
|
// Model drawing functions
|
||||||
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
|
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@
|
||||||
typedef struct float3 { float v[3]; } float3;
|
typedef struct float3 { float v[3]; } float3;
|
||||||
typedef struct float16 { float v[16]; } float16;
|
typedef struct float16 { float v[16]; } float16;
|
||||||
|
|
||||||
#include <math.h> // Required for: sinf(), cosf(), sqrtf(), tan(), fabs()
|
#include <math.h> // Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), fminf(), fmaxf(), fabs()
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Functions Definition - Utils math
|
// Module Functions Definition - Utils math
|
||||||
|
|
|
||||||
74
src/rlgl.h
74
src/rlgl.h
|
|
@ -297,14 +297,6 @@ typedef struct RenderBatch {
|
||||||
typedef enum { false, true } bool;
|
typedef enum { false, true } bool;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Color, 4 components, R8G8B8A8 (32bit)
|
|
||||||
typedef struct Color {
|
|
||||||
unsigned char r; // Color red value
|
|
||||||
unsigned char g; // Color green value
|
|
||||||
unsigned char b; // Color blue value
|
|
||||||
unsigned char a; // Color alpha value
|
|
||||||
} Color;
|
|
||||||
|
|
||||||
// Texture type
|
// Texture type
|
||||||
// NOTE: Data stored in GPU memory
|
// NOTE: Data stored in GPU memory
|
||||||
typedef struct Texture2D {
|
typedef struct Texture2D {
|
||||||
|
|
@ -880,8 +872,8 @@ static char *rlGetCompressedFormatName(int format); // Get compressed format off
|
||||||
#endif // SUPPORT_GL_DETAILS_INFO
|
#endif // SUPPORT_GL_DETAILS_INFO
|
||||||
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
||||||
#if defined(GRAPHICS_API_OPENGL_11)
|
#if defined(GRAPHICS_API_OPENGL_11)
|
||||||
static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHeight); // Generate mipmaps data on CPU side
|
static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHeight); // Generate mipmaps data on CPU side
|
||||||
static Color *rlGenNextMipmapData(Color *srcData, int srcWidth, int srcHeight); // Generate next mipmap level on CPU side
|
static unsigned char *rlGenNextMipmapData(unsigned char *srcData, int srcWidth, int srcHeight); // Generate next mipmap level on CPU side
|
||||||
#endif
|
#endif
|
||||||
static int rlGetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture)
|
static int rlGetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture)
|
||||||
|
|
||||||
|
|
@ -3957,22 +3949,20 @@ static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHei
|
||||||
|
|
||||||
width = baseWidth;
|
width = baseWidth;
|
||||||
height = baseHeight;
|
height = baseHeight;
|
||||||
size = (width*height*4);
|
size = (width*height*4); // RGBA: 4 bytes
|
||||||
|
|
||||||
// Generate mipmaps
|
// Generate mipmaps
|
||||||
// NOTE: Every mipmap data is stored after data
|
// NOTE: Every mipmap data is stored after data (RGBA - 4 bytes)
|
||||||
Color *image = (Color *)RL_MALLOC(width*height*sizeof(Color));
|
unsigned char *image = (unsigned char *)RL_MALLOC(width*height*4);
|
||||||
Color *mipmap = NULL;
|
unsigned char *mipmap = NULL;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int j = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < size; i += 4)
|
for (int i = 0; i < size; i += 4)
|
||||||
{
|
{
|
||||||
image[j].r = data[i];
|
image[i] = data[i];
|
||||||
image[j].g = data[i + 1];
|
image[i + 1] = data[i + 1];
|
||||||
image[j].b = data[i + 2];
|
image[i + 2] = data[i + 2];
|
||||||
image[j].a = data[i + 3];
|
image[i + 3] = data[i + 3];
|
||||||
j++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACELOGD("TEXTURE: Mipmap base size (%ix%i)", width, height);
|
TRACELOGD("TEXTURE: Mipmap base size (%ix%i)", width, height);
|
||||||
|
|
@ -3982,7 +3972,6 @@ static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHei
|
||||||
mipmap = rlGenNextMipmapData(image, width, height);
|
mipmap = rlGenNextMipmapData(image, width, height);
|
||||||
|
|
||||||
offset += (width*height*4); // Size of last mipmap
|
offset += (width*height*4); // Size of last mipmap
|
||||||
j = 0;
|
|
||||||
|
|
||||||
width /= 2;
|
width /= 2;
|
||||||
height /= 2;
|
height /= 2;
|
||||||
|
|
@ -3991,11 +3980,10 @@ static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHei
|
||||||
// Add mipmap to data
|
// Add mipmap to data
|
||||||
for (int i = 0; i < size; i += 4)
|
for (int i = 0; i < size; i += 4)
|
||||||
{
|
{
|
||||||
data[offset + i] = mipmap[j].r;
|
data[offset + i] = mipmap[i];
|
||||||
data[offset + i + 1] = mipmap[j].g;
|
data[offset + i + 1] = mipmap[i + 1];
|
||||||
data[offset + i + 2] = mipmap[j].b;
|
data[offset + i + 2] = mipmap[i + 2];
|
||||||
data[offset + i + 3] = mipmap[j].a;
|
data[offset + i + 3] = mipmap[i + 3];
|
||||||
j++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RL_FREE(image);
|
RL_FREE(image);
|
||||||
|
|
@ -4010,15 +3998,17 @@ static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHei
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manual mipmap generation (basic scaling algorithm)
|
// Manual mipmap generation (basic scaling algorithm)
|
||||||
static Color *rlGenNextMipmapData(Color *srcData, int srcWidth, int srcHeight)
|
static unsigned char *rlGenNextMipmapData(unsigned char *srcData, int srcWidth, int srcHeight)
|
||||||
{
|
{
|
||||||
int x2, y2;
|
int x2 = 0;
|
||||||
Color prow, pcol;
|
int y2 = 0;
|
||||||
|
unsigned char prow[4];
|
||||||
|
unsigned char pcol[4];
|
||||||
|
|
||||||
int width = srcWidth/2;
|
int width = srcWidth/2;
|
||||||
int height = srcHeight/2;
|
int height = srcHeight/2;
|
||||||
|
|
||||||
Color *mipmap = (Color *)RL_MALLOC(width*height*sizeof(Color));
|
unsigned char *mipmap = (unsigned char *)RL_MALLOC(width*height*4);
|
||||||
|
|
||||||
// Scaling algorithm works perfectly (box-filter)
|
// Scaling algorithm works perfectly (box-filter)
|
||||||
for (int y = 0; y < height; y++)
|
for (int y = 0; y < height; y++)
|
||||||
|
|
@ -4029,20 +4019,20 @@ static Color *rlGenNextMipmapData(Color *srcData, int srcWidth, int srcHeight)
|
||||||
{
|
{
|
||||||
x2 = 2*x;
|
x2 = 2*x;
|
||||||
|
|
||||||
prow.r = (srcData[y2*srcWidth + x2].r + srcData[y2*srcWidth + x2 + 1].r)/2;
|
prow[0] = (srcData[(y2*srcWidth + x2)*4 + 0] + srcData[(y2*srcWidth + x2 + 1)*4 + 0])/2;
|
||||||
prow.g = (srcData[y2*srcWidth + x2].g + srcData[y2*srcWidth + x2 + 1].g)/2;
|
prow[1] = (srcData[(y2*srcWidth + x2)*4 + 1] + srcData[(y2*srcWidth + x2 + 1)*4 + 1])/2;
|
||||||
prow.b = (srcData[y2*srcWidth + x2].b + srcData[y2*srcWidth + x2 + 1].b)/2;
|
prow[2] = (srcData[(y2*srcWidth + x2)*4 + 2] + srcData[(y2*srcWidth + x2 + 1)*4 + 2])/2;
|
||||||
prow.a = (srcData[y2*srcWidth + x2].a + srcData[y2*srcWidth + x2 + 1].a)/2;
|
prow[3] = (srcData[(y2*srcWidth + x2)*4 + 3] + srcData[(y2*srcWidth + x2 + 1)*4 + 3])/2;
|
||||||
|
|
||||||
pcol.r = (srcData[(y2+1)*srcWidth + x2].r + srcData[(y2+1)*srcWidth + x2 + 1].r)/2;
|
pcol[0] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 0] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 0])/2;
|
||||||
pcol.g = (srcData[(y2+1)*srcWidth + x2].g + srcData[(y2+1)*srcWidth + x2 + 1].g)/2;
|
pcol[1] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 1] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 1])/2;
|
||||||
pcol.b = (srcData[(y2+1)*srcWidth + x2].b + srcData[(y2+1)*srcWidth + x2 + 1].b)/2;
|
pcol[2] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 2] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 2])/2;
|
||||||
pcol.a = (srcData[(y2+1)*srcWidth + x2].a + srcData[(y2+1)*srcWidth + x2 + 1].a)/2;
|
pcol[3] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 3] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 3])/2;
|
||||||
|
|
||||||
mipmap[y*width + x].r = (prow.r + pcol.r)/2;
|
mipmap[(y*width + x)*4 + 0] = (prow[0] + pcol[0])/2;
|
||||||
mipmap[y*width + x].g = (prow.g + pcol.g)/2;
|
mipmap[(y*width + x)*4 + 1] = (prow[1] + pcol[1])/2;
|
||||||
mipmap[y*width + x].b = (prow.b + pcol.b)/2;
|
mipmap[(y*width + x)*4 + 2] = (prow[2] + pcol[2])/2;
|
||||||
mipmap[y*width + x].a = (prow.a + pcol.a)/2;
|
mipmap[(y*width + x)*4 + 3] = (prow[3] + pcol[3])/2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
61
src/text.c
61
src/text.c
|
|
@ -861,7 +861,7 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f
|
||||||
{
|
{
|
||||||
// Get next codepoint from byte string and glyph index in font
|
// Get next codepoint from byte string and glyph index in font
|
||||||
int codepointByteCount = 0;
|
int codepointByteCount = 0;
|
||||||
int codepoint = GetNextCodepoint(&text[i], &codepointByteCount);
|
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
||||||
int index = GetGlyphIndex(font, codepoint);
|
int index = GetGlyphIndex(font, codepoint);
|
||||||
|
|
||||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||||
|
|
@ -901,10 +901,10 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
|
||||||
{
|
{
|
||||||
int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop
|
int length = TextLength(text); // Total length in bytes of the text, scanned by codepoints in loop
|
||||||
|
|
||||||
int textOffsetY = 0; // Offset between lines (on line break '\n')
|
float textOffsetY = 0; // Offset between lines (on line break '\n')
|
||||||
float textOffsetX = 0.0f; // Offset X to next character to draw
|
float textOffsetX = 0.0f; // Offset X to next character to draw
|
||||||
|
|
||||||
float scaleFactor = fontSize/font.baseSize; // Character quad scaling factor
|
float scaleFactor = fontSize/(float)font.baseSize; // Character quad scaling factor
|
||||||
|
|
||||||
// Word/character wrapping mechanism variables
|
// Word/character wrapping mechanism variables
|
||||||
enum { MEASURE_STATE = 0, DRAW_STATE = 1 };
|
enum { MEASURE_STATE = 0, DRAW_STATE = 1 };
|
||||||
|
|
@ -918,7 +918,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
|
||||||
{
|
{
|
||||||
// Get next codepoint from byte string and glyph index in font
|
// Get next codepoint from byte string and glyph index in font
|
||||||
int codepointByteCount = 0;
|
int codepointByteCount = 0;
|
||||||
int codepoint = GetNextCodepoint(&text[i], &codepointByteCount);
|
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
||||||
int index = GetGlyphIndex(font, codepoint);
|
int index = GetGlyphIndex(font, codepoint);
|
||||||
|
|
||||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||||
|
|
@ -926,12 +926,12 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
|
||||||
if (codepoint == 0x3f) codepointByteCount = 1;
|
if (codepoint == 0x3f) codepointByteCount = 1;
|
||||||
i += (codepointByteCount - 1);
|
i += (codepointByteCount - 1);
|
||||||
|
|
||||||
int glyphWidth = 0;
|
float glyphWidth = 0;
|
||||||
if (codepoint != '\n')
|
if (codepoint != '\n')
|
||||||
{
|
{
|
||||||
glyphWidth = (font.chars[index].advanceX == 0)?
|
glyphWidth = (font.chars[index].advanceX == 0) ? font.recs[index].width*scaleFactor : font.chars[index].advanceX*scaleFactor;
|
||||||
(int)(font.recs[index].width*scaleFactor + spacing):
|
|
||||||
(int)(font.chars[index].advanceX*scaleFactor + spacing);
|
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
|
// NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside of the rec container
|
||||||
|
|
@ -945,7 +945,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
|
||||||
// Ref: http://jkorpela.fi/chars/spaces.html
|
// Ref: http://jkorpela.fi/chars/spaces.html
|
||||||
if ((codepoint == ' ') || (codepoint == '\t') || (codepoint == '\n')) endLine = i;
|
if ((codepoint == ' ') || (codepoint == '\t') || (codepoint == '\n')) endLine = i;
|
||||||
|
|
||||||
if ((textOffsetX + glyphWidth + 1) >= rec.width)
|
if ((textOffsetX + glyphWidth) > rec.width)
|
||||||
{
|
{
|
||||||
endLine = (endLine < 1)? i : endLine;
|
endLine = (endLine < 1)? i : endLine;
|
||||||
if (i == endLine) endLine -= codepointByteCount;
|
if (i == endLine) endLine -= codepointByteCount;
|
||||||
|
|
@ -956,7 +956,6 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
|
||||||
else if ((i + 1) == length)
|
else if ((i + 1) == length)
|
||||||
{
|
{
|
||||||
endLine = i;
|
endLine = i;
|
||||||
|
|
||||||
state = !state;
|
state = !state;
|
||||||
}
|
}
|
||||||
else if (codepoint == '\n') state = !state;
|
else if (codepoint == '\n') state = !state;
|
||||||
|
|
@ -979,26 +978,26 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
|
||||||
{
|
{
|
||||||
if (!wordWrap)
|
if (!wordWrap)
|
||||||
{
|
{
|
||||||
textOffsetY += (int)((font.baseSize + font.baseSize/2)*scaleFactor);
|
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
||||||
textOffsetX = 0;
|
textOffsetX = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!wordWrap && ((textOffsetX + glyphWidth + 1) >= rec.width))
|
if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width))
|
||||||
{
|
{
|
||||||
textOffsetY += (int)((font.baseSize + font.baseSize/2)*scaleFactor);
|
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
||||||
textOffsetX = 0;
|
textOffsetX = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When text overflows rectangle height limit, just stop drawing
|
// When text overflows rectangle height limit, just stop drawing
|
||||||
if ((textOffsetY + (int)(font.baseSize*scaleFactor)) > rec.height) break;
|
if ((textOffsetY + font.baseSize*scaleFactor) > rec.height) break;
|
||||||
|
|
||||||
// Draw selection background
|
// Draw selection background
|
||||||
bool isGlyphSelected = false;
|
bool isGlyphSelected = false;
|
||||||
if ((selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength)))
|
if ((selectStart >= 0) && (k >= selectStart) && (k < (selectStart + selectLength)))
|
||||||
{
|
{
|
||||||
DrawRectangleRec((Rectangle){ rec.x + textOffsetX - 1, rec.y + textOffsetY, (float)glyphWidth, (float)font.baseSize*scaleFactor }, selectBackTint);
|
DrawRectangleRec((Rectangle){ rec.x + textOffsetX - 1, rec.y + textOffsetY, glyphWidth, (float)font.baseSize*scaleFactor }, selectBackTint);
|
||||||
isGlyphSelected = true;
|
isGlyphSelected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1011,7 +1010,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
|
||||||
|
|
||||||
if (wordWrap && (i == endLine))
|
if (wordWrap && (i == endLine))
|
||||||
{
|
{
|
||||||
textOffsetY += (int)((font.baseSize + font.baseSize/2)*scaleFactor);
|
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
||||||
textOffsetX = 0;
|
textOffsetX = 0;
|
||||||
startLine = endLine;
|
startLine = endLine;
|
||||||
endLine = -1;
|
endLine = -1;
|
||||||
|
|
@ -1090,7 +1089,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
|
||||||
lenCounter++;
|
lenCounter++;
|
||||||
|
|
||||||
int next = 0;
|
int next = 0;
|
||||||
letter = GetNextCodepoint(&text[i], &next);
|
letter = GetCodepoint(&text[i], &next);
|
||||||
index = GetGlyphIndex(font, letter);
|
index = GetGlyphIndex(font, letter);
|
||||||
|
|
||||||
// NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
// NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||||
|
|
@ -1564,28 +1563,38 @@ RLAPI const char *CodepointToUtf8(int codepoint, int *byteLength)
|
||||||
return utf8;
|
return utf8;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all codepoints in a string, codepoints count returned by parameters
|
// Load all codepoints from a UTF8 text string, codepoints count returned by parameter
|
||||||
// REQUIRES: memset()
|
int *LoadCodepoints(const char *text, int *count)
|
||||||
int *GetCodepoints(const char *text, int *count)
|
|
||||||
{
|
{
|
||||||
static int codepoints[MAX_TEXT_UNICODE_CHARS] = { 0 };
|
int textLength = TextLength(text);
|
||||||
memset(codepoints, 0, MAX_TEXT_UNICODE_CHARS*sizeof(int));
|
|
||||||
|
|
||||||
int bytesProcessed = 0;
|
int bytesProcessed = 0;
|
||||||
int textLength = TextLength(text);
|
|
||||||
int codepointsCount = 0;
|
int codepointsCount = 0;
|
||||||
|
|
||||||
|
// Allocate a big enough buffer to store as many codepoints as text bytes
|
||||||
|
int *codepoints = RL_CALLOC(textLength, sizeof(int));
|
||||||
|
|
||||||
for (int i = 0; i < textLength; codepointsCount++)
|
for (int i = 0; i < textLength; codepointsCount++)
|
||||||
{
|
{
|
||||||
codepoints[codepointsCount] = GetNextCodepoint(text + i, &bytesProcessed);
|
codepoints[codepointsCount] = GetCodepoint(text + i, &bytesProcessed);
|
||||||
i += bytesProcessed;
|
i += bytesProcessed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-allocate buffer to the actual number of codepoints loaded
|
||||||
|
void *temp = RL_REALLOC(codepoints, codepointsCount*sizeof(int));
|
||||||
|
if (temp != NULL) codepoints = temp;
|
||||||
|
|
||||||
*count = codepointsCount;
|
*count = codepointsCount;
|
||||||
|
|
||||||
return codepoints;
|
return codepoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unload codepoints data from memory
|
||||||
|
void UnloadCodepoints(int *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 UTF8 encoded text, until '\0' is found
|
||||||
// NOTE: If an invalid UTF8 sequence is encountered a '?'(0x3f) codepoint is counted instead
|
// NOTE: If an invalid UTF8 sequence is encountered a '?'(0x3f) codepoint is counted instead
|
||||||
int GetCodepointsCount(const char *text)
|
int GetCodepointsCount(const char *text)
|
||||||
|
|
@ -1596,7 +1605,7 @@ int GetCodepointsCount(const char *text)
|
||||||
while (*ptr != '\0')
|
while (*ptr != '\0')
|
||||||
{
|
{
|
||||||
int next = 0;
|
int next = 0;
|
||||||
int letter = GetNextCodepoint(ptr, &next);
|
int letter = GetCodepoint(ptr, &next);
|
||||||
|
|
||||||
if (letter == 0x3f) ptr += 1;
|
if (letter == 0x3f) ptr += 1;
|
||||||
else ptr += next;
|
else ptr += next;
|
||||||
|
|
@ -1614,7 +1623,7 @@ int GetCodepointsCount(const char *text)
|
||||||
// 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
|
||||||
// TODO: Optimize this code for speed!!
|
// TODO: Optimize this code for speed!!
|
||||||
int GetNextCodepoint(const char *text, int *bytesProcessed)
|
int GetCodepoint(const char *text, int *bytesProcessed)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
UTF8 specs from https://www.ietf.org/rfc/rfc3629.txt
|
UTF8 specs from https://www.ietf.org/rfc/rfc3629.txt
|
||||||
|
|
|
||||||
|
|
@ -1114,7 +1114,7 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
|
||||||
{
|
{
|
||||||
// Get next codepoint from byte string and glyph index in font
|
// Get next codepoint from byte string and glyph index in font
|
||||||
int codepointByteCount = 0;
|
int codepointByteCount = 0;
|
||||||
int codepoint = GetNextCodepoint(&text[i], &codepointByteCount);
|
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
||||||
int index = GetGlyphIndex(font, codepoint);
|
int index = GetGlyphIndex(font, codepoint);
|
||||||
|
|
||||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user