aboutsummaryrefslogtreecommitdiff
path: root/raylib/examples/shapes
diff options
context:
space:
mode:
authorUneven Prankster <unevenprankster@protonmail.com>2023-11-16 21:12:27 -0300
committerUneven Prankster <unevenprankster@protonmail.com>2023-11-16 21:12:27 -0300
commit2bbf92ad5ae7708bf18ac7ef333e9a979d8d1bde (patch)
treec9d22bb0d73d9cc0c8586e4d31c93a561ea8e910 /raylib/examples/shapes
parent1c0cc775732201f4c4d3ee0d6772be786b3b4aa1 (diff)
Working so hard like a soldiermain
Can't afford a thing on TV
Diffstat (limited to 'raylib/examples/shapes')
-rw-r--r--raylib/examples/shapes/raygui.h102
-rw-r--r--raylib/examples/shapes/shapes_bouncing_ball.c3
-rw-r--r--raylib/examples/shapes/shapes_draw_circle_sector.c2
-rw-r--r--raylib/examples/shapes/shapes_lines_bezier.c41
-rw-r--r--raylib/examples/shapes/shapes_lines_bezier.pngbin17537 -> 17953 bytes
-rw-r--r--raylib/examples/shapes/shapes_lines_splines.c155
-rw-r--r--raylib/examples/shapes/shapes_splines_drawing.c247
-rw-r--r--raylib/examples/shapes/shapes_splines_drawing.pngbin0 -> 26123 bytes
-rw-r--r--raylib/examples/shapes/shapes_top_down_lights.c1
9 files changed, 321 insertions, 230 deletions
diff --git a/raylib/examples/shapes/raygui.h b/raylib/examples/shapes/raygui.h
index 26d6bac..9127710 100644
--- a/raylib/examples/shapes/raygui.h
+++ b/raylib/examples/shapes/raygui.h
@@ -136,7 +136,7 @@
*
* #define RAYGUI_DEBUG_RECS_BOUNDS
* Draw control bounds rectangles for debug
-*
+*
* #define RAYGUI_DEBUG_TEXT_BOUNDS
* Draw text bounds rectangles for debug
*
@@ -246,7 +246,7 @@
* 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria.
*
* DEPENDENCIES:
-* raylib 4.6-dev Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing
+* raylib 5.0 - Inputs reading (keyboard/mouse), shapes drawing, font loading and text drawing
*
* STANDALONE MODE:
* By default raygui depends on raylib mostly for the inputs and the drawing functionality but that dependency can be disabled
@@ -498,7 +498,7 @@ typedef enum {
typedef enum {
// Default -> populates to all controls when set
DEFAULT = 0,
-
+
// Basic controls
LABEL, // Used also for: LABELBUTTON
BUTTON,
@@ -1775,7 +1775,7 @@ int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector
{
#define RAYGUI_MIN_SCROLLBAR_WIDTH 40
#define RAYGUI_MIN_SCROLLBAR_HEIGHT 40
-
+
int result = 0;
GuiState state = guiState;
float mouseWheelSpeed = 20.0f; // Default movement speed with mouse wheel
@@ -1806,27 +1806,27 @@ int GuiScrollPanel(Rectangle bounds, const char *text, Rectangle content, Vector
int horizontalScrollBarWidth = hasHorizontalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0;
int verticalScrollBarWidth = hasVerticalScrollBar? GuiGetStyle(LISTVIEW, SCROLLBAR_WIDTH) : 0;
- Rectangle horizontalScrollBar = {
- (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + verticalScrollBarWidth : (float)bounds.x) + GuiGetStyle(DEFAULT, BORDER_WIDTH),
- (float)bounds.y + bounds.height - horizontalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH),
- (float)bounds.width - verticalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH),
- (float)horizontalScrollBarWidth
+ Rectangle horizontalScrollBar = {
+ (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + verticalScrollBarWidth : (float)bounds.x) + GuiGetStyle(DEFAULT, BORDER_WIDTH),
+ (float)bounds.y + bounds.height - horizontalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH),
+ (float)bounds.width - verticalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH),
+ (float)horizontalScrollBarWidth
};
- Rectangle verticalScrollBar = {
- (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) : (float)bounds.x + bounds.width - verticalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH)),
- (float)bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH),
- (float)verticalScrollBarWidth,
- (float)bounds.height - horizontalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH)
+ Rectangle verticalScrollBar = {
+ (float)((GuiGetStyle(LISTVIEW, SCROLLBAR_SIDE) == SCROLLBAR_LEFT_SIDE)? (float)bounds.x + GuiGetStyle(DEFAULT, BORDER_WIDTH) : (float)bounds.x + bounds.width - verticalScrollBarWidth - GuiGetStyle(DEFAULT, BORDER_WIDTH)),
+ (float)bounds.y + GuiGetStyle(DEFAULT, BORDER_WIDTH),
+ (float)verticalScrollBarWidth,
+ (float)bounds.height - horizontalScrollBarWidth - 2*GuiGetStyle(DEFAULT, BORDER_WIDTH)
};
// Make sure scroll bars have a minimum width/height
// NOTE: If content >>> bounds, size could be very small or even 0
- if (horizontalScrollBar.width < RAYGUI_MIN_SCROLLBAR_WIDTH)
+ if (horizontalScrollBar.width < RAYGUI_MIN_SCROLLBAR_WIDTH)
{
horizontalScrollBar.width = RAYGUI_MIN_SCROLLBAR_WIDTH;
mouseWheelSpeed = 30.0f; // TODO: Calculate speed increment based on content.height vs bounds.height
}
- if (verticalScrollBar.height < RAYGUI_MIN_SCROLLBAR_HEIGHT)
+ if (verticalScrollBar.height < RAYGUI_MIN_SCROLLBAR_HEIGHT)
{
verticalScrollBar.height = RAYGUI_MIN_SCROLLBAR_HEIGHT;
mouseWheelSpeed = 30.0f; // TODO: Calculate speed increment based on content.width vs bounds.width
@@ -2155,7 +2155,7 @@ int GuiToggleSlider(Rectangle bounds, const char *text, int *active)
}
else state = STATE_FOCUSED;
}
-
+
if ((*active) && (state != STATE_FOCUSED)) state = STATE_PRESSED;
}
@@ -2625,8 +2625,6 @@ int GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
if (CheckCollisionPointRec(mousePosition, textBounds)) // Mouse hover text
{
float scaleFactor = (float)GuiGetStyle(DEFAULT, TEXT_SIZE)/(float)guiFont.baseSize;
- int codepoint = 0;
- int codepointSize = 0;
int codepointIndex = 0;
float glyphWidth = 0.0f;
float widthToMouseX = 0;
@@ -2646,7 +2644,7 @@ int GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
mouseCursorIndex = i;
break;
}
-
+
widthToMouseX += (glyphWidth + (float)GuiGetStyle(DEFAULT, TEXT_SPACING));
}
@@ -2655,7 +2653,7 @@ int GuiTextBox(Rectangle bounds, char *text, int bufferSize, bool editMode)
if (GetMousePosition().x >= (textBounds.x + textEndWidth - glyphWidth/2))
{
mouseCursor.x = textBounds.x + textEndWidth;
- mouseCursorIndex = strlen(text);
+ mouseCursorIndex = (int)strlen(text);
}
// Place cursor at required index on mouse click
@@ -2743,7 +2741,7 @@ bool GuiTextBoxMulti(Rectangle bounds, char *text, int bufferSize, bool editMode
GuiSetStyle(DEFAULT, TEXT_ALIGNMENT_VERTICAL, TEXT_ALIGN_MIDDLE);
GuiSetStyle(DEFAULT, TEXT_WRAP_MODE, TEXT_WRAP_NONE);
GuiSetStyle(TEXTBOX, TEXT_READONLY, 0);
-
+
return pressed;
}
*/
@@ -2937,6 +2935,7 @@ int GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, in
int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight, float *value, float minValue, float maxValue, int sliderWidth)
{
int result = 0;
+ float oldValue = *value;
GuiState state = guiState;
float temp = (maxValue - minValue)/2.0f;
@@ -3006,6 +3005,10 @@ int GuiSliderPro(Rectangle bounds, const char *textLeft, const char *textRight,
else if (*value < minValue) *value = minValue;
}
+ // Control value change check
+ if(oldValue == *value) result = 0;
+ else result = 1;
+
// Bar limits check
if (sliderWidth > 0) // Slider
{
@@ -3085,7 +3088,7 @@ int GuiProgressBar(Rectangle bounds, const char *textLeft, const char *textRight
if (*value > maxValue) *value = maxValue;
// WARNING: Working with floats could lead to rounding issues
- if ((state != STATE_DISABLED)) progress.width = (float)(*value/(maxValue - minValue))*bounds.width - ((*value >= maxValue) ? (float)(2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)) : 0.0f);
+ if ((state != STATE_DISABLED)) progress.width = (float)(*value/(maxValue - minValue))*bounds.width - ((*value >= maxValue)? (float)(2*GuiGetStyle(PROGRESSBAR, BORDER_WIDTH)) : 0.0f);
//--------------------------------------------------------------------
// Draw control
@@ -3366,8 +3369,7 @@ int GuiColorPanel(Rectangle bounds, const char *text, Color *color)
pickerSelector.x = bounds.x + (float)hsv.y*bounds.width; // HSV: Saturation
pickerSelector.y = bounds.y + (1.0f - (float)hsv.z)*bounds.height; // HSV: Value
- float hue = -1.0f;
- Vector3 maxHue = { hue >= 0.0f ? hue : hsv.x, 1.0f, 1.0f };
+ Vector3 maxHue = { hsv.x, 1.0f, 1.0f };
Vector3 rgbHue = ConvertHSVtoRGB(maxHue);
Color maxHueCol = { (unsigned char)(255.0f*rgbHue.x),
(unsigned char)(255.0f*rgbHue.y),
@@ -3680,8 +3682,7 @@ int GuiColorPanelHSV(Rectangle bounds, const char *text, Vector3 *colorHsv)
pickerSelector.x = bounds.x + (float)colorHsv->y*bounds.width; // HSV: Saturation
pickerSelector.y = bounds.y + (1.0f - (float)colorHsv->z)*bounds.height; // HSV: Value
- float hue = -1.0f;
- Vector3 maxHue = { hue >= 0.0f ? hue : colorHsv->x, 1.0f, 1.0f };
+ Vector3 maxHue = { colorHsv->x, 1.0f, 1.0f };
Vector3 rgbHue = ConvertHSVtoRGB(maxHue);
Color maxHueCol = { (unsigned char)(255.0f*rgbHue.x),
(unsigned char)(255.0f*rgbHue.y),
@@ -3894,12 +3895,14 @@ int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vect
GuiState state = guiState;
Vector2 mousePoint = GetMousePosition();
- Vector2 currentMouseCell = { 0 };
+ Vector2 currentMouseCell = { -1, -1 };
float spaceWidth = spacing/(float)subdivs;
int linesV = (int)(bounds.width/spaceWidth) + 1;
int linesH = (int)(bounds.height/spaceWidth) + 1;
+ int color = GuiGetStyle(DEFAULT, LINE_COLOR);
+
// Update control
//--------------------------------------------------------------------
if ((state != STATE_DISABLED) && !guiLocked && !guiSliderDragging)
@@ -3915,28 +3918,23 @@ int GuiGrid(Rectangle bounds, const char *text, float spacing, int subdivs, Vect
// Draw control
//--------------------------------------------------------------------
- switch (state)
+ if (state == STATE_DISABLED) color = GuiGetStyle(DEFAULT, BORDER_COLOR_DISABLED);
+
+ if (subdivs > 0)
{
- case STATE_NORMAL:
+ // Draw vertical grid lines
+ for (int i = 0; i < linesV; i++)
{
- if (subdivs > 0)
- {
- // Draw vertical grid lines
- for (int i = 0; i < linesV; i++)
- {
- Rectangle lineV = { bounds.x + spacing*i/subdivs, bounds.y, 1, bounds.height };
- GuiDrawRectangle(lineV, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), RAYGUI_GRID_ALPHA));
- }
+ Rectangle lineV = { bounds.x + spacing*i/subdivs, bounds.y, 1, bounds.height };
+ GuiDrawRectangle(lineV, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(color), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(color), RAYGUI_GRID_ALPHA));
+ }
- // Draw horizontal grid lines
- for (int i = 0; i < linesH; i++)
- {
- Rectangle lineH = { bounds.x, bounds.y + spacing*i/subdivs, bounds.width, 1 };
- GuiDrawRectangle(lineH, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(GuiGetStyle(DEFAULT, LINE_COLOR)), RAYGUI_GRID_ALPHA));
- }
- }
- } break;
- default: break;
+ // Draw horizontal grid lines
+ for (int i = 0; i < linesH; i++)
+ {
+ Rectangle lineH = { bounds.x, bounds.y + spacing*i/subdivs, bounds.width, 1 };
+ GuiDrawRectangle(lineH, 0, BLANK, ((i%subdivs) == 0)? GuiFade(GetColor(color), RAYGUI_GRID_ALPHA*4) : GuiFade(GetColor(color), RAYGUI_GRID_ALPHA));
+ }
}
if (mouseCell != NULL) *mouseCell = currentMouseCell;
@@ -4101,7 +4099,7 @@ void GuiLoadStyleDefault(void)
GuiSetStyle(DEFAULT, BORDER_WIDTH, 1);
GuiSetStyle(DEFAULT, TEXT_PADDING, 0);
GuiSetStyle(DEFAULT, TEXT_ALIGNMENT, TEXT_ALIGN_CENTER);
-
+
// Initialize default extended property values
// NOTE: By default, extended property values are initialized to 0
GuiSetStyle(DEFAULT, TEXT_SIZE, 10); // DEFAULT, shared by all controls
@@ -4189,7 +4187,7 @@ const char *GuiIconText(int iconId, const char *text)
return NULL;
#else
static char buffer[1024] = { 0 };
- static char iconBuffer[6] = { 0 };
+ static char iconBuffer[16] = { 0 };
if (text != NULL)
{
@@ -4206,7 +4204,7 @@ const char *GuiIconText(int iconId, const char *text)
}
else
{
- sprintf(iconBuffer, "#%03i#", iconId & 0x1ff);
+ sprintf(iconBuffer, "#%03i#", iconId);
return iconBuffer;
}
@@ -4876,7 +4874,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
if (codepoint == '\n') break; // WARNING: Lines are already processed manually, no need to keep drawing after this codepoint
else
{
- // TODO: There are multiple types of spaces in Unicode,
+ // TODO: There are multiple types of spaces in Unicode,
// maybe it's a good idea to add support for more: http://jkorpela.fi/chars/spaces.html
if ((codepoint != ' ') && (codepoint != '\t')) // Do not draw codepoints with no glyph
{
@@ -4888,7 +4886,7 @@ static void GuiDrawText(const char *text, Rectangle textBounds, int alignment, C
DrawTextCodepoint(guiFont, codepoint, RAYGUI_CLITERAL(Vector2){ textBoundsPosition.x + textOffsetX, textBoundsPosition.y + textOffsetY }, (float)GuiGetStyle(DEFAULT, TEXT_SIZE), GuiFade(tint, guiAlpha));
}
}
- else if ((wrapMode == TEXT_WRAP_CHAR) || (wrapMode == TEXT_WRAP_WORD))
+ else if ((wrapMode == TEXT_WRAP_CHAR) || (wrapMode == TEXT_WRAP_WORD))
{
// Draw only glyphs inside the bounds
if ((textBoundsPosition.y + textOffsetY) <= (textBounds.y + textBounds.height - GuiGetStyle(DEFAULT, TEXT_SIZE)))
diff --git a/raylib/examples/shapes/shapes_bouncing_ball.c b/raylib/examples/shapes/shapes_bouncing_ball.c
index 203d88a..38fade6 100644
--- a/raylib/examples/shapes/shapes_bouncing_ball.c
+++ b/raylib/examples/shapes/shapes_bouncing_ball.c
@@ -67,9 +67,6 @@ int main(void)
// On pause, we draw a blinking message
if (pause && ((framesCounter/30)%2)) DrawText("PAUSED", 350, 200, 30, GRAY);
- DrawCircle(400.5, 300.5, 50, BLACK);
- DrawCircle(528.0, 172.0, 26, BLACK);
-
DrawFPS(10, 10);
EndDrawing();
diff --git a/raylib/examples/shapes/shapes_draw_circle_sector.c b/raylib/examples/shapes/shapes_draw_circle_sector.c
index 1c283e1..90e8e6a 100644
--- a/raylib/examples/shapes/shapes_draw_circle_sector.c
+++ b/raylib/examples/shapes/shapes_draw_circle_sector.c
@@ -70,7 +70,7 @@ int main(void)
GuiSliderBar((Rectangle){ 600, 170, 120, 20}, "Segments", NULL, &segments, 0, 100);
//------------------------------------------------------------------------------
- minSegments = (int)ceilf((endAngle - startAngle) / 90);
+ minSegments = truncf(ceilf((endAngle - startAngle) / 90));
DrawText(TextFormat("MODE: %s", (segments >= minSegments)? "MANUAL" : "AUTO"), 600, 200, 10, (segments >= minSegments)? MAROON : DARKGRAY);
DrawFPS(10, 10);
diff --git a/raylib/examples/shapes/shapes_lines_bezier.c b/raylib/examples/shapes/shapes_lines_bezier.c
index f015768..aaad680 100644
--- a/raylib/examples/shapes/shapes_lines_bezier.c
+++ b/raylib/examples/shapes/shapes_lines_bezier.c
@@ -26,11 +26,10 @@ int main(void)
SetConfigFlags(FLAG_MSAA_4X_HINT);
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - cubic-bezier lines");
- Vector2 start = { 0, 0 };
- Vector2 end = { (float)screenWidth, (float)screenHeight };
-
- Vector2 startControl = { 100, 0 };
- Vector2 endControl = { GetScreenWidth() - 100, GetScreenHeight() };
+ Vector2 startPoint = { 30, 30 };
+ Vector2 endPoint = { (float)screenWidth - 30, (float)screenHeight - 30 };
+ bool moveStartPoint = false;
+ bool moveEndPoint = false;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@@ -40,15 +39,21 @@ int main(void)
{
// Update
//----------------------------------------------------------------------------------
- if (IsKeyDown(KEY_LEFT_CONTROL))
+ Vector2 mouse = GetMousePosition();
+
+ if (CheckCollisionPointCircle(mouse, startPoint, 10.0f) && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) moveStartPoint = true;
+ else if (CheckCollisionPointCircle(mouse, endPoint, 10.0f) && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) moveEndPoint = true;
+
+ if (moveStartPoint)
{
- if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) startControl = GetMousePosition();
- else if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) endControl = GetMousePosition();
+ startPoint = mouse;
+ if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) moveStartPoint = false;
}
- else
+
+ if (moveEndPoint)
{
- if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) start = GetMousePosition();
- else if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) end = GetMousePosition();
+ endPoint = mouse;
+ if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) moveEndPoint = false;
}
//----------------------------------------------------------------------------------
@@ -58,16 +63,14 @@ int main(void)
ClearBackground(RAYWHITE);
- DrawText("USE MOUSE LEFT-RIGHT CLICK to DEFINE LINE START and END POINTS", 15, 20, 20, GRAY);
+ DrawText("MOVE START-END POINTS WITH MOUSE", 15, 20, 20, GRAY);
- //DrawLineBezier(start, end, 2.0f, RED);
-
- DrawLineBezierCubic(start, end, startControl, endControl, 2.0f, RED);
+ // Draw line Cubic Bezier, in-out interpolation (easing), no control points
+ DrawLineBezier(startPoint, endPoint, 4.0f, BLUE);
- DrawLineEx(start, startControl, 1.0, LIGHTGRAY);
- DrawLineEx(end, endControl, 1.0, LIGHTGRAY);
- DrawCircleV(startControl, 10, RED);
- DrawCircleV(endControl, 10, RED);
+ // Draw start-end spline circles with some details
+ DrawCircleV(startPoint, CheckCollisionPointCircle(mouse, startPoint, 10.0f)? 14 : 8, moveStartPoint? RED : BLUE);
+ DrawCircleV(endPoint, CheckCollisionPointCircle(mouse, endPoint, 10.0f)? 14 : 8, moveEndPoint? RED : BLUE);
EndDrawing();
//----------------------------------------------------------------------------------
diff --git a/raylib/examples/shapes/shapes_lines_bezier.png b/raylib/examples/shapes/shapes_lines_bezier.png
index 390a49a..aa5edf3 100644
--- a/raylib/examples/shapes/shapes_lines_bezier.png
+++ b/raylib/examples/shapes/shapes_lines_bezier.png
Binary files differ
diff --git a/raylib/examples/shapes/shapes_lines_splines.c b/raylib/examples/shapes/shapes_lines_splines.c
deleted file mode 100644
index c020c60..0000000
--- a/raylib/examples/shapes/shapes_lines_splines.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*******************************************************************************************
-*
-* raylib [shapes] example - splines drawing
-*
-* Example originally created with raylib 4.6-dev, last time updated with raylib 4.6-dev
-*
-* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
-* BSD-like license that allows static linking with closed source software
-*
-* Copyright (c) 2023 Ramon Santamaria (@raysan5)
-*
-********************************************************************************************/
-
-#include "raylib.h"
-
-#define MAX_CONTROL_POINTS 32
-
-typedef struct {
- Vector2 start;
- Vector2 end;
-} ControlPoint;
-
-//------------------------------------------------------------------------------------
-// Program main entry point
-//------------------------------------------------------------------------------------
-int main(void)
-{
- // Initialization
- //--------------------------------------------------------------------------------------
- const int screenWidth = 800;
- const int screenHeight = 450;
-
- SetConfigFlags(FLAG_MSAA_4X_HINT);
- InitWindow(screenWidth, screenHeight, "raylib [shapes] example - splines drawing");
-
- Vector2 points[MAX_CONTROL_POINTS] = {
- { 100.0f, 200.0f },
- { 300.0f, 400.0f },
- { 500.0f, 300.0f },
- { 700.0f, 100.0f },
- { 200.0f, 100.0f },
- };
-
- int pointCount = 5;
- int selectedPoint = -1;
-
- int splineType = 0; // 0-Linear, 1-BSpline, 2-CatmullRom, 3-Bezier
-
- // Cubic Bezier control points
- ControlPoint control[MAX_CONTROL_POINTS] = { 0 };
- for (int i = 0; i < pointCount - 1; i++)
- {
- control[i].start = points[i];
- control[i].end = points[i + 1];
- }
-
- SetTargetFPS(60); // Set our game to run at 60 frames-per-second
- //--------------------------------------------------------------------------------------
-
- // Main game loop
- while (!WindowShouldClose()) // Detect window close button or ESC key
- {
- // Update
- //----------------------------------------------------------------------------------
- // Points movement logic
- if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON) && (pointCount < MAX_CONTROL_POINTS))
- {
- points[pointCount] = GetMousePosition();
- pointCount++;
- }
-
- for (int i = 0; i < pointCount; i++)
- {
- if (IsMouseButtonDown(MOUSE_LEFT_BUTTON) && CheckCollisionPointCircle(GetMousePosition(), points[i], 6.0f))
- {
- selectedPoint = i;
- break;
- }
- }
-
- if (selectedPoint >= 0)
- {
- points[selectedPoint] = GetMousePosition();
- if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) selectedPoint = -1;
- }
-
- // TODO: Cubic Bezier spline control points logic
-
-
- // Spline selection logic
- if (IsKeyPressed(KEY_ONE)) splineType = 0;
- else if (IsKeyPressed(KEY_TWO)) splineType = 1;
- else if (IsKeyPressed(KEY_THREE)) splineType = 2;
- else if (IsKeyPressed(KEY_FOUR)) splineType = 3;
- //----------------------------------------------------------------------------------
-
- // Draw
- //----------------------------------------------------------------------------------
- BeginDrawing();
-
- ClearBackground(RAYWHITE);
-
- if (splineType == 0) // Linear
- {
- // Draw linear spline
- for (int i = 0; i < pointCount - 1; i++)
- {
- DrawLineEx(points[i], points[i + 1], 2.0f, RED);
- }
- }
- else if (splineType == 1) // B-Spline
- {
- // Draw b-spline
- DrawLineBSpline(points, pointCount, 2.0f, RED);
- //for (int i = 0; i < (pointCount - 3); i++) DrawLineBSplineSegment(points[i], points[i + 1], points[i + 2], points[i + 3], 24.0f, BLUE);
- }
- else if (splineType == 2) // CatmullRom Spline
- {
- // Draw spline: catmull-rom
- DrawLineCatmullRom(points, pointCount, 2.0f, RED);
- //for (int i = 0; i < (pointCount - 3); i++) DrawLineCatmullRomSegment(points[i], points[i + 1], points[i + 2], points[i + 3], 24.0f, Fade(BLUE, 0.4f));
- }
- else if (splineType == 3) // Cubic Bezier
- {
- // Draw line bezier cubic (with control points)
- for (int i = 0; i < pointCount - 1; i++)
- {
- DrawLineBezierCubic(points[i], points[i + 1], control[i].start, control[i + 1].end, 2.0f, RED);
-
- // TODO: Every cubic bezier point should have two control points
- DrawCircleV(control[i].start, 4, GOLD);
- DrawCircleV(control[i].end, 4, GOLD);
- DrawLineEx(points[i], control[i].start, 1.0, LIGHTGRAY);
- DrawLineEx(points[i + 1], control[i].end, 1.0, LIGHTGRAY);
- }
- }
-
- // Draw control points
- for (int i = 0; i < pointCount; i++)
- {
- DrawCircleV(points[i], 6.0f, RED);
- if ((splineType != 0) && (i < pointCount - 1)) DrawLineV(points[i], points[i + 1], GRAY);
- }
-
- EndDrawing();
- //----------------------------------------------------------------------------------
- }
-
- // De-Initialization
- //--------------------------------------------------------------------------------------
- CloseWindow(); // Close window and OpenGL context
- //--------------------------------------------------------------------------------------
-
- return 0;
-} \ No newline at end of file
diff --git a/raylib/examples/shapes/shapes_splines_drawing.c b/raylib/examples/shapes/shapes_splines_drawing.c
new file mode 100644
index 0000000..8df5f09
--- /dev/null
+++ b/raylib/examples/shapes/shapes_splines_drawing.c
@@ -0,0 +1,247 @@
+/*******************************************************************************************
+*
+* raylib [shapes] example - splines drawing
+*
+* Example originally created with raylib 5.0, last time updated with raylib 5.0
+*
+* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
+* BSD-like license that allows static linking with closed source software
+*
+* Copyright (c) 2023 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#define RAYGUI_IMPLEMENTATION
+#include "raygui.h" // Required for UI controls
+
+#include <stdlib.h> // Required for: NULL
+
+#define MAX_SPLINE_POINTS 32
+
+// Cubic Bezier spline control points
+// NOTE: Every segment has two control points
+typedef struct {
+ Vector2 start;
+ Vector2 end;
+} ControlPoint;
+
+// Spline types
+typedef enum {
+ SPLINE_LINEAR = 0, // Linear
+ SPLINE_BASIS, // B-Spline
+ SPLINE_CATMULLROM, // Catmull-Rom
+ SPLINE_BEZIER // Cubic Bezier
+} SplineType;
+
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main(void)
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ const int screenWidth = 800;
+ const int screenHeight = 450;
+
+ SetConfigFlags(FLAG_MSAA_4X_HINT);
+ InitWindow(screenWidth, screenHeight, "raylib [shapes] example - splines drawing");
+
+ Vector2 points[MAX_SPLINE_POINTS] = {
+ { 50.0f, 400.0f },
+ { 160.0f, 220.0f },
+ { 340.0f, 380.0f },
+ { 520.0f, 60.0f },
+ { 710.0f, 260.0f },
+ };
+
+ int pointCount = 5;
+ int selectedPoint = -1;
+ int focusedPoint = -1;
+ Vector2 *selectedControlPoint = NULL;
+ Vector2 *focusedControlPoint = NULL;
+
+ // Cubic Bezier control points initialization
+ ControlPoint control[MAX_SPLINE_POINTS] = { 0 };
+ for (int i = 0; i < pointCount - 1; i++)
+ {
+ control[i].start = (Vector2){ points[i].x + 50, points[i].y };
+ control[i].end = (Vector2){ points[i + 1].x - 50, points[i + 1].y };
+ }
+
+ // Spline config variables
+ float splineThickness = 8.0f;
+ int splineTypeActive = SPLINE_LINEAR; // 0-Linear, 1-BSpline, 2-CatmullRom, 3-Bezier
+ bool splineTypeEditMode = false;
+ bool splineHelpersActive = true;
+
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // Spline points creation logic (at the end of spline)
+ if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON) && (pointCount < MAX_SPLINE_POINTS))
+ {
+ points[pointCount] = GetMousePosition();
+ pointCount++;
+ }
+
+ // Spline point focus and selection logic
+ for (int i = 0; i < pointCount; i++)
+ {
+ if (CheckCollisionPointCircle(GetMousePosition(), points[i], 8.0f))
+ {
+ focusedPoint = i;
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) selectedPoint = i;
+ break;
+ }
+ else focusedPoint = -1;
+ }
+
+ // Spline point movement logic
+ if (selectedPoint >= 0)
+ {
+ points[selectedPoint] = GetMousePosition();
+ if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) selectedPoint = -1;
+ }
+
+ // Cubic Bezier spline control points logic
+ if ((splineTypeActive == SPLINE_BEZIER) && (focusedPoint == -1))
+ {
+ // Spline control point focus and selection logic
+ for (int i = 0; i < pointCount; i++)
+ {
+ if (CheckCollisionPointCircle(GetMousePosition(), control[i].start, 6.0f))
+ {
+ focusedControlPoint = &control[i].start;
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) selectedControlPoint = &control[i].start;
+ break;
+ }
+ else if (CheckCollisionPointCircle(GetMousePosition(), control[i].end, 6.0f))
+ {
+ focusedControlPoint = &control[i].end;
+ if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) selectedControlPoint = &control[i].end;
+ break;
+ }
+ else focusedControlPoint = NULL;
+ }
+
+ // Spline control point movement logic
+ if (selectedControlPoint != NULL)
+ {
+ *selectedControlPoint = GetMousePosition();
+ if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) selectedControlPoint = NULL;
+ }
+ }
+
+ // Spline selection logic
+ if (IsKeyPressed(KEY_ONE)) splineTypeActive = 0;
+ else if (IsKeyPressed(KEY_TWO)) splineTypeActive = 1;
+ else if (IsKeyPressed(KEY_THREE)) splineTypeActive = 2;
+ else if (IsKeyPressed(KEY_FOUR)) splineTypeActive = 3;
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ if (splineTypeActive == SPLINE_LINEAR)
+ {
+ // Draw spline: linear
+ DrawSplineLinear(points, pointCount, splineThickness, RED);
+ }
+ else if (splineTypeActive == SPLINE_BASIS)
+ {
+ // Draw spline: basis
+ DrawSplineBasis(points, pointCount, splineThickness, RED); // Provide connected points array
+
+ /*
+ for (int i = 0; i < (pointCount - 3); i++)
+ {
+ // Drawing individual segments, not considering thickness connection compensation
+ DrawSplineSegmentBasis(points[i], points[i + 1], points[i + 2], points[i + 3], splineThickness, MAROON);
+ }
+ */
+ }
+ else if (splineTypeActive == SPLINE_CATMULLROM)
+ {
+ // Draw spline: catmull-rom
+ DrawSplineCatmullRom(points, pointCount, splineThickness, RED); // Provide connected points array
+
+ /*
+ for (int i = 0; i < (pointCount - 3); i++)
+ {
+ // Drawing individual segments, not considering thickness connection compensation
+ DrawSplineSegmentCatmullRom(points[i], points[i + 1], points[i + 2], points[i + 3], splineThickness, MAROON);
+ }
+ */
+ }
+ else if (splineTypeActive == SPLINE_BEZIER)
+ {
+ // Draw spline: cubic-bezier (with control points)
+ for (int i = 0; i < pointCount - 1; i++)
+ {
+ // Drawing individual segments, not considering thickness connection compensation
+ DrawSplineSegmentBezierCubic(points[i], control[i].start, control[i].end, points[i + 1], splineThickness, RED);
+
+ // Every cubic bezier point should have two control points
+ DrawCircleV(control[i].start, 6, GOLD);
+ DrawCircleV(control[i].end, 6, GOLD);
+ if (focusedControlPoint == &control[i].start) DrawCircleV(control[i].start, 8, GREEN);
+ else if (focusedControlPoint == &control[i].end) DrawCircleV(control[i].end, 8, GREEN);
+ DrawLineEx(points[i], control[i].start, 1.0f, LIGHTGRAY);
+ DrawLineEx(points[i + 1], control[i].end, 1.0f, LIGHTGRAY);
+
+ // Draw spline control lines
+ DrawLineV(points[i], control[i].start, GRAY);
+ //DrawLineV(control[i].start, control[i].end, LIGHTGRAY);
+ DrawLineV(control[i].end, points[i + 1], GRAY);
+ }
+ }
+
+ if (splineHelpersActive)
+ {
+ // Draw spline point helpers
+ for (int i = 0; i < pointCount; i++)
+ {
+ DrawCircleLinesV(points[i], (focusedPoint == i)? 12.0f : 8.0f, (focusedPoint == i)? BLUE: DARKBLUE);
+ if ((splineTypeActive != SPLINE_LINEAR) &&
+ (splineTypeActive != SPLINE_BEZIER) &&
+ (i < pointCount - 1)) DrawLineV(points[i], points[i + 1], GRAY);
+
+ DrawText(TextFormat("[%.0f, %.0f]", points[i].x, points[i].y), points[i].x, points[i].y + 10, 10, BLACK);
+ }
+ }
+
+ // Check all possible UI states that require controls lock
+ if (splineTypeEditMode) GuiLock();
+
+ // Draw spline config
+ GuiLabel((Rectangle){ 12, 62, 140, 24 }, TextFormat("Spline thickness: %i", (int)splineThickness));
+ GuiSliderBar((Rectangle){ 12, 60 + 24, 140, 16 }, NULL, NULL, &splineThickness, 1.0f, 40.0f);
+
+ GuiCheckBox((Rectangle){ 12, 110, 20, 20 }, "Show point helpers", &splineHelpersActive);
+
+ GuiUnlock();
+
+ GuiLabel((Rectangle){ 12, 10, 140, 24 }, "Spline type:");
+ if (GuiDropdownBox((Rectangle){ 12, 8 + 24, 140, 28 }, "LINEAR;BSPLINE;CATMULLROM;BEZIER", &splineTypeActive, splineTypeEditMode)) splineTypeEditMode = !splineTypeEditMode;
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+} \ No newline at end of file
diff --git a/raylib/examples/shapes/shapes_splines_drawing.png b/raylib/examples/shapes/shapes_splines_drawing.png
new file mode 100644
index 0000000..686f04c
--- /dev/null
+++ b/raylib/examples/shapes/shapes_splines_drawing.png
Binary files differ
diff --git a/raylib/examples/shapes/shapes_top_down_lights.c b/raylib/examples/shapes/shapes_top_down_lights.c
index b09137c..f22cf3c 100644
--- a/raylib/examples/shapes/shapes_top_down_lights.c
+++ b/raylib/examples/shapes/shapes_top_down_lights.c
@@ -335,6 +335,7 @@ int main(void)
DrawFPS(screenWidth - 80, 10);
DrawText("Drag to move light #1", 10, 10, 10, DARKGREEN);
DrawText("Right click to add new light", 10, 30, 10, DARKGREEN);
+
EndDrawing();
//----------------------------------------------------------------------------------
}