Draw: Add method Draw_DrawCircle.

* Add auxiliar methods `Draw_SetPixel` and `Draw_AddPixel`.
* Refactor `Draw_DrawBoxFilled` and `Draw_DrawBox`, to use previous methods.
* Implement `Draw_DrawCircle` using naïve implementation, with `sqrt`.
This commit is contained in:
2024-10-06 17:49:51 +02:00
parent ec923e9ccb
commit 30439310f6
4 changed files with 115 additions and 32 deletions

View File

@@ -730,23 +730,66 @@ int Draw_GetFlip(DrawImg img) {
} }
///////////////////////////// /////////////////////////////
// Draw_DrawBoxFilled // Draw_SetPixel
// Draw_AddPixel
// //
// //
DrawImg Draw_DrawBoxFilled(DrawImg img, const int x1, const int y1, const int x2, const int y2, const ColorRgba color) { DrawImg Draw_SetPixel(DrawImg img, const int x, const int y, const ColorRgba color) {
DrawImage image = img; DrawImage image = img;
if (x < 0 || y < 0) {
for (int y = y1; y < y2; y++) { return img;
for (int x = x1; x < x2; x++) { }
if (x >= image->w || y >= image->h) {
return img;
}
const int offset = (x + y * image->w) * 4; const int offset = (x + y * image->w) * 4;
image->data[offset + 0] = color[0]; image->data[offset + 0] = color[0];
image->data[offset + 1] = color[1]; image->data[offset + 1] = color[1];
image->data[offset + 2] = color[2]; image->data[offset + 2] = color[2];
image->data[offset + 3] = color[3]; image->data[offset + 3] = color[3];
return img;
}
DrawImg Draw_AddPixel(DrawImg img, const int x, const int y, const ColorRgba color, const float factor) {
const float alpha = factor * ((float)color[3] / 255);
if (alpha <= 0) {
return img;
} }
if (alpha >= 255) {
Draw_SetPixel(img, x, y, color);
return img;
}
DrawImage image = img;
if (x < 0 || y < 0) {
return img;
}
if (x >= image->w || y >= image->h) {
return img;
} }
return (img); const uint8_t a = (uint8_t)(alpha * 255);
const uint8_t r = (int)((float)color[0] * alpha);
const uint8_t g = (int)((float)color[1] * alpha);
const uint8_t b = (int)((float)color[2] * alpha);
const int offset = (x + y * image->w) * 4;
image->data[offset + 0] = SumClamp_uint8(image->data[offset + 0] * (1 - alpha), r);
image->data[offset + 1] = SumClamp_uint8(image->data[offset + 1] * (1 - alpha), g);
image->data[offset + 2] = SumClamp_uint8(image->data[offset + 2] * (1 - alpha), b);
image->data[offset + 3] = SumClamp_uint8(image->data[offset + 3], a);
return img;
}
/////////////////////////////
// Draw_DrawBoxFilled
//
//
DrawImg Draw_DrawBoxFilled(DrawImg img, const int x1, const int y1, const int x2, const int y2, const ColorRgba color) {
for (int y = y1; y < y2; y++) {
for (int x = x1; x < x2; x++) {
Draw_SetPixel(img, x, y, color);
}
}
return img;
} }
///////////////////////////// /////////////////////////////
@@ -754,36 +797,51 @@ DrawImg Draw_DrawBoxFilled(DrawImg img, const int x1, const int y1, const int x2
// //
// //
DrawImg Draw_DrawBox(DrawImg img, const int x1, const int y1, const int x2, const int y2, const ColorRgba color) { DrawImg Draw_DrawBox(DrawImg img, const int x1, const int y1, const int x2, const int y2, const ColorRgba color) {
DrawImage image = img;
for (int x = x1; x < x2; x++) { for (int x = x1; x < x2; x++) {
const int offset1 = (x + y1 * image->w) * 4; Draw_SetPixel(img, x, y1, color);
image->data[offset1 + 0] = color[0]; Draw_SetPixel(img, x, y2 - 1, color);
image->data[offset1 + 1] = color[1];
image->data[offset1 + 2] = color[2];
image->data[offset1 + 3] = color[3];
const int offset2 = (x + (y2 - 1) * image->w) * 4;
image->data[offset2 + 0] = color[0];
image->data[offset2 + 1] = color[1];
image->data[offset2 + 2] = color[2];
image->data[offset2 + 3] = color[3];
} }
for (int y = y1 + 1; y < y2 - 1; y++) { for (int y = y1 + 1; y < y2 - 1; y++) {
const int offset1 = (x1 + y * image->w) * 4; Draw_SetPixel(img, x1, y, color);
image->data[offset1 + 0] = color[0]; Draw_SetPixel(img, x2 - 1, y, color);
image->data[offset1 + 1] = color[1];
image->data[offset1 + 2] = color[2];
image->data[offset1 + 3] = color[3];
const int offset2 = ((x2 - 1) + y * image->w) * 4;
image->data[offset2 + 0] = color[0];
image->data[offset2 + 1] = color[1];
image->data[offset2 + 2] = color[2];
image->data[offset2 + 3] = color[3];
} }
return (img); return (img);
} }
/////////////////////////////
// Draw_DrawCircle
//
//
DrawImg Draw_DrawCircle(DrawImg img, int centerX, int centerY, int radius, int innerRadius, const ColorRgba color) {
for (int y = -centerY; y < centerY; y++) {
for (int x = -centerX; x < centerX; x++) {
const float dist = sqrtf((float)(x * x + y * y));
if (dist <= (float)radius) {
const float delta = (float)radius - dist;
if (delta > 1.0f) {
// In
const float innerDelta = (float)innerRadius - dist;
if (innerDelta > 1.0f) {
// In
} else if (innerDelta <= 1.0f && innerDelta >= 0.0f) {
// Edge
Draw_AddPixel(img, centerX + x, centerY + y, color, 1.0f - innerDelta);
} else {
// Out
Draw_AddPixel(img, centerX + x, centerY + y, color, 1.0f);
}
} else if (delta <= 1.0f && delta >= 0.0f) {
// Edge
Draw_AddPixel(img, centerX + x, centerY + y, color, delta);
} else {
// Out
}
}
}
}
return img;
}
///////////////////////////// /////////////////////////////
// Draw_DrawImg // Draw_DrawImg
// //

View File

@@ -81,6 +81,14 @@ void Draw_GetOffset(DrawImg img, int *x, int *y);
void Draw_SetFlip(DrawImg img, int flip); void Draw_SetFlip(DrawImg img, int flip);
int Draw_GetFlip(DrawImg img); int Draw_GetFlip(DrawImg img);
/////////////////////////////
// Draw_SetPixel
// Draw_AddPixel
//
//
DrawImg Draw_SetPixel(DrawImg img, int x, int y, const ColorRgba color);
DrawImg Draw_AddPixel(DrawImg img, int x, int y, const ColorRgba color, float factor);
///////////////////////////// /////////////////////////////
// Draw_DrawBoxFilled // Draw_DrawBoxFilled
// //
@@ -93,6 +101,12 @@ DrawImg Draw_DrawBoxFilled(DrawImg img, int x1, int y1, int x2, int y2, const Co
// //
DrawImg Draw_DrawBox(DrawImg img, int x1, int y1, int x2, int y2, const ColorRgba color); DrawImg Draw_DrawBox(DrawImg img, int x1, int y1, int x2, int y2, const ColorRgba color);
/////////////////////////////
// Draw_DrawCircle
//
//
DrawImg Draw_DrawCircle(DrawImg img, int centerX, int centerY, int radius, int innerRadius, const ColorRgba color);
///////////////////////////// /////////////////////////////
// Draw_DrawImg // Draw_DrawImg
// //

View File

@@ -26,6 +26,14 @@ int MaximumInt(int i0, int i1) {
return i0; return i0;
} }
uint8_t SumClamp_uint8(const uint8_t a, const uint8_t b) {
const uint16_t sum = a + b;
if (sum > 255) {
return 255;
}
return sum;
}
///////////////////////////// /////////////////////////////
// Rect // Rect
// //

View File

@@ -5,6 +5,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#define Pi (3.1415925f) #define Pi (3.1415925f)
@@ -18,6 +19,8 @@ int MinimumInt(int i0, int i1);
int MaximumInt(int i0, int i1); int MaximumInt(int i0, int i1);
uint8_t SumClamp_uint8(const uint8_t a, const uint8_t b);
///////////////////////////// /////////////////////////////
// Rect // Rect
// //