Procházet zdrojové kódy

REVIEWED: Example: `textures_textured_curve`

Ray před 2 roky
rodič
revize
89698844a1

+ 0 - 0
examples/textures/resources/roadTexture_01.png → examples/textures/resources/road.png


+ 152 - 134
examples/textures/textures_textured_curve.c

@@ -2,145 +2,219 @@
 *
 *   raylib [textures] example - Draw a texture along a segmented curve
 *
-*   Example originally created with raylib 4.5
+*   Example originally created with raylib 4.5-dev
 *
 *   Example contributed by Jeffery Myers 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) 2019-2022 Jeffery Myers and Ramon Santamaria (@raysan5)
+*   Copyright (c) 2022 Jeffery Myers and Ramon Santamaria (@raysan5)
 *
 ********************************************************************************************/
 
 
 #include "raylib.h"
+
 #include "raymath.h"
 #include "rlgl.h"
 
-Texture RoadTexture = { 0 };
+#include <math.h>           // Required for: powf()
+#include <stdlib.h>         // Required for: NULL
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+static Texture texRoad = { 0 };
+
+static bool showCurve = false;
+
+static float curveWidth = 50;
+static int curveSegments = 24;
+
+static Vector2 curveStartPosition = { 0 };
+static Vector2 curveStartPositionTangent = { 0 };
+
+static Vector2 curveEndPosition = { 0 };
+static Vector2 curveEndPositionTangent = { 0 };
+
+static Vector2 *curveSelectedPoint = NULL;
+
+//----------------------------------------------------------------------------------
+// Module Functions Declaration
+//----------------------------------------------------------------------------------
+static void UpdateOptions(void);
+static void UpdateCurve(void);
+static void DrawCurve(void);
+static void DrawTexturedCurve(void);
+
 
-bool ShowCurve = false;
+//------------------------------------------------------------------------------------
+// Program main entry point
+//------------------------------------------------------------------------------------
+int main()
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    const int screenWidth = 800;
+    const int screenHeight = 450;
+
+	SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT);
+	InitWindow(screenWidth, screenHeight, "raylib [textures] examples - textured curve");
+
+	// Load the road texture
+	texRoad = LoadTexture("resources/road.png");
+    SetTextureFilter(texRoad, TEXTURE_FILTER_BILINEAR);
+
+	// Setup the curve
+	curveStartPosition = (Vector2){ 80, 100 };
+	curveStartPositionTangent = (Vector2){ 100, 300 };
+
+	curveEndPosition = (Vector2){ 700, 350 };
+	curveEndPositionTangent = (Vector2){ 600, 100 };
+
+    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
+        //----------------------------------------------------------------------------------
+		UpdateCurve();
+		UpdateOptions();
 
-float Width = 50;
-int Segments = 24;
+        //----------------------------------------------------------------------------------
 
-Vector2 SP = { 0 };
-Vector2 SPTangent = { 0 };
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
 
-Vector2 EP = { 0 };
-Vector2 EPTangent = { 0 };
+            ClearBackground(RAYWHITE);
 
-Vector2* Selected = NULL;
+            DrawTexturedCurve();
+            DrawCurve();
+        
+            DrawText("Drag points to move curve, press SPACE to show/hide base curve", 10, 10, 10, DARKGRAY);
+            DrawText(TextFormat("Curve width: %2.0f (Use + and - to adjust)", curveWidth), 10, 30, 10, DARKGRAY);
+            DrawText(TextFormat("Curve segments: %d (Use LEFT and RIGHT to adjust)", curveSegments), 10, 50, 10, DARKGRAY);
+            
+		EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
 
-void DrawCurve()
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+	UnloadTexture(texRoad);
+    
+    CloseWindow();              // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+
+    return 0;
+}
+
+//----------------------------------------------------------------------------------
+// Module Functions Definition
+//----------------------------------------------------------------------------------
+static void DrawCurve(void)
 {
-	if (ShowCurve)
-		DrawLineBezierCubic(SP, EP, SPTangent, EPTangent, 2, BLUE);
+	if (showCurve) DrawLineBezierCubic(curveStartPosition, curveEndPosition, curveStartPositionTangent, curveEndPositionTangent, 2, BLUE);
 
-	// draw the various control points and highlight where the mouse is
-	DrawLineV(SP, SPTangent, SKYBLUE);
-	DrawLineV(EP, EPTangent, PURPLE);
+	// Draw the various control points and highlight where the mouse is
+	DrawLineV(curveStartPosition, curveStartPositionTangent, SKYBLUE);
+	DrawLineV(curveEndPosition, curveEndPositionTangent, PURPLE);
 	Vector2 mouse = GetMousePosition();
 
-	if (CheckCollisionPointCircle(mouse, SP, 6))
-		DrawCircleV(SP, 7, YELLOW);
-	DrawCircleV(SP, 5, RED);
+	if (CheckCollisionPointCircle(mouse, curveStartPosition, 6)) DrawCircleV(curveStartPosition, 7, YELLOW);
+	DrawCircleV(curveStartPosition, 5, RED);
 
-	if (CheckCollisionPointCircle(mouse, SPTangent, 6))
-		DrawCircleV(SPTangent, 7, YELLOW);
-	DrawCircleV(SPTangent, 5, MAROON);
+	if (CheckCollisionPointCircle(mouse, curveStartPositionTangent, 6)) DrawCircleV(curveStartPositionTangent, 7, YELLOW);
+	DrawCircleV(curveStartPositionTangent, 5, MAROON);
 
-	if (CheckCollisionPointCircle(mouse, EP, 6))
-		DrawCircleV(EP, 7, YELLOW);
-	DrawCircleV(EP, 5, GREEN);
+	if (CheckCollisionPointCircle(mouse, curveEndPosition, 6)) DrawCircleV(curveEndPosition, 7, YELLOW);
+	DrawCircleV(curveEndPosition, 5, GREEN);
 
-	if (CheckCollisionPointCircle(mouse, EPTangent, 6))
-		DrawCircleV(EPTangent, 7, YELLOW);
-	DrawCircleV(EPTangent, 5, DARKGREEN);
+	if (CheckCollisionPointCircle(mouse, curveEndPositionTangent, 6)) DrawCircleV(curveEndPositionTangent, 7, YELLOW);
+	DrawCircleV(curveEndPositionTangent, 5, DARKGREEN);
 }
 
-void EditCurve()
+static void UpdateCurve(void)
 {
-	// if the mouse is not down, we are not editing the curve so clear the selection
+	// If the mouse is not down, we are not editing the curve so clear the selection
 	if (!IsMouseButtonDown(MOUSE_LEFT_BUTTON))
 	{
-		Selected = NULL;
+		curveSelectedPoint = NULL;
 		return;
 	}
 
-	// if a point was selected, move it
-	if (Selected)
+	// If a point was selected, move it
+	if (curveSelectedPoint)
 	{
-		*Selected = Vector2Add(*Selected, GetMouseDelta());
+		*curveSelectedPoint = Vector2Add(*curveSelectedPoint, GetMouseDelta());
 		return;
 	}
 
-	// the mouse is down, and nothing was selected, so see if anything was picked
+	// The mouse is down, and nothing was selected, so see if anything was picked
 	Vector2 mouse = GetMousePosition();
 
-	if (CheckCollisionPointCircle(mouse, SP, 6))
-		Selected = &SP;
-	else if (CheckCollisionPointCircle(mouse, SPTangent, 6))
-		Selected = &SPTangent;
-	else if (CheckCollisionPointCircle(mouse, EP, 6))
-		Selected = &EP;
-	else if (CheckCollisionPointCircle(mouse, EPTangent, 6))
-		Selected = &EPTangent;
+	if (CheckCollisionPointCircle(mouse, curveStartPosition, 6)) curveSelectedPoint = &curveStartPosition;
+	else if (CheckCollisionPointCircle(mouse, curveStartPositionTangent, 6)) curveSelectedPoint = &curveStartPositionTangent;
+	else if (CheckCollisionPointCircle(mouse, curveEndPosition, 6)) curveSelectedPoint = &curveEndPosition;
+	else if (CheckCollisionPointCircle(mouse, curveEndPositionTangent, 6)) curveSelectedPoint = &curveEndPositionTangent;
 }
 
-void DrawTexturedCurve()
+static void DrawTexturedCurve(void)
 {
-	const float step = 1.0f / Segments;
+	const float step = 1.0f/curveSegments;
 
-	Vector2 previous = SP;
+	Vector2 previous = curveStartPosition;
 	Vector2 previousTangent = { 0 };
 	float previousV = 0;
 
-	// we can't compute a tangent for the first point, so we need to reuse the tangent from the first segment
+	// We can't compute a tangent for the first point, so we need to reuse the tangent from the first segment
 	bool tangentSet = false;
 
 	Vector2 current = { 0 };
 	float t = 0.0f;
 
-	for (int i = 1; i <= Segments; i++)
+	for (int i = 1; i <= curveSegments; i++)
 	{
-		// segment the curve
-		t = step * i;
+		// Segment the curve
+		t = step*i;
 		float a = powf(1 - t, 3);
-		float b = 3 * powf(1 - t, 2) * t;
-		float c = 3 * (1 - t) * powf(t, 2);
+		float b = 3*powf(1 - t, 2)*t;
+		float c = 3*(1 - t)*powf(t, 2);
 		float d = powf(t, 3);
 
-		// compute the endpoint for this segment
-		current.y = a * SP.y + b * SPTangent.y + c * EPTangent.y + d * EP.y;
-		current.x = a * SP.x + b * SPTangent.x + c * EPTangent.x + d * EP.x;
+		// Compute the endpoint for this segment
+		current.y = a*curveStartPosition.y + b*curveStartPositionTangent.y + c*curveEndPositionTangent.y + d*curveEndPosition.y;
+		current.x = a*curveStartPosition.x + b*curveStartPositionTangent.x + c*curveEndPositionTangent.x + d*curveEndPosition.x;
 
-		// vector from previous to current
+		// Vector from previous to current
 		Vector2 delta = { current.x - previous.x, current.y - previous.y };
 
-		// the right hand normal to the delta vector
+		// The right hand normal to the delta vector
 		Vector2 normal = Vector2Normalize((Vector2){ -delta.y, delta.x });
 
-		// the v texture coordinate of the segment (add up the length of all the segments so far)
+		// The v texture coordinate of the segment (add up the length of all the segments so far)
 		float v = previousV + Vector2Length(delta);
 
-		// make sure the start point has a normal
+		// Make sure the start point has a normal
 		if (!tangentSet)
 		{
 			previousTangent = normal;
 			tangentSet = true;
 		}
 
-		// extend out the normals from the previous and current points to get the quad for this segment
-		Vector2 prevPosNormal = Vector2Add(previous, Vector2Scale(previousTangent, Width));
-		Vector2 prevNegNormal = Vector2Add(previous, Vector2Scale(previousTangent, -Width));
+		// Extend out the normals from the previous and current points to get the quad for this segment
+		Vector2 prevPosNormal = Vector2Add(previous, Vector2Scale(previousTangent, curveWidth));
+		Vector2 prevNegNormal = Vector2Add(previous, Vector2Scale(previousTangent, -curveWidth));
 
-		Vector2 currentPosNormal = Vector2Add(current, Vector2Scale(normal, Width));
-		Vector2 currentNegNormal = Vector2Add(current, Vector2Scale(normal, -Width));
+		Vector2 currentPosNormal = Vector2Add(current, Vector2Scale(normal, curveWidth));
+		Vector2 currentNegNormal = Vector2Add(current, Vector2Scale(normal, -curveWidth));
 
-		// draw the segment as a quad
-		rlSetTexture(RoadTexture.id);
+		// Draw the segment as a quad
+		rlSetTexture(texRoad.id);
 		rlBegin(RL_QUADS);
 
 		rlColor4ub(255,255,255,255);
@@ -160,82 +234,26 @@ void DrawTexturedCurve()
 
 		rlEnd();
 
-		// the current step is the start of the next step
+		// The current step is the start of the next step
 		previous = current;
 		previousTangent = normal;
 		previousV = v;
 	}
 }
 
-void UpdateOptions()
+static void UpdateOptions(void)
 {
-	if (IsKeyPressed(KEY_SPACE))
-		ShowCurve = !ShowCurve;
-
-	// width
-	if (IsKeyPressed(KEY_EQUAL))
-		Width += 2;
-
-	if (IsKeyPressed(KEY_MINUS))
-		Width -= 2;
-
-	if (Width < 2)
-		Width = 2;
+	if (IsKeyPressed(KEY_SPACE)) showCurve = !showCurve;
 
-	// segments
+	// Update with
+	if (IsKeyPressed(KEY_EQUAL)) curveWidth += 2;
+	if (IsKeyPressed(KEY_MINUS)) curveWidth -= 2;
 
-	if (IsKeyPressed(KEY_LEFT_BRACKET))
-		Segments -= 2;
+	if (curveWidth < 2) curveWidth = 2;
 
-	if (IsKeyPressed(KEY_RIGHT_BRACKET))
-		Segments += 2;
+	// Update segments
+	if (IsKeyPressed(KEY_LEFT)) curveSegments -= 2;
+	if (IsKeyPressed(KEY_RIGHT)) curveSegments += 2;
 
-	if (Segments < 2)
-		Segments = 2;
+	if (curveSegments < 2) curveSegments = 2;
 }
-
-int main ()
-{
-	// set up the window
-	SetConfigFlags(FLAG_VSYNC_HINT);
-	InitWindow(1280, 800, "raylib [textures] examples - textured curve");
-	SetTargetFPS(144);
-
-	// load the road texture
-	RoadTexture = LoadTexture("resources/roadTexture_01.png");
-
-	// setup the curve
-	SP = (Vector2){ 80, 400 };
-	SPTangent = (Vector2){ 600, 100 };
-
-	EP = (Vector2){ 1200, 400 };
-	EPTangent = (Vector2){ 600, 700 };
-
-	// game loop
-	while (!WindowShouldClose())
-	{
-		EditCurve();
-		UpdateOptions();
-
-		BeginDrawing();
-
-		ClearBackground(BLACK);
-
-		DrawTexturedCurve();
-		DrawCurve();
-	
-		DrawText("Drag points to move curve, press space to show/hide base curve", 10, 0, 20, WHITE);
-		DrawText(TextFormat("Width %2.0f + and - to adjust", Width), 10, 20, 20, WHITE);
-		DrawText(TextFormat("Segments %d [ and ] to adjust", Segments), 10, 40, 20, WHITE);
-		DrawFPS(10, 60);
-
-		EndDrawing();
-	}
-
-	// cleanup
-	UnloadTexture(RoadTexture);
-	CloseWindow();
-	return 0;
-}
-
-   

binární
examples/textures/textures_textured_curve.png