aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--src/engine.cpp18
-rw-r--r--src/fb/chfb.cpp1
-rw-r--r--src/o3d/deriv_vertex.cpp6
-rw-r--r--src/o3d/deriv_vertex.h8
-rw-r--r--src/o3d/mesh.cpp28
-rw-r--r--src/o3d/mesh.h15
-rw-r--r--src/o3d/tri.cpp10
-rw-r--r--src/o3d/tri.h21
-rw-r--r--src/o3d/tri_deriv.cpp138
-rw-r--r--src/o3d/tri_deriv.h22
-rw-r--r--src/o3d/vertex.cpp9
-rw-r--r--src/o3d/vertex.h16
-rw-r--r--src/renderer.cpp178
-rw-r--r--src/renderer.h7
15 files changed, 237 insertions, 244 deletions
diff --git a/Makefile.am b/Makefile.am
index 91513f7..ac2c3b6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -17,8 +17,8 @@ engine_SOURCES = \
src/o3d/vertex_data.h src/o3d/vertex_data.cpp \
src/o3d/vertex.h src/o3d/vertex.cpp \
src/o3d/deriv_vertex.h src/o3d/deriv_vertex.cpp \
- src/o3d/tri_vertex.h src/o3d/tri_vertex.cpp \
- src/o3d/tri_deriv_vertex.h src/o3d/tri_deriv_vertex.cpp \
+ src/o3d/tri.h src/o3d/tri.cpp \
+ src/o3d/tri_deriv.h src/o3d/tri_deriv.cpp \
src/o3d/camera.h src/o3d/camera.cpp \
src/o3d/scene.h src/o3d/scene.cpp
engine_CPPFLAGS = -Wall -Wextra $(DEPS_CPPFLAGS)
diff --git a/src/engine.cpp b/src/engine.cpp
index 96dfd7b..e8cde92 100644
--- a/src/engine.cpp
+++ b/src/engine.cpp
@@ -23,9 +23,8 @@
#include "o3d/scene.h"
#include "o3d/mesh.h"
#include "o3d/obj3d.h"
-#include "o3d/vertex.h"
#include "o3d/vertex_data.h"
-#include "o3d/tri_vertex.h"
+#include "o3d/tri.h"
#include "o3d/camera.h"
#include "math/vector.h"
#include "math/mat4.h"
@@ -87,11 +86,16 @@ static void scene_main(engine::Renderer& renderer, engine::math::Matrix4 final_t
for (int i = 0; i < 1; i++) {
auto final_mat = pre_final_mat * mats[i];
const auto& mesh = scene.objs[i].mesh;
- std::vector<engine::o3d::Vertex4> pts;
- for (const auto& vert : mesh.pts)
- pts.push_back({ final_mat * engine::math::Vector4{vert.point}, vert.data });
- for (auto face : mesh.faces)
- renderer.draw_triangle({pts[face[0]], pts[face[1]], pts[face[2]]});
+ std::vector<engine::math::Vector4> vertices;
+ for (const auto& vertex : mesh.vertices)
+ vertices.push_back(final_mat * vertex);
+ for (auto triangle_indices : mesh.indices) {
+ renderer.draw_triangle({
+ {vertices[triangle_indices[0][0]], mesh.normals[triangle_indices[0][1]], mesh.vertices_data[triangle_indices[0][2]]},
+ {vertices[triangle_indices[1][0]], mesh.normals[triangle_indices[1][1]], mesh.vertices_data[triangle_indices[1][2]]},
+ {vertices[triangle_indices[2][0]], mesh.normals[triangle_indices[2][1]], mesh.vertices_data[triangle_indices[2][2]]},
+ });
+ }
}
cont = update_frame();
}
diff --git a/src/fb/chfb.cpp b/src/fb/chfb.cpp
index e3c0cf1..029d619 100644
--- a/src/fb/chfb.cpp
+++ b/src/fb/chfb.cpp
@@ -33,6 +33,7 @@ void CharacterFrameBuffer::clear() {
}
void CharacterFrameBuffer::draw_point(int x, int y, engine::math::Vector3 loc, const engine::o3d::VertexData& vd) {
+ (void) loc;
(void) vd;
chars_vector[x + y * w] = face_char(0);
}
diff --git a/src/o3d/deriv_vertex.cpp b/src/o3d/deriv_vertex.cpp
index dcb2bff..7123b1c 100644
--- a/src/o3d/deriv_vertex.cpp
+++ b/src/o3d/deriv_vertex.cpp
@@ -3,9 +3,9 @@
using namespace engine::o3d;
-DerivedVertex4::DerivedVertex4(engine::math::Vector4 point, float b0, float b1) : point{point}, b0{b0}, b1{b1} {
+DerivedVertex::DerivedVertex(engine::math::Vector4 vertex, float b0, float b1) : vertex{vertex}, b0{b0}, b1{b1} {
}
-DerivedVertex4 DerivedVertex4::div_by_w() const {
- return {point.div_by_w(), b0, b1};
+DerivedVertex DerivedVertex::div_by_w() const {
+ return {vertex.div_by_w(), b0, b1};
}
diff --git a/src/o3d/deriv_vertex.h b/src/o3d/deriv_vertex.h
index 8945696..7524f9b 100644
--- a/src/o3d/deriv_vertex.h
+++ b/src/o3d/deriv_vertex.h
@@ -5,13 +5,13 @@
namespace engine::o3d {
-class DerivedVertex4 {
+class DerivedVertex {
public:
- engine::math::Vector4 point;
+ engine::math::Vector4 vertex;
float b0, b1;
- DerivedVertex4(engine::math::Vector4 point, float b0, float b1);
- DerivedVertex4 div_by_w() const;
+ DerivedVertex(engine::math::Vector4 vertex, float b0, float b1);
+ DerivedVertex div_by_w() const;
};
}
diff --git a/src/o3d/mesh.cpp b/src/o3d/mesh.cpp
index bf60cc8..2dba328 100644
--- a/src/o3d/mesh.cpp
+++ b/src/o3d/mesh.cpp
@@ -1,8 +1,8 @@
#include "o3d/mesh.h"
#include <vector>
#include <array>
+#include <cstddef>
#include "math/vector.h"
-#include "o3d/vertex.h"
using namespace engine::o3d;
@@ -32,16 +32,30 @@ using namespace engine::o3d;
Mesh Mesh::plane() {
return {
{
- { engine::math::Vector3(-1.f, 0.f, -1.f), {0.f, 0.f} },
- { engine::math::Vector3(+1.f, 0.f, -1.f), {1.f, 0.f} },
- { engine::math::Vector3(+1.f, 0.f, +1.f), {1.f, 1.f} },
- { engine::math::Vector3(-1.f, 0.f, +1.f), {0.f, 1.f} },
+ {-1.f, 0.f, -1.f, 1.f},
+ {+1.f, 0.f, -1.f, 1.f},
+ {+1.f, 0.f, +1.f, 1.f},
+ {-1.f, 0.f, +1.f, 1.f},
},
+ { {0.f, 0.f, -1.f} },
{
- { 0, 1, 2 }, { 2, 3, 0 },
+ {0.f, 0.f},
+ {1.f, 0.f},
+ {1.f, 1.f},
+ {0.f, 1.f},
+ },
+ {
+ {{ {{0, 0, 0}}, {{1, 0, 1}}, {{2, 0, 2}} }},
+ {{ {{2, 0, 2}}, {{3, 0, 3}}, {{0, 0, 0}} }},
+ {{ {{0, 0, 0}}, {{3, 0, 3}}, {{2, 0, 2}} }},
+ {{ {{2, 0, 2}}, {{1, 0, 1}}, {{0, 0, 0}} }},
}
};
}
-Mesh::Mesh(std::vector<Vertex3> pts, std::vector<std::array<int, 3>> faces) : pts{pts}, faces{faces} {
+Mesh::Mesh(std::vector<engine::math::Vector4> vertices,
+ std::vector<engine::math::Vector3> normals,
+ std::vector<VertexData> vertices_data,
+ std::vector<std::array<std::array<std::size_t, 3>, 3>> indices)
+ : vertices{vertices}, normals{normals}, vertices_data{vertices_data}, indices{indices} {
}
diff --git a/src/o3d/mesh.h b/src/o3d/mesh.h
index 34d1e09..4aad0e4 100644
--- a/src/o3d/mesh.h
+++ b/src/o3d/mesh.h
@@ -4,7 +4,9 @@
#include <vector>
#include <array>
#include <iterator>
-#include "o3d/vertex.h"
+#include <cstddef>
+#include "math/vector.h"
+#include "o3d/vertex_data.h"
namespace engine::o3d {
@@ -13,10 +15,15 @@ class Mesh {
// static Mesh cube(); // this function should not be in this file
static Mesh plane(); // this function should not be in this file
- std::vector<Vertex3> pts;
- std::vector<std::array<int, 3>> faces;
+ std::vector<engine::math::Vector4> vertices;
+ std::vector<engine::math::Vector3> normals;
+ std::vector<VertexData> vertices_data;
+ std::vector<std::array<std::array<std::size_t, 3>, 3>> indices;
- Mesh(std::vector<Vertex3> pts, std::vector<std::array<int, 3>> faces);
+ Mesh(std::vector<engine::math::Vector4> vertices,
+ std::vector<engine::math::Vector3> normals,
+ std::vector<VertexData> vertices_data,
+ std::vector<std::array<std::array<std::size_t, 3>, 3>> indices);
};
}
diff --git a/src/o3d/tri.cpp b/src/o3d/tri.cpp
index 08f5e7e..73410bf 100644
--- a/src/o3d/tri.cpp
+++ b/src/o3d/tri.cpp
@@ -1,16 +1,16 @@
-#include "o3d/tri_vertex.h"
+#include "o3d/tri.h"
#include <vector>
#include "math/vector.h"
#include "o3d/vertex_data.h"
#include "o3d/deriv_vertex.h"
#include "o3d/vertex.h"
-#include "o3d/tri_deriv_vertex.h"
+#include "o3d/tri_deriv.h"
using namespace engine::o3d;
-TriangleVertex4::TriangleVertex4(Vertex4 vertex1, Vertex4 vertex2, Vertex4 vertex3) : vertex1{vertex1}, vertex2{vertex2}, vertex3{vertex3} {
+Triangle::Triangle(Vertex vertex1, Vertex vertex2, Vertex vertex3) : vertex1{vertex1}, vertex2{vertex2}, vertex3{vertex3} {
}
-TriangleDerivedVertex4 TriangleVertex4::to_derived() const {
- return {{vertex1.point, 1.f, 0.f}, {vertex2.point, 0.f, 1.f}, {vertex3.point, 0.f, 0.f}};
+TriangleDerived Triangle::to_derived() const {
+ return {{vertex1.vertex, 1.f, 0.f}, {vertex2.vertex, 0.f, 1.f}, {vertex3.vertex, 0.f, 0.f}};
}
diff --git a/src/o3d/tri.h b/src/o3d/tri.h
index 715f649..7fa37fe 100644
--- a/src/o3d/tri.h
+++ b/src/o3d/tri.h
@@ -1,22 +1,23 @@
-#ifndef O3D_TRI_VERTEX_H
-#define O3D_TRI_VERTEX_H
+#ifndef O3D_TRI_H
+#define O3D_TRI_H
#include <vector>
#include "o3d/vertex.h"
-#include "o3d/tri_deriv_vertex.h"
+#include "o3d/tri.h"
+#include "o3d/tri_deriv.h"
namespace engine::o3d {
-class TriangleVertex4 {
+class Triangle {
public:
- Vertex4 vertex1;
- Vertex4 vertex2;
- Vertex4 vertex3;
+ Vertex vertex1;
+ Vertex vertex2;
+ Vertex vertex3;
- TriangleVertex4(Vertex4 vertex1, Vertex4 vertex2, Vertex4 vertex3);
- TriangleDerivedVertex4 to_derived() const;
+ Triangle(Vertex vertex1, Vertex vertex2, Vertex vertex3);
+ TriangleDerived to_derived() const;
};
}
-#endif // O3D_TRI_VERTEX_H
+#endif // O3D_TRI_H
diff --git a/src/o3d/tri_deriv.cpp b/src/o3d/tri_deriv.cpp
index 3605b51..81f60a0 100644
--- a/src/o3d/tri_deriv.cpp
+++ b/src/o3d/tri_deriv.cpp
@@ -1,18 +1,18 @@
-#include "o3d/tri_deriv_vertex.h"
+#include "o3d/tri_deriv.h"
#include <vector>
#include "math/vector.h"
#include "o3d/deriv_vertex.h"
using namespace engine::o3d;
-TriangleDerivedVertex4::TriangleDerivedVertex4(DerivedVertex4 derived_vertex1, DerivedVertex4 derived_vertex2, DerivedVertex4 derived_vertex3)
+TriangleDerived::TriangleDerived(DerivedVertex derived_vertex1, DerivedVertex derived_vertex2, DerivedVertex derived_vertex3)
: derived_vertex1{derived_vertex1}, derived_vertex2{derived_vertex2}, derived_vertex3{derived_vertex3} {
}
#define P1_OUT 1
#define P2_OUT 2
#define P3_OUT 4
-static void _perspective_crop_x(std::vector<TriangleDerivedVertex4>& tris, TriangleDerivedVertex4 t, int n, float x) {
+static void _perspective_crop_x(std::vector<TriangleDerived>& tris, TriangleDerived t, int n, float x) {
switch (n) {
case 0:
tris.push_back(t);
@@ -24,9 +24,9 @@ static void _perspective_crop_x(std::vector<TriangleDerivedVertex4>& tris, Trian
case P1_OUT | P3_OUT:
case P1_OUT | P2_OUT:
{
- DerivedVertex4* q1;
- DerivedVertex4* q2;
- DerivedVertex4* q3;
+ DerivedVertex* q1;
+ DerivedVertex* q2;
+ DerivedVertex* q3;
switch (n) {
case P1_OUT:
case P2_OUT | P3_OUT:
@@ -47,29 +47,29 @@ static void _perspective_crop_x(std::vector<TriangleDerivedVertex4>& tris, Trian
q3 = &t.derived_vertex1;
break;
}
- engine::math::Vector4 dq2 = q1->point - q2->point;
- float fac2 = (x - q2->point.x) / dq2.x;
- float r2w = 1.f / (fac2 / q1->point.w + (1.f - fac2) / q2->point.w);
- float fac2_b = r2w * fac2 / q1->point.w;
- DerivedVertex4 r2{
+ engine::math::Vector4 dq2 = q1->vertex - q2->vertex;
+ float fac2 = (x - q2->vertex.x) / dq2.x;
+ float r2w = 1.f / (fac2 / q1->vertex.w + (1.f - fac2) / q2->vertex.w);
+ float fac2_b = r2w * fac2 / q1->vertex.w;
+ DerivedVertex r2{
{
x,
- q2->point.y + fac2 * dq2.y,
- fac2_b * q1->point.z + (1.f - fac2_b) * q2->point.z,
+ q2->vertex.y + fac2 * dq2.y,
+ fac2_b * q1->vertex.z + (1.f - fac2_b) * q2->vertex.z,
r2w
},
fac2_b * q1->b0 + (1.f - fac2_b) * q2->b0,
fac2_b * q1->b1 + (1.f - fac2_b) * q2->b1
};
- engine::math::Vector4 dq3 = q1->point - q3->point;
- float fac3 = (x - q3->point.x) / dq3.x;
- float r3w = 1.f / (fac3 / q1->point.w + (1.f - fac3) / q3->point.w);
- float fac3_b = r3w * fac3 / q1->point.w;
- DerivedVertex4 r3{
+ engine::math::Vector4 dq3 = q1->vertex - q3->vertex;
+ float fac3 = (x - q3->vertex.x) / dq3.x;
+ float r3w = 1.f / (fac3 / q1->vertex.w + (1.f - fac3) / q3->vertex.w);
+ float fac3_b = r3w * fac3 / q1->vertex.w;
+ DerivedVertex r3{
{
x,
- q3->point.y + fac3 * dq3.y,
- fac3_b * q1->point.z + (1.f - fac3_b) * q3->point.z,
+ q3->vertex.y + fac3 * dq3.y,
+ fac3_b * q1->vertex.z + (1.f - fac3_b) * q3->vertex.z,
r3w
},
fac3_b * q1->b0 + (1.f - fac3_b) * q3->b0,
@@ -105,7 +105,7 @@ static void _perspective_crop_x(std::vector<TriangleDerivedVertex4>& tris, Trian
}
}
-static void _perspective_crop_y(std::vector<TriangleDerivedVertex4>& tris, TriangleDerivedVertex4 t, int n, float y) {
+static void _perspective_crop_y(std::vector<TriangleDerived>& tris, TriangleDerived t, int n, float y) {
switch (n) {
case 0:
tris.push_back(t);
@@ -117,9 +117,9 @@ static void _perspective_crop_y(std::vector<TriangleDerivedVertex4>& tris, Trian
case P1_OUT | P3_OUT:
case P1_OUT | P2_OUT:
{
- DerivedVertex4* q1;
- DerivedVertex4* q2;
- DerivedVertex4* q3;
+ DerivedVertex* q1;
+ DerivedVertex* q2;
+ DerivedVertex* q3;
switch (n) {
case P1_OUT:
case P2_OUT | P3_OUT:
@@ -140,29 +140,29 @@ static void _perspective_crop_y(std::vector<TriangleDerivedVertex4>& tris, Trian
q3 = &t.derived_vertex1;
break;
}
- engine::math::Vector4 dq2 = q1->point - q2->point;
- float fac2 = (y - q2->point.y) / dq2.y;
- float r2w = 1.f / (fac2 / q1->point.w + (1.f - fac2) / q2->point.w);
- float fac2_b = r2w * fac2 / q1->point.w;
- DerivedVertex4 r2{
+ engine::math::Vector4 dq2 = q1->vertex - q2->vertex;
+ float fac2 = (y - q2->vertex.y) / dq2.y;
+ float r2w = 1.f / (fac2 / q1->vertex.w + (1.f - fac2) / q2->vertex.w);
+ float fac2_b = r2w * fac2 / q1->vertex.w;
+ DerivedVertex r2{
{
- q2->point.x + fac2 * dq2.x,
+ q2->vertex.x + fac2 * dq2.x,
y,
- fac2_b * q1->point.z + (1.f - fac2_b) * q2->point.z,
+ fac2_b * q1->vertex.z + (1.f - fac2_b) * q2->vertex.z,
r2w
},
fac2_b * q1->b0 + (1.f - fac2_b) * q2->b0,
fac2_b * q1->b1 + (1.f - fac2_b) * q2->b1
};
- engine::math::Vector4 dq3 = q1->point - q3->point;
- float fac3 = (y - q3->point.y) / dq3.y;
- float r3w = 1.f / (fac3 / q1->point.w + (1.f - fac3) / q3->point.w);
- float fac3_b = r3w * fac3 / q1->point.w;
- DerivedVertex4 r3{
+ engine::math::Vector4 dq3 = q1->vertex - q3->vertex;
+ float fac3 = (y - q3->vertex.y) / dq3.y;
+ float r3w = 1.f / (fac3 / q1->vertex.w + (1.f - fac3) / q3->vertex.w);
+ float fac3_b = r3w * fac3 / q1->vertex.w;
+ DerivedVertex r3{
{
- q3->point.x + fac3 * dq3.x,
+ q3->vertex.x + fac3 * dq3.x,
y,
- fac3_b * q1->point.z + (1.f - fac3_b) * q3->point.z,
+ fac3_b * q1->vertex.z + (1.f - fac3_b) * q3->vertex.z,
r3w
},
fac3_b * q1->b0 + (1.f - fac3_b) * q3->b0,
@@ -198,24 +198,24 @@ static void _perspective_crop_y(std::vector<TriangleDerivedVertex4>& tris, Trian
}
}
-std::vector<TriangleDerivedVertex4> TriangleDerivedVertex4::perspective_crop_xy_out(float x1, float x2, float y1, float y2) const {
- std::vector<TriangleDerivedVertex4> tris_final;
- std::vector<TriangleDerivedVertex4> tris1;
- _perspective_crop_x(tris1, *this, (derived_vertex1.point.x < x1) | ((derived_vertex2.point.x < x1) << 1) | ((derived_vertex3.point.x < x1) << 2), x1);
+std::vector<TriangleDerived> TriangleDerived::perspective_crop_xy_out(float x1, float x2, float y1, float y2) const {
+ std::vector<TriangleDerived> tris_final;
+ std::vector<TriangleDerived> tris1;
+ _perspective_crop_x(tris1, *this, (derived_vertex1.vertex.x < x1) | ((derived_vertex2.vertex.x < x1) << 1) | ((derived_vertex3.vertex.x < x1) << 2), x1);
for (auto t1 : tris1) {
- std::vector<TriangleDerivedVertex4> tris2;
- _perspective_crop_x(tris2, t1, (t1.derived_vertex1.point.x > x2) | ((t1.derived_vertex2.point.x > x2) << 1) | ((t1.derived_vertex3.point.x > x2) << 2), x2);
+ std::vector<TriangleDerived> tris2;
+ _perspective_crop_x(tris2, t1, (t1.derived_vertex1.vertex.x > x2) | ((t1.derived_vertex2.vertex.x > x2) << 1) | ((t1.derived_vertex3.vertex.x > x2) << 2), x2);
for (auto t2 : tris2) {
- std::vector<TriangleDerivedVertex4> tris3;
- _perspective_crop_y(tris3, t2, (t2.derived_vertex1.point.y < y1) | ((t2.derived_vertex2.point.y < y1) << 1) | ((t2.derived_vertex3.point.y < y1) << 2), y1);
+ std::vector<TriangleDerived> tris3;
+ _perspective_crop_y(tris3, t2, (t2.derived_vertex1.vertex.y < y1) | ((t2.derived_vertex2.vertex.y < y1) << 1) | ((t2.derived_vertex3.vertex.y < y1) << 2), y1);
for (auto t3 : tris3)
- _perspective_crop_y(tris_final, t3, (t3.derived_vertex1.point.y > y2) | ((t3.derived_vertex2.point.y > y2) << 1) | ((t3.derived_vertex3.point.y > y2) << 2), y2);
+ _perspective_crop_y(tris_final, t3, (t3.derived_vertex1.vertex.y > y2) | ((t3.derived_vertex2.vertex.y > y2) << 1) | ((t3.derived_vertex3.vertex.y > y2) << 2), y2);
}
}
return tris_final;
}
-static void _crop_z(std::vector<TriangleDerivedVertex4>& tris, TriangleDerivedVertex4 t, int n, float z) {
+static void _crop_z(std::vector<TriangleDerived>& tris, TriangleDerived t, int n, float z) {
switch (n) {
case 0:
tris.push_back(t);
@@ -227,9 +227,9 @@ static void _crop_z(std::vector<TriangleDerivedVertex4>& tris, TriangleDerivedVe
case P1_OUT | P3_OUT:
case P1_OUT | P2_OUT:
{
- DerivedVertex4* q1;
- DerivedVertex4* q2;
- DerivedVertex4* q3;
+ DerivedVertex* q1;
+ DerivedVertex* q2;
+ DerivedVertex* q3;
switch (n) {
case P1_OUT:
case P2_OUT | P3_OUT:
@@ -250,26 +250,26 @@ static void _crop_z(std::vector<TriangleDerivedVertex4>& tris, TriangleDerivedVe
q3 = &t.derived_vertex1;
break;
}
- engine::math::Vector4 dq2 = q1->point - q2->point;
- float fac2 = (z - q2->point.z) / dq2.z;
- DerivedVertex4 r2{
+ engine::math::Vector4 dq2 = q1->vertex - q2->vertex;
+ float fac2 = (z - q2->vertex.z) / dq2.z;
+ DerivedVertex r2{
{
- q2->point.x + fac2 * dq2.x,
- q2->point.y + fac2 * dq2.y,
+ q2->vertex.x + fac2 * dq2.x,
+ q2->vertex.y + fac2 * dq2.y,
z,
- q2->point.w + fac2 * dq2.w
+ q2->vertex.w + fac2 * dq2.w
},
fac2 * q1->b0 + (1.f - fac2) * q2->b0,
fac2 * q1->b1 + (1.f - fac2) * q2->b1
};
- engine::math::Vector4 dq3 = q1->point - q3->point;
- float fac3 = (z - q3->point.z) / dq3.z;
- DerivedVertex4 r3{
+ engine::math::Vector4 dq3 = q1->vertex - q3->vertex;
+ float fac3 = (z - q3->vertex.z) / dq3.z;
+ DerivedVertex r3{
{
- q3->point.x + fac3 * dq3.x,
- q3->point.y + fac3 * dq3.y,
+ q3->vertex.x + fac3 * dq3.x,
+ q3->vertex.y + fac3 * dq3.y,
z,
- q3->point.w + fac3 * dq3.w
+ q3->vertex.w + fac3 * dq3.w
},
fac3 * q1->b0 + (1.f - fac3) * q3->b0,
fac3 * q1->b1 + (1.f - fac3) * q3->b1
@@ -304,18 +304,18 @@ static void _crop_z(std::vector<TriangleDerivedVertex4>& tris, TriangleDerivedVe
}
}
-std::vector<TriangleDerivedVertex4> TriangleDerivedVertex4::crop_z_out(float z1, float z2) const {
- std::vector<TriangleDerivedVertex4> tris;
- _crop_z(tris, *this, (derived_vertex1.point.z < z1) | ((derived_vertex2.point.z < z1) << 1) | ((derived_vertex3.point.z < z1) << 2), z1);
- std::vector<TriangleDerivedVertex4> tris2;
+std::vector<TriangleDerived> TriangleDerived::crop_z_out(float z1, float z2) const {
+ std::vector<TriangleDerived> tris;
+ _crop_z(tris, *this, (derived_vertex1.vertex.z < z1) | ((derived_vertex2.vertex.z < z1) << 1) | ((derived_vertex3.vertex.z < z1) << 2), z1);
+ std::vector<TriangleDerived> tris2;
for (auto t : tris)
- _crop_z(tris2, t, (t.derived_vertex1.point.z > z2) | ((t.derived_vertex2.point.z > z2) << 1) | ((t.derived_vertex3.point.z > z2) << 2), z2);
+ _crop_z(tris2, t, (t.derived_vertex1.vertex.z > z2) | ((t.derived_vertex2.vertex.z > z2) << 1) | ((t.derived_vertex3.vertex.z > z2) << 2), z2);
return tris2;
}
#undef P1_OUT
#undef P2_OUT
#undef P3_OUT
-TriangleDerivedVertex4 TriangleDerivedVertex4::div_by_w() const {
+TriangleDerived TriangleDerived::div_by_w() const {
return {derived_vertex1.div_by_w(), derived_vertex2.div_by_w(), derived_vertex3.div_by_w()};
}
diff --git a/src/o3d/tri_deriv.h b/src/o3d/tri_deriv.h
index 41ed4dc..201539b 100644
--- a/src/o3d/tri_deriv.h
+++ b/src/o3d/tri_deriv.h
@@ -1,5 +1,5 @@
-#ifndef O3D_TRI_DERIV_VERTEX_H
-#define O3D_TRI_DERIV_VERTEX_H
+#ifndef O3D_TRI_VERTEX_H
+#define O3D_TRI_VERTEX_H
#include <vector>
#include "o3d/vertex.h"
@@ -7,18 +7,18 @@
namespace engine::o3d {
-class TriangleDerivedVertex4 {
+class TriangleDerived {
public:
- DerivedVertex4 derived_vertex1;
- DerivedVertex4 derived_vertex2;
- DerivedVertex4 derived_vertex3;
+ DerivedVertex derived_vertex1;
+ DerivedVertex derived_vertex2;
+ DerivedVertex derived_vertex3;
- TriangleDerivedVertex4(DerivedVertex4 derived_vertex1, DerivedVertex4 derived_vertex2, DerivedVertex4 derived_vertex3);
- std::vector<TriangleDerivedVertex4> perspective_crop_xy_out(float x1, float x2, float y1, float y2) const;
- std::vector<TriangleDerivedVertex4> crop_z_out(float z1, float z2) const;
- TriangleDerivedVertex4 div_by_w() const;
+ TriangleDerived(DerivedVertex derived_vertex1, DerivedVertex derived_vertex2, DerivedVertex derived_vertex3);
+ std::vector<TriangleDerived> perspective_crop_xy_out(float x1, float x2, float y1, float y2) const;
+ std::vector<TriangleDerived> crop_z_out(float z1, float z2) const;
+ TriangleDerived div_by_w() const;
};
}
-#endif // O3D_TRI_DERIV_VERTEX_H
+#endif // O3D_TRI_VERTEX_H
diff --git a/src/o3d/vertex.cpp b/src/o3d/vertex.cpp
index ec9c05f..5845e27 100644
--- a/src/o3d/vertex.cpp
+++ b/src/o3d/vertex.cpp
@@ -4,11 +4,6 @@
using namespace engine::o3d;
-Vertex3::Vertex3(engine::math::Vector3 point, VertexData data) : point{point}, data{data} {
-}
-
-Vertex4::Vertex4(engine::math::Vector4 point, VertexData data) : point{point}, data{data} {
-}
-
-Vertex4::Vertex4(Vertex3 vertex) : point{vertex.point}, data{vertex.data} {
+Vertex::Vertex(engine::math::Vector4 vertex, engine::math::Vector3 normal, VertexData data)
+ : vertex{vertex}, normal{normal}, data{data} {
}
diff --git a/src/o3d/vertex.h b/src/o3d/vertex.h
index b0dd195..1247fc8 100644
--- a/src/o3d/vertex.h
+++ b/src/o3d/vertex.h
@@ -6,21 +6,13 @@
namespace engine::o3d {
-class Vertex3 {
+class Vertex {
public:
- engine::math::Vector3 point;
+ engine::math::Vector4 vertex;
+ engine::math::Vector3 normal;
VertexData data;
- Vertex3(engine::math::Vector3 point, VertexData data);
-};
-
-class Vertex4 {
- public:
- engine::math::Vector4 point;
- VertexData data;
-
- Vertex4(engine::math::Vector4 point, VertexData data);
- Vertex4(Vertex3 vertex);
+ Vertex(engine::math::Vector4 vertex, engine::math::Vector3 normal, VertexData data);
};
}
diff --git a/src/renderer.cpp b/src/renderer.cpp
index 7a32807..1fa8799 100644
--- a/src/renderer.cpp
+++ b/src/renderer.cpp
@@ -6,8 +6,8 @@
#include "math/vector.h"
#include "o3d/vertex.h"
#include "o3d/deriv_vertex.h"
-#include "o3d/tri_vertex.h"
-#include "o3d/tri_deriv_vertex.h"
+#include "o3d/tri.h"
+#include "o3d/tri_deriv.h"
#include "o3d/vertex_data.h"
using namespace engine;
@@ -34,127 +34,105 @@ void Renderer::clear() {
fb->clear();
}
-void Renderer::_draw_cropped_triangle(o3d::TriangleVertex4 root, o3d::TriangleDerivedVertex4 triangle) {
- std::array<o3d::DerivedVertex4*, 3> sorted_vs = { &triangle.derived_vertex1, &triangle.derived_vertex2, &triangle.derived_vertex3 };
+enum TriangleSide { top, bottom };
-#define SWAP_IF_LT(X,Y) ({ \
- if (sorted_vs[X]->point.y < sorted_vs[Y]->point.y) { \
- auto temp = sorted_vs[X]; \
- sorted_vs[X] = sorted_vs[Y]; \
- sorted_vs[Y] = temp; \
- } \
- })
- SWAP_IF_LT(1, 0);
- SWAP_IF_LT(2, 1);
- SWAP_IF_LT(1, 0);
-#undef SWAP_IF_LT
+void Renderer::_draw_cropped_triangle(const o3d::Triangle& root, const o3d::TriangleDerived& triangle) {
+ std::array<const o3d::DerivedVertex*, 3> sorted_vs = { &triangle.derived_vertex1, &triangle.derived_vertex2, &triangle.derived_vertex3 };
+
+ {
+ const auto swap_if_lt = [&](auto x, auto y) {
+ if (sorted_vs[x]->vertex.y < sorted_vs[y]->vertex.y) {
+ auto temp = sorted_vs[x];
+ sorted_vs[x] = sorted_vs[y];
+ sorted_vs[y] = temp;
+ }
+ };
+
+ swap_if_lt(1, 0);
+ swap_if_lt(2, 1);
+ swap_if_lt(1, 0);
+ }
auto middle_vl = *sorted_vs[1];
- const float fac = (sorted_vs[1]->point.y - sorted_vs[0]->point.y) / (sorted_vs[2]->point.y - sorted_vs[0]->point.y);
- const float fac_b0 = (1.f - fac) / sorted_vs[0]->point.w / ((1.f - fac) / sorted_vs[0]->point.w + fac / sorted_vs[2]->point.w);
- o3d::DerivedVertex4 middle_vr{
+ const float fac = (sorted_vs[1]->vertex.y - sorted_vs[0]->vertex.y) / (sorted_vs[2]->vertex.y - sorted_vs[0]->vertex.y);
+ const float fac_b0 = (1.f - fac) / sorted_vs[0]->vertex.w / ((1.f - fac) / sorted_vs[0]->vertex.w + fac / sorted_vs[2]->vertex.w);
+ o3d::DerivedVertex middle_vr{
{
- sorted_vs[0]->point.x + fac * (sorted_vs[2]->point.x - sorted_vs[0]->point.x),
- sorted_vs[1]->point.y,
- fac_b0 * sorted_vs[0]->point.z + (1.f - fac_b0) * sorted_vs[2]->point.z,
- 1.f / (1.f / sorted_vs[0]->point.w + fac * (1.f / sorted_vs[2]->point.w - 1.f / sorted_vs[0]->point.w))
+ sorted_vs[0]->vertex.x + fac * (sorted_vs[2]->vertex.x - sorted_vs[0]->vertex.x),
+ sorted_vs[1]->vertex.y,
+ fac_b0 * sorted_vs[0]->vertex.z + (1.f - fac_b0) * sorted_vs[2]->vertex.z,
+ 1.f / (1.f / sorted_vs[0]->vertex.w + fac * (1.f / sorted_vs[2]->vertex.w - 1.f / sorted_vs[0]->vertex.w))
},
fac_b0 * sorted_vs[0]->b0 + (1.f - fac_b0) * sorted_vs[2]->b0,
fac_b0 * sorted_vs[0]->b1 + (1.f - fac_b0) * sorted_vs[2]->b1
};
- if (middle_vr.point.x < middle_vl.point.x) {
+ if (middle_vr.vertex.x < middle_vl.vertex.x) {
auto temp = middle_vr;
middle_vr = middle_vl;
middle_vl = temp;
}
- // top triangle
- {
- if (sorted_vs[0]->point.y != sorted_vs[1]->point.y) {
- int top_y = static_cast<int>(std::floor(sorted_vs[0]->point.y + 1.f));
- int bottom_y = static_cast<int>(std::ceil(sorted_vs[1]->point.y - 1.f));
- for (int y = top_y; y <= bottom_y; y++) {
- float iy = static_cast<float>(y);
- float s = (iy - sorted_vs[0]->point.y) / (sorted_vs[1]->point.y - sorted_vs[0]->point.y);
- float sub_bb0 = 1.f - s;
- float xl = sorted_vs[0]->point.x + s * (middle_vl.point.x - sorted_vs[0]->point.x);
- float xr = sorted_vs[0]->point.x + s * (middle_vr.point.x - sorted_vs[0]->point.x);
- int left_x = static_cast<int>(std::ceil(xl));
- int right_x = static_cast<int>(std::ceil(xr - 1.f));
- for (int x = left_x; x <= right_x; x++) {
- float ix = static_cast<float>(x);
- float t = (ix - xl) / (xr - xl);
- float sub_bb1 = s * (1.f - t);
- float b_fac = 1.f / (sub_bb0 / sorted_vs[0]->point.w + sub_bb1 / middle_vl.point.w + (1.f - sub_bb0 - sub_bb1) / middle_vr.point.w);
- float sub_b0 = b_fac * sub_bb0 / sorted_vs[0]->point.w;
- float sub_b1 = b_fac * sub_bb1 / middle_vl.point.w;
- float b0 = sub_b0 * sorted_vs[0]->b0 + sub_b1 * middle_vl.b0 + (1.f - sub_b0 - sub_b1) * middle_vr.b0;
- float b1 = sub_b0 * sorted_vs[0]->b1 + sub_b1 * middle_vl.b1 + (1.f - sub_b0 - sub_b1) * middle_vr.b1;
- math::Vector3 loc{
- b0 * root.vertex1.point.x + b1 * root.vertex2.point.x + (1.f - b0 - b1) * root.vertex3.point.x,
- b0 * root.vertex1.point.y + b1 * root.vertex2.point.y + (1.f - b0 - b1) * root.vertex3.point.y,
- b0 * root.vertex1.point.z + b1 * root.vertex2.point.z + (1.f - b0 - b1) * root.vertex3.point.z
- };
- if (loc.z < depth_buf[x + y * fb->width()]) {
- depth_buf[x + y * fb->width()] = loc.z;
- fb->draw_point(x, y, loc, o3d::VertexData::bilerp(root.vertex1.data, root.vertex2.data, root.vertex3.data, b0, b1));
- }
- }
- }
+ const auto _draw_cropped_triangle_side = [&]<TriangleSide side>() {
+ const int vertex_end_index = ([&]() { if constexpr (side == TriangleSide::top) return 0; else return 2; })();
+ const o3d::DerivedVertex& vertex_end = *sorted_vs[vertex_end_index];
+ if (vertex_end.vertex.y == sorted_vs[1]->vertex.y)
+ return;
+ int top_y;
+ int bottom_y;
+ if constexpr (side == TriangleSide::top) {
+ top_y = static_cast<int>(std::floor(vertex_end.vertex.y + 1.f));
+ bottom_y = static_cast<int>(std::ceil(sorted_vs[1]->vertex.y - 1.f));
+ } else {
+ bottom_y = static_cast<int>(std::floor(vertex_end.vertex.y));
+ top_y = static_cast<int>(std::ceil(sorted_vs[1]->vertex.y));
}
- }
-
- // bottom triangle
- {
- if (sorted_vs[1]->point.y != sorted_vs[2]->point.y) {
- int bottom_y = static_cast<int>(std::floor(sorted_vs[2]->point.y));
- int top_y = static_cast<int>(std::ceil(sorted_vs[1]->point.y));
- for (int y = top_y; y <= bottom_y; y++) {
- float iy = static_cast<float>(y);
- float s = (iy - sorted_vs[2]->point.y) / (sorted_vs[1]->point.y - sorted_vs[2]->point.y);
- float sub_bb0 = 1.f - s;
- float xl = sorted_vs[2]->point.x + s * (middle_vl.point.x - sorted_vs[2]->point.x);
- float xr = sorted_vs[2]->point.x + s * (middle_vr.point.x - sorted_vs[2]->point.x);
- int left_x = static_cast<int>(std::ceil(xl));
- int right_x = static_cast<int>(std::ceil(xr - 1.f));
- for (int x = left_x; x <= right_x; x++) {
- float ix = static_cast<float>(x);
- float t = (ix - xl) / (xr - xl);
- float sub_bb1 = s * (1.f - t);
- float b_fac = 1.f / (sub_bb0 / sorted_vs[2]->point.w + sub_bb1 / middle_vl.point.w + (1.f - sub_bb0 - sub_bb1) / middle_vr.point.w);
- float sub_b0 = b_fac * sub_bb0 / sorted_vs[2]->point.w;
- float sub_b1 = b_fac * sub_bb1 / middle_vl.point.w;
- float b0 = sub_b0 * sorted_vs[2]->b0 + sub_b1 * middle_vl.b0 + (1.f - sub_b0 - sub_b1) * middle_vr.b0;
- float b1 = sub_b0 * sorted_vs[2]->b1 + sub_b1 * middle_vl.b1 + (1.f - sub_b0 - sub_b1) * middle_vr.b1;
- math::Vector3 loc{
- b0 * root.vertex1.point.x + b1 * root.vertex2.point.x + (1.f - b0 - b1) * root.vertex3.point.x,
- b0 * root.vertex1.point.y + b1 * root.vertex2.point.y + (1.f - b0 - b1) * root.vertex3.point.y,
- b0 * root.vertex1.point.z + b1 * root.vertex2.point.z + (1.f - b0 - b1) * root.vertex3.point.z
- };
- if (loc.z < depth_buf[x + y * fb->width()]) {
- depth_buf[x + y * fb->width()] = loc.z;
- fb->draw_point(x, y, loc, o3d::VertexData::bilerp(root.vertex1.data, root.vertex2.data, root.vertex3.data, b0, b1));
- }
+ for (int y = top_y; y <= bottom_y; y++) {
+ float iy = static_cast<float>(y);
+ float s = (iy - vertex_end.vertex.y) / (sorted_vs[1]->vertex.y - vertex_end.vertex.y);
+ float sub_bb0 = 1.f - s;
+ float xl = vertex_end.vertex.x + s * (middle_vl.vertex.x - vertex_end.vertex.x);
+ float xr = vertex_end.vertex.x + s * (middle_vr.vertex.x - vertex_end.vertex.x);
+ int left_x = static_cast<int>(std::ceil(xl));
+ int right_x = static_cast<int>(std::ceil(xr - 1.f));
+ for (int x = left_x; x <= right_x; x++) {
+ float ix = static_cast<float>(x);
+ float t = (ix - xl) / (xr - xl);
+ float sub_bb1 = s * (1.f - t);
+ float b_fac = 1.f / (sub_bb0 / vertex_end.vertex.w + sub_bb1 / middle_vl.vertex.w + (1.f - sub_bb0 - sub_bb1) / middle_vr.vertex.w);
+ float sub_b0 = b_fac * sub_bb0 / vertex_end.vertex.w;
+ float sub_b1 = b_fac * sub_bb1 / middle_vl.vertex.w;
+ float b0 = sub_b0 * vertex_end.b0 + sub_b1 * middle_vl.b0 + (1.f - sub_b0 - sub_b1) * middle_vr.b0;
+ float b1 = sub_b0 * vertex_end.b1 + sub_b1 * middle_vl.b1 + (1.f - sub_b0 - sub_b1) * middle_vr.b1;
+ math::Vector3 loc{
+ b0 * root.vertex1.vertex.x + b1 * root.vertex2.vertex.x + (1.f - b0 - b1) * root.vertex3.vertex.x,
+ b0 * root.vertex1.vertex.y + b1 * root.vertex2.vertex.y + (1.f - b0 - b1) * root.vertex3.vertex.y,
+ b0 * root.vertex1.vertex.z + b1 * root.vertex2.vertex.z + (1.f - b0 - b1) * root.vertex3.vertex.z
+ };
+ if (loc.z < depth_buf[x + y * fb->width()]) {
+ depth_buf[x + y * fb->width()] = loc.z;
+ fb->draw_point(x, y, loc, o3d::VertexData::bilerp(root.vertex1.data, root.vertex2.data, root.vertex3.data, b0, b1));
}
}
}
- }
+ };
+ _draw_cropped_triangle_side.operator()<TriangleSide::top>();
+ _draw_cropped_triangle_side.operator()<TriangleSide::bottom>();
}
-void Renderer::draw_triangle(o3d::TriangleVertex4 triangle) {
+void Renderer::draw_triangle(o3d::Triangle triangle) {
for (auto t1 : triangle.to_derived().crop_z_out(-1.f, 1.f)) {
for (auto t2 : t1.div_by_w().perspective_crop_xy_out(-1.f, 1.f, -1.f, 1.f)) {
- auto pp1 = t2.derived_vertex1.point.xy();
- auto pp2 = t2.derived_vertex2.point.xy();
- auto pp3 = t2.derived_vertex3.point.xy();
+ auto pp1 = t2.derived_vertex1.vertex.xy();
+ auto pp2 = t2.derived_vertex2.vertex.xy();
+ auto pp3 = t2.derived_vertex3.vertex.xy();
if ((pp2 - pp1).det(pp3 - pp1) >= 0.f) continue;
float fw_over_2 = static_cast<float>(fb->width()) / 2.f, fh_over_2 = static_cast<float>(fb->height()) / 2.f;
- t2.derived_vertex1.point.x = (t2.derived_vertex1.point.x + 1.f) * fw_over_2 - .5f;
- t2.derived_vertex1.point.y = (t2.derived_vertex1.point.y + 1.f) * fh_over_2 - .5f;
- t2.derived_vertex2.point.x = (t2.derived_vertex2.point.x + 1.f) * fw_over_2 - .5f;
- t2.derived_vertex2.point.y = (t2.derived_vertex2.point.y + 1.f) * fh_over_2 - .5f;
- t2.derived_vertex3.point.x = (t2.derived_vertex3.point.x + 1.f) * fw_over_2 - .5f;
- t2.derived_vertex3.point.y = (t2.derived_vertex3.point.y + 1.f) * fh_over_2 - .5f;
+ t2.derived_vertex1.vertex.x = (t2.derived_vertex1.vertex.x + 1.f) * fw_over_2 - .5f;
+ t2.derived_vertex1.vertex.y = (t2.derived_vertex1.vertex.y + 1.f) * fh_over_2 - .5f;
+ t2.derived_vertex2.vertex.x = (t2.derived_vertex2.vertex.x + 1.f) * fw_over_2 - .5f;
+ t2.derived_vertex2.vertex.y = (t2.derived_vertex2.vertex.y + 1.f) * fh_over_2 - .5f;
+ t2.derived_vertex3.vertex.x = (t2.derived_vertex3.vertex.x + 1.f) * fw_over_2 - .5f;
+ t2.derived_vertex3.vertex.y = (t2.derived_vertex3.vertex.y + 1.f) * fh_over_2 - .5f;
_draw_cropped_triangle(triangle, t2);
}
}
diff --git a/src/renderer.h b/src/renderer.h
index 046a4ef..457099d 100644
--- a/src/renderer.h
+++ b/src/renderer.h
@@ -3,7 +3,8 @@
#include <memory>
#include "fb/fb.h"
-#include "o3d/tri_vertex.h"
+#include "o3d/tri.h"
+#include "o3d/tri_deriv.h"
namespace engine {
@@ -16,12 +17,12 @@ class Renderer {
unsigned int width() const;
unsigned int height() const;
void clear();
- void draw_triangle(o3d::TriangleVertex4 triangle);
+ void draw_triangle(o3d::Triangle triangle);
private:
std::vector<float> depth_buf;
- void _draw_cropped_triangle(o3d::TriangleVertex4 root, o3d::TriangleDerivedVertex4 triangle);
+ void _draw_cropped_triangle(const o3d::Triangle& root, const o3d::TriangleDerived& triangle);
};
}