From 74f7112614e74cd243af8a2941839fb33cf275d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robin=20=E2=9D=A4=EF=B8=8F?= Date: Fri, 14 Nov 2025 11:09:30 -0500 Subject: [PATCH] [examples] Added: `shapes_rlgl_triangle` example (#5353) * [examples] Added: `shapes_rlgl_triangle` example * correct name * formatting --- examples/shapes/shapes_rlgl_triangle.c | 189 +++++++++++++++++++++++ examples/shapes/shapes_rlgl_triangle.png | Bin 0 -> 22402 bytes 2 files changed, 189 insertions(+) create mode 100644 examples/shapes/shapes_rlgl_triangle.c create mode 100644 examples/shapes/shapes_rlgl_triangle.png diff --git a/examples/shapes/shapes_rlgl_triangle.c b/examples/shapes/shapes_rlgl_triangle.c new file mode 100644 index 000000000..9174110e4 --- /dev/null +++ b/examples/shapes/shapes_rlgl_triangle.c @@ -0,0 +1,189 @@ +/******************************************************************************************* +* +* raylib [shapes] example - rlgl triangle +* +* Example complexity rating: [★★☆☆] 2/4 +* +* Example originally created with raylib 5.6-dev, last time updated with raylib 5.6-dev +* +* Example contributed by Robin (@RobinsAviary) and reviewed by Ramon Santamaria (@raysan5) +* +* 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) 2025-2025 Robin (@RobinsAviary) +* +********************************************************************************************/ + +#include "raylib.h" +#include "rlgl.h" +#include "raymath.h" + +//------------------------------------------------------------------------------------ +// 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 - rlgl triangle"); + + // Starting postions and rendered triangle positions + Vector2 startingPositions[] = {{ 400.0f, 150.0f }, { 300.0f, 300.0f }, { 500.0f, 300.0f }}; + Vector2 trianglePositions[] = { startingPositions[0], startingPositions[1], startingPositions[2] }; + + // Currently selected vertex, -1 means none + int triangleIndex = -1; + + SetTargetFPS(60); + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + // Reset index on release + if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) + { + triangleIndex = -1; + } + + // If the user has selected a vertex, offset it by the mouse's delta this frame + if (triangleIndex != -1) + { + Vector2 *position = &trianglePositions[triangleIndex]; + + Vector2 mouseDelta = GetMouseDelta(); + position->x += mouseDelta.x; + position->y += mouseDelta.y; + } + + // Enable/disable backface culling (2-sided triangles, slower to render) + if (IsKeyPressed(KEY_LEFT)) + { + rlEnableBackfaceCulling(); + } + + if (IsKeyPressed(KEY_RIGHT)) + { + rlDisableBackfaceCulling(); + } + + // Reset triangle vertices to starting positions and reset backface culling + if (IsKeyPressed(KEY_R)) + { + trianglePositions[0] = startingPositions[0]; + trianglePositions[1] = startingPositions[1]; + trianglePositions[2] = startingPositions[2]; + + rlEnableBackfaceCulling(); + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + if (IsKeyDown(KEY_SPACE)) + { + // Draw triangle with lines + rlBegin(RL_LINES); + // Three lines, six points + // Define color for next vertex + rlColor4ub(255, 0, 0, 255); + // Define vertex + rlVertex2f(trianglePositions[0].x, trianglePositions[0].y); + rlColor4ub(0, 255, 0, 255); + rlVertex2f(trianglePositions[1].x, trianglePositions[1].y); + + rlColor4ub(0, 255, 0, 255); + rlVertex2f(trianglePositions[1].x, trianglePositions[1].y); + rlColor4ub(0, 0, 255, 255); + rlVertex2f(trianglePositions[2].x, trianglePositions[2].y); + + rlColor4ub(0, 0, 255, 255); + rlVertex2f(trianglePositions[2].x, trianglePositions[2].y); + rlColor4ub(255, 0, 0, 255); + rlVertex2f(trianglePositions[0].x, trianglePositions[0].y); + rlEnd(); + } + else + { + // Draw triangle as a triangle + rlBegin(RL_TRIANGLES); + // One triangle, three points + // Define color for next vertex + rlColor4ub(255, 0, 0, 255); + // Define vertex + rlVertex2f(trianglePositions[0].x, trianglePositions[0].y); + rlColor4ub(0, 255, 0, 255); + rlVertex2f(trianglePositions[1].x, trianglePositions[1].y); + rlColor4ub(0, 0, 255, 255); + rlVertex2f(trianglePositions[2].x, trianglePositions[2].y); + rlEnd(); + } + + // Render the vertex handles, reacting to mouse movement/input + for (unsigned int i = 0; i < 3; i++) + { + Vector2 position = trianglePositions[i]; + + float size = 4.0f; + + Vector2 mousePosition = GetMousePosition(); + + // If the cursor is within the handle circle + if (Vector2Distance(mousePosition, position) < size) + { + float fillAlpha = 0.0f; + if (triangleIndex == -1) + { + fillAlpha = 0.5f; + } + + // If handle selected/clicked + if (i == triangleIndex) + { + fillAlpha = 1.0f; + } + + // If clicked, set selected index to handle index + if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) + { + triangleIndex = i; + } + + // If visible, draw DARKGRAY circle with varying alpha. + if (fillAlpha > 0.0f) + { + Color fillColor = ColorAlpha(DARKGRAY, fillAlpha); + + DrawCircleV(position, size, fillColor); + } + } + + // Draw handle outline + DrawCircleLinesV(position, size, BLACK); + } + + // Draw controls + DrawText("space for lines\nleft for backface culling\nright for no backface culling\nclick and drag points\nr to reset", 10, 10, 20, DARKGRAY); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/examples/shapes/shapes_rlgl_triangle.png b/examples/shapes/shapes_rlgl_triangle.png new file mode 100644 index 0000000000000000000000000000000000000000..9fec558ff1e337157e488886e18238018cf4907c GIT binary patch literal 22402 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