Skip to content

Commit 63a8c0d

Browse files
Initial migration from TS to C++
1 parent e10e9cf commit 63a8c0d

32 files changed

+7077
-26
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
build/
2+
.cache/

CMakeLists.txt

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,4 @@
1-
cmake_minimum_required(VERSION 3.10)
1+
cmake_minimum_required(VERSION 3.5)
22

3-
project(2D-renderer-cpp VERSION 1.0 LANGUAGES CXX)
4-
5-
set(CMAKE_CXX_STANDARD 11)
6-
set(CMAKE_CXX_STANDARD_REQUIRED ON)
7-
8-
file(GLOB SOURCES "src/*.cpp")
9-
file(GLOB HEADERS "src/*.h")
10-
11-
add_executable(2D-renderer-cpp ${SOURCES} ${HEADERS})
12-
13-
# Include directories
14-
target_include_directories(2D-renderer-cpp PRIVATE src)
15-
16-
# Compiler options (optional)
17-
target_compile_options(2D-renderer-cpp PRIVATE -Wall -Wextra)
18-
19-
# For better build organization in IDEs
20-
source_group("Source Files" FILES ${SOURCES})
21-
source_group("Header Files" FILES ${HEADERS})
3+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
4+
project(graphics_engine)

main/CMakeLists.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
idf_component_register(SRCS
2+
"main.cpp"
3+
"src/Renderer.cpp"
4+
"src/Utils.cpp"
5+
"src/Texture.cpp"
6+
"src/Collider.cpp"
7+
"src/Shapes/Shape.cpp"
8+
"src/Shapes/Circle.cpp"
9+
"src/Shapes/Rectangle.cpp"
10+
"src/Shapes/Polygon.cpp"
11+
"src/Shapes/LineSegment.cpp"
12+
"src/Shapes/Point.cpp"
13+
"src/Shapes/RegularPolygon.cpp"
14+
"src/Shapes/Collection.cpp"
15+
INCLUDE_DIRS
16+
"include"
17+
"include/Shapes"
18+
REQUIRES)
19+
20+
target_compile_options(${COMPONENT_LIB} PRIVATE
21+
-Wno-narrowing
22+
-Wno-error=narrowing)

main/component.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
COMPONENT_ADD_INCLUDEDIRS := include include/Shapes
2+
COMPONENT_SRCDIRS := src src/Shapes

main/include/Collider.hpp

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
#pragma once
2+
#include <cmath>
3+
#include <cstring>
4+
#include <vector>
5+
6+
// Forward declarations
7+
class CircleCollider;
8+
class RectangleCollider;
9+
class PolygonCollider;
10+
class LineSegmentCollider;
11+
class PointCollider;
12+
class RegularPolygonCollider;
13+
14+
// Collider type enum
15+
enum class ColliderType {
16+
CIRCLE,
17+
RECTANGLE,
18+
POLYGON,
19+
LINE,
20+
POINT,
21+
REGULAR_POLYGON
22+
};
23+
24+
// Visitor Interface
25+
class CollisionVisitor {
26+
public:
27+
virtual bool visitCircle(const CircleCollider *circle) = 0;
28+
virtual bool visitRectangle(const RectangleCollider *rect) = 0;
29+
virtual bool visitPolygon(const PolygonCollider *polygon) = 0;
30+
virtual bool visitLine(const LineSegmentCollider *line) = 0;
31+
virtual bool visitPoint(const PointCollider *point) = 0;
32+
virtual bool
33+
visitRegularPolygon(const RegularPolygonCollider *regularPolygon) = 0;
34+
virtual ~CollisionVisitor() = default;
35+
};
36+
37+
// Collidable Interface
38+
class Collidable {
39+
public:
40+
virtual bool accept(CollisionVisitor *visitor) const = 0;
41+
virtual ColliderType getType() const = 0;
42+
virtual ~Collidable() = default;
43+
};
44+
45+
// Base Collider
46+
class Collider : public Collidable {
47+
public:
48+
float x;
49+
float y;
50+
51+
Collider(float x, float y) : x(x), y(y) {}
52+
virtual ~Collider() = default;
53+
54+
virtual bool intersects(const Collider *other) const = 0;
55+
virtual void translate(float dx, float dy) {
56+
x += dx;
57+
y += dy;
58+
}
59+
};
60+
61+
// Collision Math utilities
62+
namespace CollisionMath {
63+
inline float distanceSquared(float x1, float y1, float x2, float y2) {
64+
float dx = x1 - x2;
65+
float dy = y1 - y2;
66+
return dx * dx + dy * dy;
67+
}
68+
69+
inline bool pointInPolygon(float x, float y,
70+
const std::vector<std::pair<float, float>> &points) {
71+
bool inside = false;
72+
size_t n = points.size();
73+
for (size_t i = 0, j = n - 1; i < n; j = i++) {
74+
float xi = points[i].first, yi = points[i].second;
75+
float xj = points[j].first, yj = points[j].second;
76+
77+
bool intersect = ((yi > y) != (yj > y)) &&
78+
(x < (xj - xi) * (y - yi) / (yj - yi) + xi);
79+
if (intersect)
80+
inside = !inside;
81+
}
82+
return inside;
83+
}
84+
85+
inline bool lineIntersectLine(float x1, float y1, float x2, float y2, float x3,
86+
float y3, float x4, float y4) {
87+
float denominator = ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
88+
89+
if (denominator == 0)
90+
return false;
91+
92+
float ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denominator;
93+
float ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denominator;
94+
95+
return ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1;
96+
}
97+
} // namespace CollisionMath
98+
99+
// Intersection Visitor
100+
class IntersectionVisitor : public CollisionVisitor {
101+
private:
102+
const Collider *other;
103+
104+
public:
105+
IntersectionVisitor(const Collider *other) : other(other) {}
106+
107+
bool visitCircle(const CircleCollider *circle) override;
108+
bool visitRectangle(const RectangleCollider *rect) override;
109+
bool visitPolygon(const PolygonCollider *polygon) override;
110+
bool visitLine(const LineSegmentCollider *line) override;
111+
bool visitPoint(const PointCollider *point) override;
112+
bool
113+
visitRegularPolygon(const RegularPolygonCollider *regularPolygon) override;
114+
115+
private:
116+
// Intersection implementations
117+
bool circleCircle(const CircleCollider *c1, const CircleCollider *c2);
118+
bool circleRectangle(const CircleCollider *circle,
119+
const RectangleCollider *rect);
120+
bool circlePoint(const CircleCollider *circle, const PointCollider *point);
121+
bool circleLine(const CircleCollider *circle,
122+
const LineSegmentCollider *line);
123+
bool circlePolygon(const CircleCollider *circle,
124+
const PolygonCollider *polygon);
125+
bool circleRegularPolygon(const CircleCollider *circle,
126+
const RegularPolygonCollider *regularPolygon);
127+
128+
bool rectangleRectangle(const RectangleCollider *r1,
129+
const RectangleCollider *r2);
130+
bool rectanglePoint(const RectangleCollider *rect,
131+
const PointCollider *point);
132+
bool rectangleLine(const RectangleCollider *rect,
133+
const LineSegmentCollider *line);
134+
bool rectanglePolygon(const RectangleCollider *rect,
135+
const PolygonCollider *polygon);
136+
bool rectangleRegularPolygon(const RectangleCollider *rect,
137+
const RegularPolygonCollider *regularPolygon);
138+
139+
bool polygonPoint(const PolygonCollider *polygon,
140+
const PointCollider *point);
141+
bool polygonLine(const PolygonCollider *polygon,
142+
const LineSegmentCollider *line);
143+
bool polygonPolygon(const PolygonCollider *p1, const PolygonCollider *p2);
144+
bool polygonRegularPolygon(const PolygonCollider *polygon,
145+
const RegularPolygonCollider *regularPolygon);
146+
147+
bool linePoint(const LineSegmentCollider *line, const PointCollider *point);
148+
bool lineLine(const LineSegmentCollider *l1, const LineSegmentCollider *l2);
149+
bool lineRegularPolygon(const LineSegmentCollider *line,
150+
const RegularPolygonCollider *regularPolygon);
151+
152+
bool pointPoint(const PointCollider *p1, const PointCollider *p2);
153+
bool pointRegularPolygon(const PointCollider *point,
154+
const RegularPolygonCollider *regularPolygon);
155+
};
156+
157+
// Concrete Collider Classes
158+
class CircleCollider : public Collider {
159+
public:
160+
float radius;
161+
162+
CircleCollider(float x, float y, float radius)
163+
: Collider(x, y), radius(radius) {}
164+
165+
bool accept(CollisionVisitor *visitor) const override {
166+
return visitor->visitCircle(this);
167+
}
168+
169+
ColliderType getType() const override { return ColliderType::CIRCLE; }
170+
171+
bool intersects(const Collider *other) const override {
172+
IntersectionVisitor visitor(other);
173+
return this->accept(&visitor);
174+
}
175+
};
176+
177+
class RectangleCollider : public Collider {
178+
public:
179+
float width;
180+
float height;
181+
182+
RectangleCollider(float x, float y, float width, float height)
183+
: Collider(x, y), width(width), height(height) {}
184+
185+
bool accept(CollisionVisitor *visitor) const override {
186+
return visitor->visitRectangle(this);
187+
}
188+
189+
ColliderType getType() const override { return ColliderType::RECTANGLE; }
190+
191+
bool intersects(const Collider *other) const override {
192+
IntersectionVisitor visitor(other);
193+
return this->accept(&visitor);
194+
}
195+
};
196+
197+
class PolygonCollider : public Collider {
198+
public:
199+
std::vector<std::pair<float, float>> points;
200+
201+
PolygonCollider(float x, float y,
202+
const std::vector<std::pair<float, float>> &points)
203+
: Collider(x, y), points(points) {}
204+
205+
bool accept(CollisionVisitor *visitor) const override {
206+
return visitor->visitPolygon(this);
207+
}
208+
209+
ColliderType getType() const override { return ColliderType::POLYGON; }
210+
211+
bool intersects(const Collider *other) const override {
212+
IntersectionVisitor visitor(other);
213+
return this->accept(&visitor);
214+
}
215+
216+
std::vector<std::pair<float, float>> getWorldPoints() const {
217+
std::vector<std::pair<float, float>> worldPoints;
218+
for (const auto &p : points) {
219+
worldPoints.push_back({p.first + x, p.second + y});
220+
}
221+
return worldPoints;
222+
}
223+
};
224+
225+
class LineSegmentCollider : public Collider {
226+
public:
227+
float x2;
228+
float y2;
229+
230+
LineSegmentCollider(float x1, float y1, float x2, float y2)
231+
: Collider(x1, y1), x2(x2), y2(y2) {}
232+
233+
bool accept(CollisionVisitor *visitor) const override {
234+
return visitor->visitLine(this);
235+
}
236+
237+
ColliderType getType() const override { return ColliderType::LINE; }
238+
239+
bool intersects(const Collider *other) const override {
240+
IntersectionVisitor visitor(other);
241+
return this->accept(&visitor);
242+
}
243+
};
244+
245+
class PointCollider : public Collider {
246+
public:
247+
PointCollider(float x, float y) : Collider(x, y) {}
248+
249+
bool accept(CollisionVisitor *visitor) const override {
250+
return visitor->visitPoint(this);
251+
}
252+
253+
ColliderType getType() const override { return ColliderType::POINT; }
254+
255+
bool intersects(const Collider *other) const override {
256+
IntersectionVisitor visitor(other);
257+
return this->accept(&visitor);
258+
}
259+
};
260+
261+
class RegularPolygonCollider : public Collider {
262+
public:
263+
int sides;
264+
float radius;
265+
266+
RegularPolygonCollider(float x, float y, int sides, float radius)
267+
: Collider(x, y), sides(sides), radius(radius) {}
268+
269+
bool accept(CollisionVisitor *visitor) const override {
270+
return visitor->visitRegularPolygon(this);
271+
}
272+
273+
ColliderType getType() const override {
274+
return ColliderType::REGULAR_POLYGON;
275+
}
276+
277+
bool intersects(const Collider *other) const override {
278+
IntersectionVisitor visitor(other);
279+
return this->accept(&visitor);
280+
}
281+
282+
std::vector<std::pair<float, float>> generateRegularPolygonPoints() const {
283+
std::vector<std::pair<float, float>> points;
284+
for (int i = 0; i < sides; i++) {
285+
float angle = (i * 2 * M_PI / sides) - M_PI / 2;
286+
points.push_back(
287+
{std::cos(angle) * radius, std::sin(angle) * radius});
288+
}
289+
return points;
290+
}
291+
};

main/include/Renderer.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#pragma once
2+
#include "Shapes/Collection.hpp"
3+
#include "Utils.hpp"
4+
#include <algorithm>
5+
#include <map>
6+
#include <string>
7+
#include <vector>
8+
9+
class Renderer {
10+
private:
11+
int width;
12+
int height;
13+
Color backgroundColor;
14+
15+
public:
16+
Renderer(int width, int height,
17+
const Color &backgroundColor = Color(255, 255, 255, 1.0f));
18+
19+
Pixels render(const std::vector<Collection *> &collections,
20+
const DrawOptions &options);
21+
22+
static Pixels blendPixels(const Pixels &pixels);
23+
static Pixel blendPixel(const Pixel &background, const Pixel &foreground);
24+
25+
int getWidth() const { return width; }
26+
int getHeight() const { return height; }
27+
const Color &getBackgroundColor() const { return backgroundColor; }
28+
};

0 commit comments

Comments
 (0)