-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[shapes] Add
shapes_rectangle_advanced
example implementing a `Dra…
…wRectangleRoundedGradientH` function (#4435) * [rshapes] Add function * "[shapes] rectangle advanced: fix screen width and height to fit with other examples"
- Loading branch information
Showing
7 changed files
with
809 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,330 @@ | ||
#include "raylib.h" | ||
#include "rlgl.h" | ||
#include <math.h> | ||
|
||
// Draw rectangle with rounded edges and horizontal gradient, with options to choose side of roundness | ||
// Adapted from both `DrawRectangleRounded` and `DrawRectangleGradientH` | ||
void DrawRectangleRoundedGradientH(Rectangle rec, float roundnessLeft, float roundnessRight, int segments, Color left, Color right) | ||
{ | ||
// Neither side is rounded | ||
if ((roundnessLeft <= 0.0f && roundnessRight <= 0.0f) || (rec.width < 1) || (rec.height < 1 )) | ||
{ | ||
DrawRectangleGradientEx(rec, left, left, right, right); | ||
return; | ||
} | ||
|
||
if (roundnessLeft >= 1.0f) roundnessLeft = 1.0f; | ||
if (roundnessRight >= 1.0f) roundnessRight = 1.0f; | ||
|
||
// Calculate corner radius both from right and left | ||
float recSize = rec.width > rec.height ? rec.height : rec.width; | ||
float radiusLeft = (recSize*roundnessLeft)/2; | ||
float radiusRight = (recSize*roundnessRight)/2; | ||
|
||
if (radiusLeft <= 0.0f) radiusLeft = 0.0f; | ||
if (radiusRight <= 0.0f) radiusRight = 0.0f; | ||
|
||
if (radiusRight <= 0.0f && radiusLeft <= 0.0f) return; | ||
|
||
float stepLength = 90.0f/(float)segments; | ||
|
||
/* | ||
Diagram Copied here for reference, original at `DrawRectangleRounded` source code | ||
P0____________________P1 | ||
/| |\ | ||
/1| 2 |3\ | ||
P7 /__|____________________|__\ P2 | ||
| |P8 P9| | | ||
| 8 | 9 | 4 | | ||
| __|____________________|__ | | ||
P6 \ |P11 P10| / P3 | ||
\7| 6 |5/ | ||
\|____________________|/ | ||
P5 P4 | ||
*/ | ||
|
||
// Coordinates of the 12 points also apdated from `DrawRectangleRounded` | ||
const Vector2 point[12] = { | ||
// PO, P1, P2 | ||
{(float)rec.x + radiusLeft, rec.y}, {(float)(rec.x + rec.width) - radiusRight, rec.y}, { rec.x + rec.width, (float)rec.y + radiusRight }, | ||
// P3, P4 | ||
{rec.x + rec.width, (float)(rec.y + rec.height) - radiusRight}, {(float)(rec.x + rec.width) - radiusRight, rec.y + rec.height}, | ||
// P5, P6, P7 | ||
{(float)rec.x + radiusLeft, rec.y + rec.height}, { rec.x, (float)(rec.y + rec.height) - radiusLeft}, {rec.x, (float)rec.y + radiusLeft}, | ||
// P8, P9 | ||
{(float)rec.x + radiusLeft, (float)rec.y + radiusLeft}, {(float)(rec.x + rec.width) - radiusRight, (float)rec.y + radiusRight}, | ||
// P10, P11 | ||
{(float)(rec.x + rec.width) - radiusRight, (float)(rec.y + rec.height) - radiusRight}, {(float)rec.x + radiusLeft, (float)(rec.y + rec.height) - radiusLeft} | ||
}; | ||
|
||
const Vector2 centers[4] = { point[8], point[9], point[10], point[11] }; | ||
const float angles[4] = { 180.0f, 270.0f, 0.0f, 90.0f }; | ||
|
||
#if defined(SUPPORT_QUADS_DRAW_MODE) | ||
rlSetTexture(GetShapesTexture().id); | ||
Rectangle shapeRect = GetShapesTextureRectangle(); | ||
|
||
rlBegin(RL_QUADS); | ||
// Draw all the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner | ||
for (int k = 0; k < 4; ++k) | ||
{ | ||
Color color; | ||
float radius; | ||
if (k == 0) color = left, radius = radiusLeft; // [1] Upper Left Corner | ||
if (k == 1) color = right, radius = radiusRight; // [3] Upper Right Corner | ||
if (k == 2) color = right, radius = radiusRight; // [5] Lower Right Corner | ||
if (k == 3) color = left, radius = radiusLeft; // [7] Lower Left Corner | ||
float angle = angles[k]; | ||
const Vector2 center = centers[k]; | ||
|
||
for (int i = 0; i < segments/2; i++) | ||
{ | ||
rlColor4ub(color.r, color.g, color.b, color.a); | ||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(center.x, center.y); | ||
|
||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength*2))*radius, center.y + sinf(DEG2RAD*(angle + stepLength*2))*radius); | ||
|
||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius); | ||
|
||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius); | ||
|
||
angle += (stepLength*2); | ||
} | ||
|
||
// End one even segments | ||
if ( segments % 2) | ||
{ | ||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(center.x, center.y); | ||
|
||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius); | ||
|
||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius); | ||
|
||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(center.x, center.y); | ||
} | ||
} | ||
|
||
// | ||
// Here we use the `Diagram` to guide ourselves to which point receives what color. | ||
// | ||
// By choosing the color correctly associated with a pointe the gradient effect | ||
// will naturally come from OpenGL interpolation. | ||
// | ||
|
||
// [2] Upper Rectangle | ||
rlColor4ub(left.r, left.g, left.b, left.a); | ||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(point[0].x, point[0].y); | ||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(point[8].x, point[8].y); | ||
|
||
rlColor4ub(right.r, right.g, right.b, right.a); | ||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(point[9].x, point[9].y); | ||
|
||
rlColor4ub(right.r, right.g, right.b, right.a); | ||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(point[1].x, point[1].y); | ||
|
||
// [4] Left Rectangle | ||
rlColor4ub(right.r, right.g, right.b, right.a); | ||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(point[2].x, point[2].y); | ||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(point[9].x, point[9].y); | ||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(point[10].x, point[10].y); | ||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(point[3].x, point[3].y); | ||
|
||
// [6] Bottom Rectangle | ||
rlColor4ub(left.r, left.g, left.b, left.a); | ||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(point[11].x, point[11].y); | ||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(point[5].x, point[5].y); | ||
|
||
rlColor4ub(right.r, right.g, right.b, right.a); | ||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(point[4].x, point[4].y); | ||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(point[10].x, point[10].y); | ||
|
||
// [8] left Rectangle | ||
rlColor4ub(left.r, left.g, left.b, left.a); | ||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(point[7].x, point[7].y); | ||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(point[6].x, point[6].y); | ||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(point[11].x, point[11].y); | ||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(point[8].x, point[8].y); | ||
|
||
// [9] Middle Rectangle | ||
rlColor4ub(left.r, left.g, left.b, left.a); | ||
rlTexCoord2f(shapeRect.x/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(point[8].x, point[8].y); | ||
rlTexCoord2f(shapeRect.x/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(point[11].x, point[11].y); | ||
|
||
rlColor4ub(right.r, right.g, right.b, right.a); | ||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, (shapeRect.y + shapeRect.height)/texShapes.height); | ||
rlVertex2f(point[10].x, point[10].y); | ||
rlTexCoord2f((shapeRect.x + shapeRect.width)/texShapes.width, shapeRect.y/texShapes.height); | ||
rlVertex2f(point[9].x, point[9].y); | ||
|
||
rlEnd(); | ||
rlSetTexture(0); | ||
#else | ||
|
||
// | ||
// Here we use the `Diagram` to guide ourselves to which point receives what color. | ||
// | ||
// By choosing the color correctly associated with a pointe the gradient effect | ||
// will naturally come from OpenGL interpolation. | ||
// But this time instead of Quad, we think in triangles. | ||
// | ||
|
||
rlBegin(RL_TRIANGLES); | ||
|
||
// Draw all of the 4 corners: [1] Upper Left Corner, [3] Upper Right Corner, [5] Lower Right Corner, [7] Lower Left Corner | ||
for (int k = 0; k < 4; ++k) | ||
{ | ||
Color color; | ||
float radius; | ||
if (k == 0) color = left, radius = radiusLeft; // [1] Upper Left Corner | ||
if (k == 1) color = right, radius = radiusRight; // [3] Upper Right Corner | ||
if (k == 2) color = right, radius = radiusRight; // [5] Lower Right Corner | ||
if (k == 3) color = left, radius = radiusLeft; // [7] Lower Left Corner | ||
float angle = angles[k]; | ||
const Vector2 center = centers[k]; | ||
for (int i = 0; i < segments; i++) | ||
{ | ||
rlColor4ub(color.r, color.g, color.b, color.a); | ||
rlVertex2f(center.x, center.y); | ||
rlVertex2f(center.x + cosf(DEG2RAD*(angle + stepLength))*radius, center.y + sinf(DEG2RAD*(angle + stepLength))*radius); | ||
rlVertex2f(center.x + cosf(DEG2RAD*angle)*radius, center.y + sinf(DEG2RAD*angle)*radius); | ||
angle += stepLength; | ||
} | ||
} | ||
|
||
// [2] Upper Rectangle | ||
rlColor4ub(left.r, left.g, left.b, left.a); | ||
rlVertex2f(point[0].x, point[0].y); | ||
rlVertex2f(point[8].x, point[8].y); | ||
rlColor4ub(right.r, right.g, right.b, right.a); | ||
rlVertex2f(point[9].x, point[9].y); | ||
rlVertex2f(point[1].x, point[1].y); | ||
rlColor4ub(left.r, left.g, left.b, left.a); | ||
rlVertex2f(point[0].x, point[0].y); | ||
rlColor4ub(right.r, right.g, right.b, right.a); | ||
rlVertex2f(point[9].x, point[9].y); | ||
|
||
// [4] Right Rectangle | ||
rlColor4ub(right.r, right.g, right.b, right.a); | ||
rlVertex2f(point[9].x, point[9].y); | ||
rlVertex2f(point[10].x, point[10].y); | ||
rlVertex2f(point[3].x, point[3].y); | ||
rlVertex2f(point[2].x, point[2].y); | ||
rlVertex2f(point[9].x, point[9].y); | ||
rlVertex2f(point[3].x, point[3].y); | ||
|
||
// [6] Bottom Rectangle | ||
rlColor4ub(left.r, left.g, left.b, left.a); | ||
rlVertex2f(point[11].x, point[11].y); | ||
rlVertex2f(point[5].x, point[5].y); | ||
rlColor4ub(right.r, right.g, right.b, right.a); | ||
rlVertex2f(point[4].x, point[4].y); | ||
rlVertex2f(point[10].x, point[10].y); | ||
rlColor4ub(left.r, left.g, left.b, left.a); | ||
rlVertex2f(point[11].x, point[11].y); | ||
rlColor4ub(right.r, right.g, right.b, right.a); | ||
rlVertex2f(point[4].x, point[4].y); | ||
|
||
// [8] Left Rectangle | ||
rlColor4ub(left.r, left.g, left.b, left.a); | ||
rlVertex2f(point[7].x, point[7].y); | ||
rlVertex2f(point[6].x, point[6].y); | ||
rlVertex2f(point[11].x, point[11].y); | ||
rlVertex2f(point[8].x, point[8].y); | ||
rlVertex2f(point[7].x, point[7].y); | ||
rlVertex2f(point[11].x, point[11].y); | ||
|
||
// [9] Middle Rectangle | ||
rlColor4ub(left.r, left.g, left.b, left.a); | ||
rlVertex2f(point[8].x, point[8].y); | ||
rlVertex2f(point[11].x, point[11].y); | ||
rlColor4ub(right.r, right.g, right.b, right.a); | ||
rlVertex2f(point[10].x, point[10].y); | ||
rlVertex2f(point[9].x, point[9].y); | ||
rlColor4ub(left.r, left.g, left.b, left.a); | ||
rlVertex2f(point[8].x, point[8].y); | ||
rlColor4ub(right.r, right.g, right.b, right.a); | ||
rlVertex2f(point[10].x, point[10].y); | ||
rlEnd(); | ||
#endif | ||
} | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
// Initialization | ||
//-------------------------------------------------------------------------------------- | ||
const int screenWidth = 800; | ||
const int screenHeight = 450; | ||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - rectangle avanced"); | ||
SetTargetFPS(60); | ||
//-------------------------------------------------------------------------------------- | ||
|
||
// Main game loop | ||
while (!WindowShouldClose()) // Detect window close button or ESC key | ||
{ | ||
// Update rectangle bounds | ||
//---------------------------------------------------------------------------------- | ||
double width = GetScreenWidth()/2.0, height = GetScreenHeight()/6.0; | ||
Rectangle rec = { | ||
GetScreenWidth() / 2.0 - width/2, | ||
GetScreenHeight() / 2.0 - (5)*(height/2), | ||
width, height | ||
}; | ||
//-------------------------------------------------------------------------------------- | ||
|
||
// Draw | ||
//---------------------------------------------------------------------------------- | ||
BeginDrawing(); | ||
ClearBackground(RAYWHITE); | ||
|
||
// Draw All Rectangles with different roundess for each side and different gradients | ||
DrawRectangleRoundedGradientH(rec, 0.8, 0.8, 36, BLUE, RED); | ||
|
||
rec.y += rec.height + 1; | ||
DrawRectangleRoundedGradientH(rec, 0.5, 1.0, 36, RED, PINK); | ||
|
||
rec.y += rec.height + 1; | ||
DrawRectangleRoundedGradientH(rec, 1.0, 0.5, 36, RED, BLUE); | ||
|
||
rec.y += rec.height + 1; | ||
DrawRectangleRoundedGradientH(rec, 0.0, 1.0, 36, BLUE, BLACK); | ||
|
||
rec.y += rec.height + 1; | ||
DrawRectangleRoundedGradientH(rec, 1.0, 0.0, 36, BLUE, PINK); | ||
EndDrawing(); | ||
//-------------------------------------------------------------------------------------- | ||
} | ||
|
||
// De-Initialization | ||
//-------------------------------------------------------------------------------------- | ||
CloseWindow(); // Close window and OpenGL context | ||
//-------------------------------------------------------------------------------------- | ||
return 0; | ||
} | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.