From e39e45824db79623fa4c7b55a606ca79fc27659e Mon Sep 17 00:00:00 2001 From: Lambert Wang <77245864+lambert-wang@users.noreply.github.com> Date: Mon, 10 May 2021 11:08:58 -0700 Subject: [PATCH] Add RenderPolyLinesEx routine (#1758) Co-authored-by: Lambert Wang --- examples/shapes/shapes_basic_shapes.c | 21 ++++--- src/raylib.h | 5 +- src/shapes.c | 86 +++++++++++++++++++++++---- 3 files changed, 92 insertions(+), 20 deletions(-) diff --git a/examples/shapes/shapes_basic_shapes.c b/examples/shapes/shapes_basic_shapes.c index cd165d2e6..086de774a 100644 --- a/examples/shapes/shapes_basic_shapes.c +++ b/examples/shapes/shapes_basic_shapes.c @@ -39,27 +39,32 @@ int main(void) DrawText("some basic shapes available on raylib", 20, 20, 20, DARKGRAY); - DrawCircle(screenWidth/4, 120, 35, DARKBLUE); + // Circle shapes and lines + DrawCircle(screenWidth/5, 120, 35, DARKBLUE); + DrawCircleGradient(screenWidth/5, 220, 60, GREEN, SKYBLUE); + DrawCircleLines(screenWidth/5, 340, 80, DARKBLUE); + // Rectangle shapes and ines DrawRectangle(screenWidth/4*2 - 60, 100, 120, 60, RED); - DrawRectangleLines(screenWidth/4*2 - 40, 320, 80, 60, ORANGE); // NOTE: Uses QUADS internally, not lines DrawRectangleGradientH(screenWidth/4*2 - 90, 170, 180, 130, MAROON, GOLD); + DrawRectangleLines(screenWidth/4*2 - 40, 320, 80, 60, ORANGE); // NOTE: Uses QUADS internally, not lines + // Triangle shapes and lines DrawTriangle((Vector2){screenWidth/4.0f *3.0f, 80.0f}, (Vector2){screenWidth/4.0f *3.0f - 60.0f, 150.0f}, (Vector2){screenWidth/4.0f *3.0f + 60.0f, 150.0f}, VIOLET); - DrawPoly((Vector2){screenWidth/4*3, 320}, 6, 80, 0, BROWN); + DrawTriangleLines((Vector2){screenWidth/4.0f*3.0f, 160.0f}, + (Vector2){screenWidth/4.0f*3.0f - 20.0f, 230.0f}, + (Vector2){screenWidth/4.0f*3.0f + 20.0f, 230.0f}, DARKBLUE); - DrawCircleGradient(screenWidth/4, 220, 60, GREEN, SKYBLUE); + // Polygon shapes and lines + DrawPoly((Vector2){screenWidth/4*3, 320}, 6, 80, 0, BROWN); + DrawPolyLinesEx((Vector2){screenWidth/4*3, 320}, 6, 80, 0, 6, BEIGE); // NOTE: We draw all LINES based shapes together to optimize internal drawing, // this way, all LINES are rendered in a single draw pass DrawLine(18, 42, screenWidth - 18, 42, BLACK); - DrawCircleLines(screenWidth/4, 340, 80, DARKBLUE); - DrawTriangleLines((Vector2){screenWidth/4.0f*3.0f, 160.0f}, - (Vector2){screenWidth/4.0f*3.0f - 20.0f, 230.0f}, - (Vector2){screenWidth/4.0f*3.0f + 20.0f, 230.0f}, DARKBLUE); EndDrawing(); //---------------------------------------------------------------------------------- } diff --git a/src/raylib.h b/src/raylib.h index 53c816483..4caed9134 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1172,15 +1172,16 @@ RLAPI void DrawRectangleGradientV(int posX, int posY, int width, int height, Col RLAPI void DrawRectangleGradientH(int posX, int posY, int width, int height, Color color1, Color color2);// Draw a horizontal-gradient-filled rectangle RLAPI void DrawRectangleGradientEx(Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline -RLAPI void DrawRectangleLinesEx(Rectangle rec, int lineThick, Color color); // Draw rectangle outline with extended parameters +RLAPI void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color); // Draw rectangle outline with extended parameters RLAPI void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges -RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int lineThick, Color color); // Draw rectangle with rounded edges outline +RLAPI void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline RLAPI void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) RLAPI void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!) RLAPI void DrawTriangleFan(Vector2 *points, int pointsCount, Color color); // Draw a triangle fan defined by points (first vertex is the center) RLAPI void DrawTriangleStrip(Vector2 *points, int pointsCount, Color color); // Draw a triangle strip defined by points RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version) RLAPI void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides +RLAPI void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters // Basic shapes collision detection functions RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles diff --git a/src/shapes.c b/src/shapes.c index ae2611182..9f03bfb3e 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -766,7 +766,7 @@ void DrawRectangleLines(int posX, int posY, int width, int height, Color color) } // Draw rectangle outline with extended parameters -void DrawRectangleLinesEx(Rectangle rec, int lineThick, Color color) +void DrawRectangleLinesEx(Rectangle rec, float lineThick, Color color) { if ((lineThick > rec.width) || (lineThick > rec.height)) { @@ -784,11 +784,11 @@ void DrawRectangleLinesEx(Rectangle rec, int lineThick, Color color) // BBBBBBBB // BBBBBBBB // - float thick = (float)lineThick; - Rectangle top = { rec.x, rec.y, rec.width, thick }; - Rectangle bottom = { rec.x, rec.y - thick + rec.height, rec.width, thick }; - Rectangle left = { rec.x, rec.y + thick, thick, rec.height - thick*2.0f }; - Rectangle right = { rec.x - thick + rec.width, rec.y + thick, thick, rec.height - thick*2.0f }; + + Rectangle top = { rec.x, rec.y, rec.width, lineThick }; + Rectangle bottom = { rec.x, rec.y - lineThick + rec.height, rec.width, lineThick }; + Rectangle left = { rec.x, rec.y + lineThick, lineThick, rec.height - lineThick*2.0f }; + Rectangle right = { rec.x - lineThick + rec.width, rec.y + lineThick, lineThick, rec.height - lineThick*2.0f }; DrawRectangleRec(top, color); DrawRectangleRec(bottom, color); @@ -1019,7 +1019,7 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co } // Draw rectangle with rounded edges outline -void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int lineThick, Color color) +void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, float lineThick, Color color) { if (lineThick < 0) lineThick = 0; @@ -1046,7 +1046,7 @@ void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, int } float stepLength = 90.0f/(float)segments; - const float outerRadius = radius + (float)lineThick, innerRadius = radius; + const float outerRadius = radius + lineThick, innerRadius = radius; /* Quick sketch to make sense of all of this, @@ -1379,7 +1379,11 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col if (sides < 3) sides = 3; float centralAngle = 0.0f; - rlCheckRenderBatchLimit(4*(360/sides)); +#if defined(SUPPORT_QUADS_DRAW_MODE) + rlCheckRenderBatchLimit(4*sides); // Each side is a quad +#else + rlCheckRenderBatchLimit(3*sides); +#endif rlPushMatrix(); rlTranslatef(center.x, center.y, 0.0f); @@ -1431,7 +1435,7 @@ void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Colo if (sides < 3) sides = 3; float centralAngle = 0.0f; - rlCheckRenderBatchLimit(3*(360/sides)); + rlCheckRenderBatchLimit(2*sides); rlPushMatrix(); rlTranslatef(center.x, center.y, 0.0f); @@ -1450,6 +1454,68 @@ void DrawPolyLines(Vector2 center, int sides, float radius, float rotation, Colo rlPopMatrix(); } +void DrawPolyLinesEx(Vector2 center, int sides, float radius, float rotation, float lineThick, Color color) +{ + if (sides < 3) sides = 3; + float centralAngle = 0.0f; + float exteriorAngle = 360.0f/(float)sides; + float innerRadius = radius - (lineThick*cosf(DEG2RAD*exteriorAngle/2.0f)); + +#if defined(SUPPORT_QUADS_DRAW_MODE) + rlCheckRenderBatchLimit(4*sides); +#else + rlCheckRenderBatchLimit(6*sides); +#endif + + rlPushMatrix(); + rlTranslatef(center.x, center.y, 0.0f); + rlRotatef(rotation, 0.0f, 0.0f, 1.0f); + +#if defined(SUPPORT_QUADS_DRAW_MODE) + rlSetTexture(texShapes.id); + + rlBegin(RL_QUADS); + for (int i = 0; i < sides; i++) + { + rlColor4ub(color.r, color.g, color.b, color.a); + + rlTexCoord2f(texShapesRec.x/texShapes.width, texShapesRec.y/texShapes.height); + rlVertex2f(sinf(DEG2RAD*centralAngle)*innerRadius, cosf(DEG2RAD*centralAngle)*innerRadius); + + rlTexCoord2f(texShapesRec.x/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius); + + centralAngle += exteriorAngle; + rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, texShapesRec.y/texShapes.height); + rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius); + + rlTexCoord2f((texShapesRec.x + texShapesRec.width)/texShapes.width, (texShapesRec.y + texShapesRec.height)/texShapes.height); + rlVertex2f(sinf(DEG2RAD*centralAngle)*innerRadius, cosf(DEG2RAD*centralAngle)*innerRadius); + } + rlEnd(); + rlSetTexture(0); +#else + rlBegin(RL_TRIANGLES); + for (int i = 0; i < sides; i++) + { + rlColor4ub(color.r, color.g, color.b, color.a); + float nextAngle = centralAngle + exteriorAngle; + + rlVertex2f(sinf(DEG2RAD*centralAngle)*radius, cosf(DEG2RAD*centralAngle)*radius); + rlVertex2f(sinf(DEG2RAD*centralAngle)*innerRadius, cosf(DEG2RAD*centralAngle)*innerRadius); + rlVertex2f(sinf(DEG2RAD*nextAngle)*radius, cosf(DEG2RAD*nextAngle)*radius); + + rlVertex2f(sinf(DEG2RAD*centralAngle)*innerRadius, cosf(DEG2RAD*centralAngle)*innerRadius); + rlVertex2f(sinf(DEG2RAD*nextAngle)*radius, cosf(DEG2RAD*nextAngle)*radius); + rlVertex2f(sinf(DEG2RAD*nextAngle)*innerRadius, cosf(DEG2RAD*nextAngle)*innerRadius); + + centralAngle = nextAngle; + } + rlEnd(); +#endif + rlPopMatrix(); +} + //---------------------------------------------------------------------------------- // Module Functions Definition - Collision Detection functions //----------------------------------------------------------------------------------