Merged
This commit is contained in:
commit
9a1816bc5b
14
.gitignore
vendored
14
.gitignore
vendored
|
|
@ -53,17 +53,6 @@ packages/
|
|||
*.bc
|
||||
*.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
|
||||
*.mode*v*
|
||||
*.pbxuser
|
||||
|
|
@ -93,9 +82,6 @@ compile_commands.json
|
|||
CTestTestfile.cmake
|
||||
build
|
||||
|
||||
# Unignore These makefiles...
|
||||
!examples/CMakeLists.txt
|
||||
|
||||
# Ignore GNU global tags
|
||||
GPATH
|
||||
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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
|
|
|
|||
|
|
@ -5,15 +5,16 @@
|
|||
* 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)
|
||||
*
|
||||
* Example contributed by Giancamillo Alessandroni ([discord]NotManyIdeas#9972 - [github]NotManyIdeasDev) and
|
||||
* Example contributed by Giancamillo Alessandroni (@NotManyIdeasDev) and
|
||||
* 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 <math.h>
|
||||
|
||||
#include <math.h> // Required for: sinf(), cosf()
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
|
@ -22,33 +23,32 @@ int main(void)
|
|||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
const int virualScreenWidth = 160;
|
||||
const int virtualScreenWidth = 160;
|
||||
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");
|
||||
|
||||
Camera2D worldSpaceCamera = { 0 }; // Game world camera
|
||||
Camera2D worldSpaceCamera = { 0 }; // Game world camera
|
||||
worldSpaceCamera.zoom = 1.0f;
|
||||
|
||||
Camera2D screenSpaceCamera = { 0 }; //Smoothing camera
|
||||
Camera2D screenSpaceCamera = { 0 }; // Smoothing camera
|
||||
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 secondRectangle = { 90.0f, 55.0f, 30.0f, 10.0f };
|
||||
Rectangle thirdRectangle = { 80.0f, 65.0f, 15.0f, 25.0f };
|
||||
Rectangle rec01 = { 70.0f, 35.0f, 20.0f, 20.0f };
|
||||
Rectangle rec02 = { 90.0f, 55.0f, 30.0f, 10.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.
|
||||
Rectangle renderTextureSource = { 0.0f, 0.0f, (float)renderTexture.texture.width, (float)-renderTexture.texture.height };
|
||||
Rectangle renderTextureDest = { -virtualRatio, -virtualRatio, screenWidth + (virtualRatio*2), screenHeight + (virtualRatio*2) };
|
||||
// The target's height is flipped (in the source Rectangle), due to OpenGL reasons
|
||||
Rectangle sourceRec = { 0.0f, 0.0f, (float)target.texture.width, -(float)target.texture.height };
|
||||
Rectangle destRec = { -virtualRatio, -virtualRatio, screenWidth + (virtualRatio*2), screenHeight + (virtualRatio*2) };
|
||||
|
||||
Vector2 origin = { 0.0f, 0.0f };
|
||||
|
||||
float rotation = 0.0f;
|
||||
float degreesPerSecond = 60.0f;
|
||||
|
||||
float cameraX = 0.0f;
|
||||
float cameraY = 0.0f;
|
||||
|
|
@ -61,16 +61,16 @@ int main(void)
|
|||
{
|
||||
// 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;
|
||||
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 };
|
||||
|
||||
//Round worldSpace coordinates, keep decimals into screenSpace coordinates.
|
||||
// Round worldSpace coordinates, keep decimals into screenSpace coordinates
|
||||
worldSpaceCamera.target.x = (int)screenSpaceCamera.target.x;
|
||||
screenSpaceCamera.target.x -= worldSpaceCamera.target.x;
|
||||
screenSpaceCamera.target.x *= virtualRatio;
|
||||
|
|
@ -83,47 +83,35 @@ int main(void)
|
|||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(RED); // This is for debug purposes. If you see red, then you've probably done something wrong.
|
||||
|
||||
BeginTextureMode(renderTexture);
|
||||
BeginMode2D(worldSpaceCamera);
|
||||
ClearBackground(RAYWHITE); // This is the color you should see as background color.
|
||||
|
||||
// Draw the rectangles
|
||||
DrawRectanglePro(firstRectangle, origin, rotation, BLACK);
|
||||
DrawRectanglePro(secondRectangle, origin, -rotation, RED);
|
||||
DrawRectanglePro(thirdRectangle, origin, rotation + 45.0f, BLUE);
|
||||
|
||||
EndMode2D();
|
||||
BeginTextureMode(target);
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
BeginMode2D(worldSpaceCamera);
|
||||
DrawRectanglePro(rec01, origin, rotation, BLACK);
|
||||
DrawRectanglePro(rec02, origin, -rotation, RED);
|
||||
DrawRectanglePro(rec03, origin, rotation + 45.0f, BLUE);
|
||||
EndMode2D();
|
||||
EndTextureMode();
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(RED);
|
||||
|
||||
BeginMode2D(screenSpaceCamera);
|
||||
BeginMode2D(screenSpaceCamera);
|
||||
DrawTexturePro(target.texture, sourceRec, destRec, origin, 0.0f, WHITE);
|
||||
EndMode2D();
|
||||
|
||||
// Draw the render texture with an offset of 1 worldSpace unit/pixel, so that the content behind the renderTexture is not shown.
|
||||
DrawTexturePro(
|
||||
renderTexture.texture,
|
||||
renderTextureSource,
|
||||
renderTextureDest,
|
||||
origin,
|
||||
0.0f,
|
||||
WHITE
|
||||
);
|
||||
|
||||
EndMode2D();
|
||||
|
||||
//Debug info
|
||||
DrawText("Screen resolution: 800x450", 5, 0, 20, DARKBLUE);
|
||||
DrawText("World resolution: 160x90", 5, 20, 20, DARKGREEN);
|
||||
DrawFPS(screenWidth - 75, 0);
|
||||
DrawText(TextFormat("Screen resolution: %ix%i", screenWidth, screenHeight), 10, 10, 20, DARKBLUE);
|
||||
DrawText(TextFormat("World resolution: %ix%i", virtualScreenWidth, virtualScreenHeight), 10, 40, 20, DARKGREEN);
|
||||
DrawFPS(GetScreenWidth() - 95, 10);
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadRenderTexture(renderTexture); // RenderTexture unloading
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
UnloadRenderTexture(target); // Unload render texture
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
float offsetThisFrame = 10.0f*GetFrameTime();
|
||||
|
||||
// Move player 1 forward and backwards (no turning)
|
||||
// Move Player1 forward and backwards (no turning)
|
||||
if (IsKeyDown(KEY_W))
|
||||
{
|
||||
cameraPlayer1.position.z += offsetThisFrame;
|
||||
|
|
@ -101,7 +101,7 @@ int main(void)
|
|||
cameraPlayer1.target.z -= offsetThisFrame;
|
||||
}
|
||||
|
||||
// Move player 2 forward and backwards (no turning)
|
||||
// Move Player2 forward and backwards (no turning)
|
||||
if (IsKeyDown(KEY_UP))
|
||||
{
|
||||
cameraPlayer2.position.x += offsetThisFrame;
|
||||
|
|
@ -116,7 +116,7 @@ int main(void)
|
|||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
// Draw player 1's view to the render texture
|
||||
// Draw Player1 view to the render texture
|
||||
BeginTextureMode(screenPlayer1);
|
||||
ClearBackground(SKYBLUE);
|
||||
BeginMode3D(cameraPlayer1);
|
||||
|
|
@ -125,7 +125,7 @@ int main(void)
|
|||
DrawText("PLAYER1 W/S to move", 0, 0, 20, RED);
|
||||
EndTextureMode();
|
||||
|
||||
// Draw player 2's view to the render texture
|
||||
// Draw Player2 view to the render texture
|
||||
BeginTextureMode(screenPlayer2);
|
||||
ClearBackground(SKYBLUE);
|
||||
BeginMode3D(cameraPlayer2);
|
||||
|
|
@ -134,21 +134,21 @@ int main(void)
|
|||
DrawText("PLAYER2 UP/DOWN to move", 0, 0, 20, BLUE);
|
||||
EndTextureMode();
|
||||
|
||||
// Draw both view render textures to the screen side by side
|
||||
// Draw both views render textures to the screen side by side
|
||||
BeginDrawing();
|
||||
ClearBackground(BLACK);
|
||||
DrawTextureRec(screenPlayer1.texture, splitScreenRect, (Vector2) { 0, 0 }, WHITE);
|
||||
DrawTextureRec(screenPlayer2.texture, splitScreenRect, (Vector2) { screenWidth/2.0f, 0 }, WHITE);
|
||||
DrawTextureRec(screenPlayer1.texture, splitScreenRect, (Vector2){ 0, 0 }, WHITE);
|
||||
DrawTextureRec(screenPlayer2.texture, splitScreenRect, (Vector2){ screenWidth/2.0f, 0 }, WHITE);
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadRenderTexture(screenPlayer1);
|
||||
UnloadRenderTexture(screenPlayer2);
|
||||
UnloadTexture(textureGrid);
|
||||
UnloadRenderTexture(screenPlayer1); // Unload render texture
|
||||
UnloadRenderTexture(screenPlayer2); // Unload render texture
|
||||
UnloadTexture(textureGrid); // Unload texture
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -105,30 +105,26 @@ int main(void)
|
|||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
BeginTextureMode(target);
|
||||
ClearBackground(RAYWHITE);
|
||||
BeginVrStereoMode(config);
|
||||
BeginMode3D(camera);
|
||||
|
||||
BeginTextureMode(target);
|
||||
ClearBackground(RAYWHITE);
|
||||
BeginVrStereoMode(config);
|
||||
BeginMode3D(camera);
|
||||
|
||||
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
|
||||
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
|
||||
DrawGrid(40, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
EndVrStereoMode();
|
||||
EndTextureMode();
|
||||
DrawCube(cubePosition, 2.0f, 2.0f, 2.0f, RED);
|
||||
DrawCubeWires(cubePosition, 2.0f, 2.0f, 2.0f, MAROON);
|
||||
DrawGrid(40, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
EndVrStereoMode();
|
||||
EndTextureMode();
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
BeginShaderMode(distortion);
|
||||
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width,
|
||||
(float)-target.texture.height }, (Vector2){ 0.0f, 0.0f }, WHITE);
|
||||
EndShaderMode();
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,11 +48,11 @@ int main(void)
|
|||
Color colors[10] = { 0 };
|
||||
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
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -79,37 +79,33 @@ int main(void)
|
|||
|
||||
// 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();
|
||||
ClearBackground(BLACK);
|
||||
ClearBackground(BLACK); // Clear screen background
|
||||
|
||||
// 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();
|
||||
|
||||
// Draw RenderTexture2D to window, properly scaled
|
||||
// Draw render texture to screen, properly scaled
|
||||
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,
|
||||
(float)gameScreenWidth*scale, (float)gameScreenHeight*scale }, (Vector2){ 0, 0 }, 0.0f, WHITE);
|
||||
|
||||
EndDrawing();
|
||||
//--------------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
|
|
|||
|
|
@ -41,16 +41,18 @@
|
|||
*
|
||||
* 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)
|
||||
*
|
||||
* 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"
|
||||
|
||||
int main()
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ int main(void)
|
|||
|
||||
// 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
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -65,6 +65,14 @@
|
|||
#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
|
||||
#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
|
||||
typedef struct Camera {
|
||||
Vector3 position; // Camera position
|
||||
|
|
@ -271,7 +279,7 @@ static void DrawGrid(int slices, float spacing)
|
|||
int halfSlices = slices / 2;
|
||||
|
||||
rlBegin(RL_LINES);
|
||||
for(int i = -halfSlices; i <= halfSlices; i++)
|
||||
for (int i = -halfSlices; i <= halfSlices; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -65,11 +65,11 @@ int main(void)
|
|||
// Setup orbital camera
|
||||
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
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -81,55 +81,46 @@ int main(void)
|
|||
// Send new value to the shader to be used on drawing
|
||||
SetShaderValue(shader, swirlCenterLoc, swirlCenter, SHADER_UNIFORM_VEC2);
|
||||
|
||||
UpdateCamera(&camera); // Update camera
|
||||
UpdateCamera(&camera); // Update camera
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// 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();
|
||||
ClearBackground(RAYWHITE); // Clear screen background
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
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)
|
||||
|
||||
// Enable shader using the custom uniform
|
||||
BeginShaderMode(shader);
|
||||
|
||||
// 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);
|
||||
|
||||
EndShaderMode();
|
||||
|
||||
// Draw some 2d text over drawn texture
|
||||
DrawText("(c) Barracks 3D model by Alberto Cano", screenWidth - 220, screenHeight - 20, 10, GRAY);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadShader(shader); // Unload shader
|
||||
UnloadTexture(texture); // Unload texture
|
||||
UnloadModel(model); // Unload model
|
||||
UnloadRenderTexture(target); // Unload render texture
|
||||
UnloadShader(shader); // Unload shader
|
||||
UnloadTexture(texture); // Unload texture
|
||||
UnloadModel(model); // Unload model
|
||||
UnloadRenderTexture(target); // Unload render texture
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -46,11 +46,11 @@ int main(void)
|
|||
// 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));
|
||||
|
||||
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
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -59,35 +59,33 @@ int main(void)
|
|||
|
||||
// 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();
|
||||
|
||||
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)
|
||||
ClearBackground(RAYWHITE); // Clear screen background
|
||||
|
||||
BeginShaderMode(shader);
|
||||
// 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);
|
||||
EndShaderMode();
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadShader(shader); // Unload shader
|
||||
UnloadRenderTexture(target); // Unload texture
|
||||
UnloadShader(shader); // Unload shader
|
||||
UnloadRenderTexture(target); // Unload render texture
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -75,15 +75,15 @@ int main(void)
|
|||
SetShaderValue(shader, zoomLoc, &zoom, SHADER_UNIFORM_FLOAT);
|
||||
SetShaderValue(shader, offsetLoc, offset, SHADER_UNIFORM_VEC2);
|
||||
|
||||
int incrementSpeed = 0; // Multiplier of speed to change c value
|
||||
bool showControls = true; // Show controls
|
||||
bool pause = false; // Pause animation
|
||||
int incrementSpeed = 0; // Multiplier of speed to change c value
|
||||
bool showControls = true; // Show controls
|
||||
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
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -145,20 +145,19 @@ int main(void)
|
|||
|
||||
// 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();
|
||||
|
||||
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();
|
||||
ClearBackground(BLACK); // Clear screen background
|
||||
|
||||
// Draw the saved texture and rendered julia set with 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_SPACE to pause movement animation", 10, 75, 10, RAYWHITE);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadShader(shader); // Unload shader
|
||||
UnloadRenderTexture(target); // Unload render texture
|
||||
UnloadShader(shader); // Unload shader
|
||||
UnloadRenderTexture(target); // Unload render texture
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -124,50 +124,38 @@ int main(void)
|
|||
|
||||
// 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();
|
||||
ClearBackground(RAYWHITE); // Clear screen background
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
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
|
||||
// Render generated texture using selected postprocessing shader
|
||||
BeginShaderMode(shaders[currentShader]);
|
||||
|
||||
// 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);
|
||||
|
||||
EndShaderMode();
|
||||
|
||||
// Draw 2d shapes and text over drawn texture
|
||||
DrawRectangle(0, 9, 580, 30, Fade(LIGHTGRAY, 0.7f));
|
||||
|
||||
DrawText("(c) Church 3D model by Alberto Cano", screenWidth - 200, screenHeight - 20, 10, GRAY);
|
||||
|
||||
DrawText("CURRENT POSTPRO SHADER:", 10, 15, 20, BLACK);
|
||||
DrawText(postproShaderText[currentShader], 330, 15, 20, RED);
|
||||
DrawText("< >", 540, 10, 30, DARKBLUE);
|
||||
|
||||
DrawFPS(700, 15);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Unload all postpro shaders
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -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 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 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 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);
|
||||
|
||||
#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
|
||||
int codepointByteCount = 0;
|
||||
int codepoint = GetNextCodepoint(&text[i], &codepointByteCount);
|
||||
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
||||
int index = GetGlyphIndex(font, codepoint);
|
||||
|
||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||
|
|
@ -582,7 +582,7 @@ Vector3 MeasureText3D(Font font, const char* text, float fontSize, float fontSpa
|
|||
lenCounter++;
|
||||
|
||||
int next = 0;
|
||||
letter = GetNextCodepoint(&text[i], &next);
|
||||
letter = GetCodepoint(&text[i], &next);
|
||||
index = GetGlyphIndex(font, letter);
|
||||
|
||||
// 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
|
||||
int codepointByteCount = 0;
|
||||
int codepoint = GetNextCodepoint(&text[i], &codepointByteCount);
|
||||
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
||||
int index = GetGlyphIndex(font, codepoint);
|
||||
|
||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||
|
|
@ -649,7 +649,7 @@ void DrawTextWave3D(Font font, const char *text, Vector3 position, float fontSiz
|
|||
}
|
||||
else if (codepoint == '~')
|
||||
{
|
||||
if (GetNextCodepoint(&text[i+1], &codepointByteCount) == '~')
|
||||
if (GetCodepoint(&text[i+1], &codepointByteCount) == '~')
|
||||
{
|
||||
codepointByteCount += 1;
|
||||
wave = !wave;
|
||||
|
|
@ -698,7 +698,7 @@ Vector3 MeasureTextWave3D(Font font, const char* text, float fontSize, float fon
|
|||
lenCounter++;
|
||||
|
||||
int next = 0;
|
||||
letter = GetNextCodepoint(&text[i], &next);
|
||||
letter = GetCodepoint(&text[i], &next);
|
||||
index = GetGlyphIndex(font, letter);
|
||||
|
||||
// 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 == '~' && GetNextCodepoint(&text[i+1], &next) == '~')
|
||||
if (letter == '~' && GetCodepoint(&text[i+1], &next) == '~')
|
||||
{
|
||||
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);|
|
||||
GenMeshHeightmap|Mesh|(Image heightmap, Vector3 size);|
|
||||
GenMeshCubicmap|Mesh|(Image cubicmap, Vector3 cubeSize);|
|
||||
MeshBoundingBox|BoundingBox|(Mesh mesh);|
|
||||
GetMeshBoundingBox|BoundingBox|(Mesh mesh);|
|
||||
MeshTangents|void|(Mesh *mesh);|
|
||||
MeshBinormals|void|(Mesh *mesh);|
|
||||
DrawModel|void|(Model model, Vector3 position, float scale, Color tint);|
|
||||
|
|
|
|||
|
|
@ -1549,7 +1549,7 @@
|
|||
</KeyWord>
|
||||
|
||||
<!-- Mesh manipulation functions -->
|
||||
<KeyWord name="MeshBoundingBox" func="yes">
|
||||
<KeyWord name="GetMeshBoundingBox" func="yes">
|
||||
<Overload retVal="BoundingBox" descr="Compute mesh bounding box limits">
|
||||
<Param name="Mesh mesh" />
|
||||
</Overload>
|
||||
|
|
|
|||
|
|
@ -2495,7 +2495,7 @@
|
|||
</KeyWord>
|
||||
|
||||
<!-- Mesh manipulation functions -->
|
||||
<KeyWord name="MeshBoundingBox" func="yes">
|
||||
<KeyWord name="GetMeshBoundingBox" func="yes">
|
||||
<Overload retVal="BoundingBox" descr="Compute mesh bounding box limits">
|
||||
<Param name="Mesh mesh" />
|
||||
</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
|
||||
|
||||
// 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 MeshBinormals(Mesh *mesh); // Compute mesh binormals
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
// Reconfigure standard input to receive key inputs, works with SSH connection.
|
||||
#define SUPPORT_SSH_KEYBOARD_RPI 1
|
||||
// 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.
|
||||
// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.
|
||||
#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.
|
||||
#define SUPPORT_DATA_STORAGE 1
|
||||
// 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
|
||||
//------------------------------------------------------------------------------------
|
||||
|
|
@ -161,7 +165,6 @@
|
|||
//------------------------------------------------------------------------------------
|
||||
#define MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions:
|
||||
// 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()
|
||||
|
||||
|
||||
|
|
|
|||
257
src/core.c
257
src/core.c
|
|
@ -56,7 +56,7 @@
|
|||
* 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.
|
||||
*
|
||||
* #define SUPPORT_MOUSE_CURSOR_NATIVE (Raspberry Pi and DRM only)
|
||||
* #define SUPPORT_MOUSE_CURSOR_POINT
|
||||
* Draw a mouse pointer on screen
|
||||
*
|
||||
* #define SUPPORT_BUSY_WAIT_LOOP
|
||||
|
|
@ -387,7 +387,7 @@ typedef struct CoreData {
|
|||
Point position; // Window position on screen (required on fullscreen toggle)
|
||||
Size display; // Display width and height (monitor, device-screen, LCD, ...)
|
||||
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)
|
||||
Point renderOffset; // Offset from render area (must be divided by 2)
|
||||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
static void InitTimer(void); // Initialize timer (hi-resolution if available)
|
||||
static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
|
||||
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 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)
|
||||
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)
|
||||
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 EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *e, void *userData);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
|
||||
|
|
@ -673,7 +670,7 @@ static void PlayAutomationEvent(unsigned int frame);
|
|||
|
||||
#if defined(_WIN32)
|
||||
// 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
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -843,6 +840,9 @@ void InitWindow(int width, int height, const char *title)
|
|||
|
||||
// Init hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// Initialize random seed
|
||||
srand((unsigned int)time(NULL));
|
||||
|
||||
#if defined(SUPPORT_DEFAULT_FONT)
|
||||
// Load default font
|
||||
|
|
@ -875,10 +875,14 @@ void InitWindow(int width, int height, const char *title)
|
|||
#endif
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
// Check fullscreen change events
|
||||
//emscripten_set_fullscreenchange_callback("#canvas", NULL, 1, EmscriptenFullscreenChangeCallback);
|
||||
//emscripten_set_resize_callback("#canvas", NULL, 1, EmscriptenResizeCallback);
|
||||
|
||||
// Check fullscreen change events(note this is done on the window since most
|
||||
// browsers don't support this on #canvas)
|
||||
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
|
||||
//emscripten_set_keypress_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
|
||||
void SetWindowSize(int width, int height)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
glfwSetWindowSize(CORE.Window.handle, width, height);
|
||||
#endif
|
||||
#if defined(PLATFORM_WEB)
|
||||
|
|
@ -1938,7 +1942,10 @@ void ClearBackground(Color color)
|
|||
// Setup canvas (framebuffer) to start drawing
|
||||
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.previous = CORE.Time.current;
|
||||
|
||||
|
|
@ -1952,22 +1959,22 @@ void BeginDrawing(void)
|
|||
// End canvas drawing and swap buffers (double buffering)
|
||||
void EndDrawing(void)
|
||||
{
|
||||
#if (defined(PLATFORM_RPI) || defined(PLATFORM_DRM)) && defined(SUPPORT_MOUSE_CURSOR_NATIVE)
|
||||
// On native mode we have no system mouse cursor, so,
|
||||
// we draw a small rectangle for user reference
|
||||
rlDrawRenderBatchActive(); // Update and draw internal render batch
|
||||
|
||||
#if defined(SUPPORT_MOUSE_CURSOR_POINT)
|
||||
// Draw a small rectangle on mouse position for user reference
|
||||
if (!CORE.Input.Mouse.cursorHidden)
|
||||
{
|
||||
DrawRectangle(CORE.Input.Mouse.currentPosition.x, CORE.Input.Mouse.currentPosition.y, 3, 3, MAROON);
|
||||
rlDrawRenderBatchActive(); // Update and draw internal render batch
|
||||
}
|
||||
#endif
|
||||
|
||||
rlDrawRenderBatchActive(); // Update and draw internal render batch
|
||||
|
||||
#if defined(SUPPORT_GIF_RECORDING)
|
||||
#define GIF_RECORD_FRAMERATE 10
|
||||
|
||||
// Draw record indicator
|
||||
if (gifRecording)
|
||||
{
|
||||
#define GIF_RECORD_FRAMERATE 10
|
||||
gifFramesCounter++;
|
||||
|
||||
// NOTE: We record one gif frame every 10 game frames
|
||||
|
|
@ -1992,6 +1999,7 @@ void EndDrawing(void)
|
|||
#endif
|
||||
|
||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||
// Draw record/play indicator
|
||||
if (eventsRecording)
|
||||
{
|
||||
gifFramesCounter++;
|
||||
|
|
@ -2018,7 +2026,8 @@ void EndDrawing(void)
|
|||
}
|
||||
#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
|
||||
CORE.Time.current = GetTime();
|
||||
|
|
@ -2030,7 +2039,7 @@ void EndDrawing(void)
|
|||
// Wait for some milliseconds...
|
||||
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();
|
||||
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
|
||||
}
|
||||
|
||||
PollInputEvents(); // Poll user events
|
||||
PollInputEvents(); // Poll user events (before next frame update)
|
||||
#endif
|
||||
|
||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||
// Events recording and playing logic
|
||||
if (eventsRecording) RecordAutomationEvent(CORE.Time.frameCounter);
|
||||
|
||||
// TODO: When should we play? After/before/replace PollInputEvents()?
|
||||
if (eventsPlaying)
|
||||
else if (eventsPlaying)
|
||||
{
|
||||
// TODO: When should we play? After/before/replace PollInputEvents()?
|
||||
if (CORE.Time.frameCounter >= eventCount) eventsPlaying = false;
|
||||
PlayAutomationEvent(CORE.Time.frameCounter);
|
||||
}
|
||||
|
|
@ -2638,6 +2648,9 @@ void SetTargetFPS(int fps)
|
|||
// NOTE: We calculate an average framerate
|
||||
int GetFPS(void)
|
||||
{
|
||||
int fps = 0;
|
||||
|
||||
#if !defined(SUPPORT_CUSTOM_FRAME_CONTROL)
|
||||
#define FPS_CAPTURE_FRAMES_COUNT 30 // 30 captures
|
||||
#define FPS_AVERAGE_TIME_SECONDS 0.5f // 500 millisecondes
|
||||
#define FPS_STEP (FPS_AVERAGE_TIME_SECONDS/FPS_CAPTURE_FRAMES_COUNT)
|
||||
|
|
@ -2658,7 +2671,10 @@ int GetFPS(void)
|
|||
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)
|
||||
|
|
@ -3540,6 +3556,17 @@ Vector2 GetMousePosition(void)
|
|||
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
|
||||
void SetMousePosition(int x, int y)
|
||||
{
|
||||
|
|
@ -4661,8 +4688,6 @@ static void SetupFramebuffer(int width, int height)
|
|||
// Initialize hi-resolution timer
|
||||
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.
|
||||
// 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.
|
||||
|
|
@ -4689,7 +4714,7 @@ static void InitTimer(void)
|
|||
// 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://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)
|
||||
UWPGetSleepFunc()(ms/1000);
|
||||
|
|
@ -4737,8 +4762,70 @@ static void Wait(float ms)
|
|||
#endif
|
||||
}
|
||||
|
||||
// Poll (store) all input events
|
||||
static void PollInputEvents(void)
|
||||
// Swap back buffer with front buffer (screen drawing)
|
||||
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)
|
||||
// NOTE: Gestures update must be called every frame to reset gestures correctly
|
||||
|
|
@ -5014,68 +5101,6 @@ static void PollInputEvents(void)
|
|||
#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)
|
||||
// GLFW3 Error Callback, runs on GLFW3 error
|
||||
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);
|
||||
}
|
||||
|
||||
#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
|
||||
// NOTE: Window resizing not allowed by default
|
||||
|
|
@ -5374,6 +5429,9 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
|
||||
// Init hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// Initialize random seed
|
||||
srand((unsigned int)time(NULL));
|
||||
|
||||
#if defined(SUPPORT_DEFAULT_FONT)
|
||||
// Load default font
|
||||
|
|
@ -6327,7 +6385,8 @@ static void *EventThread(void *arg)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
Wait(5); // Sleep for 5ms to avoid hogging CPU time
|
||||
|
||||
WaitTime(5); // Sleep for 5ms to avoid hogging CPU time
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6829,7 +6888,7 @@ static void LoadAutomationEvents(const char *fileName)
|
|||
{
|
||||
sscanf(buffer, "e %d %d %d %d %d", &events[count].frame, &events[count].type,
|
||||
&events[count].params[0], &events[count].params[1], &events[count].params[2]);
|
||||
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
|
|
|
|||
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 } */
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (material.name) {
|
||||
/* Flush last material element */
|
||||
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)
|
||||
// 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 double GetCurrentTime(void); // Get current time measure in milliseconds
|
||||
#endif
|
||||
|
|
@ -370,7 +370,7 @@ PHYSACDEF void InitPhysics(void)
|
|||
{
|
||||
#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
|
||||
// Initialize high resolution timer
|
||||
InitTimer();
|
||||
InitTimerHiRes();
|
||||
#endif
|
||||
|
||||
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)
|
||||
// Initializes hi-resolution MONOTONIC timer
|
||||
static void InitTimer(void)
|
||||
static void InitTimerHiRes(void)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
QueryPerformanceFrequency((unsigned long long int *) &frequency);
|
||||
|
|
|
|||
12
src/models.c
12
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);
|
||||
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)
|
||||
rlEnableVertexBuffer(mesh.vboId[1]);
|
||||
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
|
||||
// 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
|
||||
void MeshTangents(Mesh *mesh)
|
||||
void GenMeshTangents(Mesh *mesh)
|
||||
{
|
||||
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");
|
||||
|
|
@ -2732,7 +2728,7 @@ void MeshTangents(Mesh *mesh)
|
|||
}
|
||||
|
||||
// Compute mesh binormals (aka bitangent)
|
||||
void MeshBinormals(Mesh *mesh)
|
||||
void GenMeshBinormals(Mesh *mesh)
|
||||
{
|
||||
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
|
||||
|
||||
// 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);
|
||||
output->bones[j].parent = (data->nodes[j].parent != NULL) ? (int)(data->nodes[j].parent - data->nodes) : -1;
|
||||
|
|
@ -5007,7 +5003,7 @@ static ModelAnimation *LoadGLTFModelAnimations(const char *fileName, int *animCo
|
|||
for (int frame = 0; frame < output->frameCount; frame++)
|
||||
{
|
||||
output->framePoses[frame] = RL_MALLOC(output->boneCount*sizeof(Transform));
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < output->boneCount; i++)
|
||||
{
|
||||
if (data->nodes[i].has_translation) memcpy(&output->framePoses[frame][i].translation, data->nodes[i].translation, 3 * sizeof(float));
|
||||
|
|
|
|||
20
src/raylib.h
20
src/raylib.h
|
|
@ -222,7 +222,7 @@ typedef struct Color {
|
|||
|
||||
// Rectangle, 4 components
|
||||
typedef struct Rectangle {
|
||||
float x; // Rectangle top-left corner position x
|
||||
float x; // Rectangle top-left corner position x
|
||||
float y; // Rectangle top-left corner position y
|
||||
float width; // Rectangle width
|
||||
float height; // Rectangle height
|
||||
|
|
@ -960,6 +960,14 @@ RLAPI const char *GetMonitorName(int monitor); // Get the hum
|
|||
RLAPI void SetClipboardText(const char *text); // Set 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
|
||||
RLAPI void ShowCursor(void); // Shows 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 GetMouseY(void); // Get mouse position Y
|
||||
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 SetMouseOffset(int offsetX, int offsetY); // Set mouse offset
|
||||
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!)
|
||||
|
||||
// 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 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)
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
|
@ -1435,8 +1445,8 @@ RLAPI Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
|
|||
|
||||
// Mesh manipulation functions
|
||||
RLAPI BoundingBox GetMeshBoundingBox(Mesh mesh); // Compute mesh bounding box limits
|
||||
RLAPI void MeshTangents(Mesh *mesh); // Compute mesh tangents
|
||||
RLAPI void MeshBinormals(Mesh *mesh); // Compute mesh binormals
|
||||
RLAPI void GenMeshTangents(Mesh *mesh); // Compute mesh tangents
|
||||
RLAPI void GenMeshBinormals(Mesh *mesh); // Compute mesh binormals
|
||||
|
||||
// Model drawing functions
|
||||
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@
|
|||
typedef struct float3 { float v[3]; } float3;
|
||||
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
|
||||
|
|
|
|||
74
src/rlgl.h
74
src/rlgl.h
|
|
@ -297,14 +297,6 @@ typedef struct RenderBatch {
|
|||
typedef enum { false, true } bool;
|
||||
#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
|
||||
// NOTE: Data stored in GPU memory
|
||||
typedef struct Texture2D {
|
||||
|
|
@ -880,8 +872,8 @@ static char *rlGetCompressedFormatName(int format); // Get compressed format off
|
|||
#endif // SUPPORT_GL_DETAILS_INFO
|
||||
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
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 int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHeight); // Generate mipmaps data on CPU side
|
||||
static unsigned char *rlGenNextMipmapData(unsigned char *srcData, int srcWidth, int srcHeight); // Generate next mipmap level on CPU side
|
||||
#endif
|
||||
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;
|
||||
height = baseHeight;
|
||||
size = (width*height*4);
|
||||
size = (width*height*4); // RGBA: 4 bytes
|
||||
|
||||
// Generate mipmaps
|
||||
// NOTE: Every mipmap data is stored after data
|
||||
Color *image = (Color *)RL_MALLOC(width*height*sizeof(Color));
|
||||
Color *mipmap = NULL;
|
||||
// NOTE: Every mipmap data is stored after data (RGBA - 4 bytes)
|
||||
unsigned char *image = (unsigned char *)RL_MALLOC(width*height*4);
|
||||
unsigned char *mipmap = NULL;
|
||||
int offset = 0;
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < size; i += 4)
|
||||
{
|
||||
image[j].r = data[i];
|
||||
image[j].g = data[i + 1];
|
||||
image[j].b = data[i + 2];
|
||||
image[j].a = data[i + 3];
|
||||
j++;
|
||||
image[i] = data[i];
|
||||
image[i + 1] = data[i + 1];
|
||||
image[i + 2] = data[i + 2];
|
||||
image[i + 3] = data[i + 3];
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
offset += (width*height*4); // Size of last mipmap
|
||||
j = 0;
|
||||
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
|
|
@ -3991,11 +3980,10 @@ static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHei
|
|||
// Add mipmap to data
|
||||
for (int i = 0; i < size; i += 4)
|
||||
{
|
||||
data[offset + i] = mipmap[j].r;
|
||||
data[offset + i + 1] = mipmap[j].g;
|
||||
data[offset + i + 2] = mipmap[j].b;
|
||||
data[offset + i + 3] = mipmap[j].a;
|
||||
j++;
|
||||
data[offset + i] = mipmap[i];
|
||||
data[offset + i + 1] = mipmap[i + 1];
|
||||
data[offset + i + 2] = mipmap[i + 2];
|
||||
data[offset + i + 3] = mipmap[i + 3];
|
||||
}
|
||||
|
||||
RL_FREE(image);
|
||||
|
|
@ -4010,15 +3998,17 @@ static int rlGenerateMipmapsData(unsigned char *data, int baseWidth, int baseHei
|
|||
}
|
||||
|
||||
// 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;
|
||||
Color prow, pcol;
|
||||
int x2 = 0;
|
||||
int y2 = 0;
|
||||
unsigned char prow[4];
|
||||
unsigned char pcol[4];
|
||||
|
||||
int width = srcWidth/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)
|
||||
for (int y = 0; y < height; y++)
|
||||
|
|
@ -4029,20 +4019,20 @@ static Color *rlGenNextMipmapData(Color *srcData, int srcWidth, int srcHeight)
|
|||
{
|
||||
x2 = 2*x;
|
||||
|
||||
prow.r = (srcData[y2*srcWidth + x2].r + srcData[y2*srcWidth + x2 + 1].r)/2;
|
||||
prow.g = (srcData[y2*srcWidth + x2].g + srcData[y2*srcWidth + x2 + 1].g)/2;
|
||||
prow.b = (srcData[y2*srcWidth + x2].b + srcData[y2*srcWidth + x2 + 1].b)/2;
|
||||
prow.a = (srcData[y2*srcWidth + x2].a + srcData[y2*srcWidth + x2 + 1].a)/2;
|
||||
prow[0] = (srcData[(y2*srcWidth + x2)*4 + 0] + srcData[(y2*srcWidth + x2 + 1)*4 + 0])/2;
|
||||
prow[1] = (srcData[(y2*srcWidth + x2)*4 + 1] + srcData[(y2*srcWidth + x2 + 1)*4 + 1])/2;
|
||||
prow[2] = (srcData[(y2*srcWidth + x2)*4 + 2] + srcData[(y2*srcWidth + x2 + 1)*4 + 2])/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.g = (srcData[(y2+1)*srcWidth + x2].g + srcData[(y2+1)*srcWidth + x2 + 1].g)/2;
|
||||
pcol.b = (srcData[(y2+1)*srcWidth + x2].b + srcData[(y2+1)*srcWidth + x2 + 1].b)/2;
|
||||
pcol.a = (srcData[(y2+1)*srcWidth + x2].a + srcData[(y2+1)*srcWidth + x2 + 1].a)/2;
|
||||
pcol[0] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 0] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 0])/2;
|
||||
pcol[1] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 1] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 1])/2;
|
||||
pcol[2] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 2] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 2])/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].g = (prow.g + pcol.g)/2;
|
||||
mipmap[y*width + x].b = (prow.b + pcol.b)/2;
|
||||
mipmap[y*width + x].a = (prow.a + pcol.a)/2;
|
||||
mipmap[(y*width + x)*4 + 0] = (prow[0] + pcol[0])/2;
|
||||
mipmap[(y*width + x)*4 + 1] = (prow[1] + pcol[1])/2;
|
||||
mipmap[(y*width + x)*4 + 2] = (prow[2] + pcol[2])/2;
|
||||
mipmap[(y*width + x)*4 + 3] = (prow[3] + pcol[3])/2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1645,7 +1645,7 @@ bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshol
|
|||
if (fabsf(dxl) >= fabsf(dyl)) collision = (dxl > 0)? ((p1.x <= point.x) && (point.x <= p2.x)) : ((p2.x <= point.x) && (point.x <= p1.x));
|
||||
else collision = (dyl > 0)? ((p1.y <= point.y) && (point.y <= p2.y)) : ((p2.y <= point.y) && (point.y <= p1.y));
|
||||
}
|
||||
|
||||
|
||||
return collision;
|
||||
}
|
||||
|
||||
|
|
|
|||
63
src/text.c
63
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
|
||||
int codepointByteCount = 0;
|
||||
int codepoint = GetNextCodepoint(&text[i], &codepointByteCount);
|
||||
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
||||
int index = GetGlyphIndex(font, codepoint);
|
||||
|
||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||
|
|
@ -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 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 scaleFactor = fontSize/font.baseSize; // Character quad scaling factor
|
||||
float scaleFactor = fontSize/(float)font.baseSize; // Character quad scaling factor
|
||||
|
||||
// Word/character wrapping mechanism variables
|
||||
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
|
||||
int codepointByteCount = 0;
|
||||
int codepoint = GetNextCodepoint(&text[i], &codepointByteCount);
|
||||
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
||||
int index = GetGlyphIndex(font, codepoint);
|
||||
|
||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||
|
|
@ -926,12 +926,12 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
|
|||
if (codepoint == 0x3f) codepointByteCount = 1;
|
||||
i += (codepointByteCount - 1);
|
||||
|
||||
int glyphWidth = 0;
|
||||
float glyphWidth = 0;
|
||||
if (codepoint != '\n')
|
||||
{
|
||||
glyphWidth = (font.chars[index].advanceX == 0)?
|
||||
(int)(font.recs[index].width*scaleFactor + spacing):
|
||||
(int)(font.chars[index].advanceX*scaleFactor + spacing);
|
||||
glyphWidth = (font.chars[index].advanceX == 0) ? font.recs[index].width*scaleFactor : font.chars[index].advanceX*scaleFactor;
|
||||
|
||||
if (i + 1 < length) glyphWidth = glyphWidth + spacing;
|
||||
}
|
||||
|
||||
// NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside of the rec container
|
||||
|
|
@ -945,7 +945,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
|
|||
// Ref: http://jkorpela.fi/chars/spaces.html
|
||||
if ((codepoint == ' ') || (codepoint == '\t') || (codepoint == '\n')) endLine = i;
|
||||
|
||||
if ((textOffsetX + glyphWidth + 1) >= rec.width)
|
||||
if ((textOffsetX + glyphWidth) > rec.width)
|
||||
{
|
||||
endLine = (endLine < 1)? i : endLine;
|
||||
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)
|
||||
{
|
||||
endLine = i;
|
||||
|
||||
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)
|
||||
{
|
||||
textOffsetY += (int)((font.baseSize + font.baseSize/2)*scaleFactor);
|
||||
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
||||
textOffsetX = 0;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
bool isGlyphSelected = false;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -1011,7 +1010,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
|
|||
|
||||
if (wordWrap && (i == endLine))
|
||||
{
|
||||
textOffsetY += (int)((font.baseSize + font.baseSize/2)*scaleFactor);
|
||||
textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor;
|
||||
textOffsetX = 0;
|
||||
startLine = endLine;
|
||||
endLine = -1;
|
||||
|
|
@ -1090,7 +1089,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
|
|||
lenCounter++;
|
||||
|
||||
int next = 0;
|
||||
letter = GetNextCodepoint(&text[i], &next);
|
||||
letter = GetCodepoint(&text[i], &next);
|
||||
index = GetGlyphIndex(font, letter);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Get all codepoints in a string, codepoints count returned by parameters
|
||||
// REQUIRES: memset()
|
||||
int *GetCodepoints(const char *text, int *count)
|
||||
// Load all codepoints from a UTF8 text string, codepoints count returned by parameter
|
||||
int *LoadCodepoints(const char *text, int *count)
|
||||
{
|
||||
static int codepoints[MAX_TEXT_UNICODE_CHARS] = { 0 };
|
||||
memset(codepoints, 0, MAX_TEXT_UNICODE_CHARS*sizeof(int));
|
||||
|
||||
int bytesProcessed = 0;
|
||||
int textLength = TextLength(text);
|
||||
|
||||
int bytesProcessed = 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++)
|
||||
{
|
||||
codepoints[codepointsCount] = GetNextCodepoint(text + i, &bytesProcessed);
|
||||
codepoints[codepointsCount] = GetCodepoint(text + 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;
|
||||
|
||||
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
|
||||
// NOTE: If an invalid UTF8 sequence is encountered a '?'(0x3f) codepoint is counted instead
|
||||
int GetCodepointsCount(const char *text)
|
||||
|
|
@ -1596,7 +1605,7 @@ int GetCodepointsCount(const char *text)
|
|||
while (*ptr != '\0')
|
||||
{
|
||||
int next = 0;
|
||||
int letter = GetNextCodepoint(ptr, &next);
|
||||
int letter = GetCodepoint(ptr, &next);
|
||||
|
||||
if (letter == 0x3f) ptr += 1;
|
||||
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
|
||||
// but that character is not supported by the default font in raylib
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
int codepointByteCount = 0;
|
||||
int codepoint = GetNextCodepoint(&text[i], &codepointByteCount);
|
||||
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
||||
int index = GetGlyphIndex(font, codepoint);
|
||||
|
||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user