Skip to content

Commit

Permalink
Add circle rendering support and example
Browse files Browse the repository at this point in the history
  • Loading branch information
Bexin3 authored Jan 8, 2024
1 parent a8c384e commit 2cfcd2f
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 31 deletions.
44 changes: 44 additions & 0 deletions examples/FillCircle/FillCircle.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "SpeeduinoGL.h"
#include "Arduino_H7_Video.h"
#include "dsi.h"
#include "SDRAM.h"

uint16_t* FrameBuffer = (uint16_t*)SDRAM_START_ADDRESS;
const int ResV = 480;

Rectangle sq1 = {
{ 0, 0 },
{ 0, 480 },
{ 800, 0 },
{ 800, 480 }
};

Point centre = {400, 240};

// The buffer used to rotate and resize the frame
Arduino_H7_Video Display(800, 480, GigaDisplayShield);

void setup() {
SDRAM.begin();
Display.begin();

dsi_lcdClear(0);
dsi_drawCurrentFrameBuffer();
dsi_lcdClear(0);
dsi_drawCurrentFrameBuffer();

ConfigBuffer(SDRAM_START_ADDRESS, ResV);
FillRectangle(sq1, 0x00FF);
}

void loop() {

int32_t t1 = micros();
// FillRectangle(sq1, 0x00FF);
FillCircle(100, 0x0FFF, centre);
Serial.println(micros() - t1);

dsi_lcdDrawImage((void*)FrameBuffer, (void*)dsi_getCurrentFrameBuffer(), 480, 800, DMA2D_INPUT_RGB565);
dsi_drawCurrentFrameBuffer();
}

8 changes: 4 additions & 4 deletions examples/RotatingSquare/RotatingSquare.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
uint16_t* FrameBuffer = (uint16_t*)SDRAM_START_ADDRESS;
const int ResV = 480;

Square sq1 = {
Rectangle sq1 = {
{0, 0},
{0, 480},
{800, 0},
Expand All @@ -31,7 +31,7 @@ void setup() {
}

void loop() {
FillSquare(sq1, 0x0986);
FillRectangle(sq1, 0x0986);

angle += 0.01;

Expand All @@ -42,8 +42,8 @@ void loop() {
{400 + 150 * (cos(angle) + sin(angle)), 240 + 150 * (cos(angle) - sin(angle)) }
};

int32_t t1 = micros();
FillSquare(sq1, 0x00FF);
int32_t t1 = micros();
FillRectangle(sq1, 0x00FF);
Serial.println(micros() - t1);

dsi_lcdDrawImage((void *)FrameBuffer, (void *)dsi_getCurrentFrameBuffer(), 480, 800, DMA2D_INPUT_RGB565);
Expand Down
86 changes: 61 additions & 25 deletions src/SpeeduinoGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ uint32_t ResH = 800;
gradBC, gradAC, Colour, Polarized);
}

void FillSquare(Square square, uint16_t Colour) {
void FillRectangle(Rectangle rectangle, uint16_t Colour) {
// Sort points based on x-coordinates
std::sort(&square.A, &square.C + 1,
std::sort(&rectangle.A, &rectangle.C + 1,
[](const Point &a, const Point &b) {
return a.w < b.w;
}
Expand All @@ -48,53 +48,53 @@ uint32_t ResH = 800;
bool switched = false;
bool Polarized = false;

float gradAC = (square.C.h - square.A.h) / (square.C.w - square.A.w);
float gradAD = (square.D.h - square.A.h) / (square.D.w - square.A.w);
float gradAB = (square.B.h - square.A.h) / (square.B.w - square.A.w);
float gradAC = (rectangle.C.h - rectangle.A.h) / (rectangle.C.w - rectangle.A.w);
float gradAD = (rectangle.D.h - rectangle.A.h) / (rectangle.D.w - rectangle.A.w);
float gradAB = (rectangle.B.h - rectangle.A.h) / (rectangle.B.w - rectangle.A.w);

if (gradAD > gradAB) {
if (gradAC > gradAD) {
std::swap(square.C, square.D);
std::swap(rectangle.C, rectangle.D);
std::swap(gradAC, gradAD);
switched = true;
}
} else {
if (gradAC < gradAD) {
std::swap(square.C, square.D);
std::swap(rectangle.C, rectangle.D);
std::swap(gradAC, gradAD);
switched = true;
}
}

float gradBC = (square.C.h - square.B.h) / (square.C.w - square.B.w);
float gradDC = (square.C.h - square.D.h) / (square.C.w - square.D.w);
float gradBC = (rectangle.C.h - rectangle.B.h) / (rectangle.C.w - rectangle.B.w);
float gradDC = (rectangle.C.h - rectangle.D.h) / (rectangle.C.w - rectangle.D.w);

Polarized = gradAB > gradAD;

PolarizedTwoLineRasterizer(ceil(square.A.w), ceil(square.B.w),
square.A.h + gradAD * (ceil(square.A.w) - square.A.w),
square.A.h + gradAB * (ceil(square.A.w) - square.A.w),
PolarizedTwoLineRasterizer(ceil(rectangle.A.w), ceil(rectangle.B.w),
rectangle.A.h + gradAD * (ceil(rectangle.A.w) - rectangle.A.w),
rectangle.A.h + gradAB * (ceil(rectangle.A.w) - rectangle.A.w),
gradAB, gradAD, Colour, Polarized);

if (switched) {
PolarizedTwoLineRasterizer(ceil(square.B.w), ceil(square.C.w),
square.A.h + gradAD * (ceil(square.B.w) - square.A.w),
square.B.h + gradBC * (ceil(square.B.w) - square.B.w),
PolarizedTwoLineRasterizer(ceil(rectangle.B.w), ceil(rectangle.C.w),
rectangle.A.h + gradAD * (ceil(rectangle.B.w) - rectangle.A.w),
rectangle.B.h + gradBC * (ceil(rectangle.B.w) - rectangle.B.w),
gradBC, gradAD, Colour, Polarized);

PolarizedTwoLineRasterizer(ceil(square.C.w), ceil(square.D.w),
square.A.h + gradAD * (ceil(square.C.w) - square.A.w),
square.C.h + gradDC * (ceil(square.C.w) - square.C.w),
PolarizedTwoLineRasterizer(ceil(rectangle.C.w), ceil(rectangle.D.w),
rectangle.A.h + gradAD * (ceil(rectangle.C.w) - rectangle.A.w),
rectangle.C.h + gradDC * (ceil(rectangle.C.w) - rectangle.C.w),
gradDC, gradAD, Colour, Polarized);
} else {
PolarizedTwoLineRasterizer(ceil(square.B.w), ceil(square.D.w),
square.A.h + gradAD * (ceil(square.B.w) - square.A.w),
square.B.h + gradBC * (ceil(square.B.w) - square.B.w),
PolarizedTwoLineRasterizer(ceil(rectangle.B.w), ceil(rectangle.D.w),
rectangle.A.h + gradAD * (ceil(rectangle.B.w) - rectangle.A.w),
rectangle.B.h + gradBC * (ceil(rectangle.B.w) - rectangle.B.w),
gradBC, gradAD, Colour, Polarized);

PolarizedTwoLineRasterizer(ceil(square.D.w), ceil(square.C.w),
square.D.h + gradDC * (ceil(square.D.w) - square.D.w),
square.B.h + gradBC * (ceil(square.D.w) - square.B.w),
PolarizedTwoLineRasterizer(ceil(rectangle.D.w), ceil(rectangle.C.w),
rectangle.D.h + gradDC * (ceil(rectangle.D.w) - rectangle.D.w),
rectangle.B.h + gradBC * (ceil(rectangle.D.w) - rectangle.B.w),
gradBC, gradDC, Colour, Polarized);
}
}
Expand All @@ -114,7 +114,6 @@ uint32_t ResH = 800;
if (CellStartX < 0) {
PointerCoordinateH -= Gradient2 * CellStartX;
PointerEndH -= Gradient1 * CellStartX;
CellStartX = 0;
}

if (CellEndX > ResH) {
Expand All @@ -138,3 +137,40 @@ uint32_t ResH = 800;
}
}

void FillCircle(float Radius, uint16_t Colour, Point Centre) {
uint16_t* ImageBuffer = (uint16_t*)ImageAddress;

float RadiusTo2 = pow(Radius, 2);

uint32_t CellEndX = ceil(Centre.w+Radius);

if (CellEndX > ResH) {
CellEndX = ResH;
};

uint32_t CellStartX = ceil(Centre.w-Radius);
float RadiusPos = CellStartX-(Centre.w);


for (uint32_t CurrentW = CellStartX; CellEndX > CurrentW; CurrentW++) {


float height = sqrt(RadiusTo2 - pow(RadiusPos, 2));
uint16_t PointerCoorInt = floor(Centre.h - height + 1);
uint16_t PointerEndInt = ceil(Centre.h + height);



if (PointerEndInt > ResV) {
PointerEndInt = ResV;
}

for (int32_t CurrentH = PointerCoorInt; (PointerEndInt) > CurrentH; CurrentH++) {
ImageBuffer[ResV * (CurrentW) + (CurrentH)] = Colour;
};

RadiusPos++;

}
}

5 changes: 3 additions & 2 deletions src/SpeeduinoGL.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
Point C;
};

struct Square {
struct Rectangle {
Point A;
Point B;
Point D;
Expand All @@ -23,9 +23,10 @@

void ConfigBuffer(uint32_t address = 0x60000000, uint32_t ResolutionV = 480, uint32_t ResolutionH = 800);
void FillTriangle(Triangle triangle, uint16_t Colour);
void FillSquare(Square square, uint16_t Colour);
void FillRectangle(Rectangle rectangle, uint16_t Colour);

void PolarizedTwoLineRasterizer(int32_t CellStartX, int32_t CellEndX, float PointerCoordinateH, float PointerEndH, float Gradient1, float Gradient2, uint16_t Colour, bool Polarity);
void TwoLineRasterizer(int32_t CellStartX, int32_t CellEndX, float PointerCoordinateH, float PointerEndH, float Gradient1, float Gradient2, uint16_t Colour);
void FillCircle(float Radius, uint16_t Colour, Point Centre);

#endif

0 comments on commit 2cfcd2f

Please sign in to comment.