summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElizabeth (Lizzy) Hunt <elizabeth.hunt@simponic.xyz>2023-11-28 14:47:29 -0700
committerGitHub <noreply@github.com>2023-11-28 14:47:29 -0700
commit4dcdd32bf7578acf3ea9bc1e98d39d82e3e1afdd (patch)
tree2d9eb3fbc17d453ee33e478bafb9936beff12eb3
parentebc517c800a90f6f0ed157e5c3bd7c3bd18165b5 (diff)
parent3197f9e40cd7079e19990c64c98de667e2457d75 (diff)
downloadgbarubik-main.tar.gz
gbarubik-main.zip
Merge pull request #1 from Simponic/cubeHEADmain
Cube
-rw-r--r--inc/mesh.hpp6
-rw-r--r--inc/model_instance.hpp12
-rw-r--r--inc/palette.hpp7
-rw-r--r--inc/renderable.hpp2
-rw-r--r--inc/scene.hpp29
-rw-r--r--src/cube.cpp21
-rw-r--r--src/main.cpp27
-rw-r--r--src/mesh.hpp11
-rw-r--r--src/model_instance.cpp60
-rw-r--r--src/scene.cpp38
10 files changed, 170 insertions, 43 deletions
diff --git a/inc/mesh.hpp b/inc/mesh.hpp
index db465fb..91fa500 100644
--- a/inc/mesh.hpp
+++ b/inc/mesh.hpp
@@ -14,9 +14,9 @@ typedef struct TRIANGLE {
} TRIANGLE;
class Mesh {
-protected:
- usu::vector<VECTOR> m_vertices;
- usu::vector<TRIANGLE> m_triangles;
+public:
+ usu::vector<VECTOR> vertices;
+ usu::vector<TRIANGLE> triangles;
};
#endif // MESH_HPP
diff --git a/inc/model_instance.hpp b/inc/model_instance.hpp
index a8bbee0..8126278 100644
--- a/inc/model_instance.hpp
+++ b/inc/model_instance.hpp
@@ -5,13 +5,19 @@
#include "renderable.hpp"
#include <tonc.h>
-class ModelInstance : Renderable {
+class ModelInstance : public Renderable {
private:
+ std::shared_ptr<Mesh> m_mesh;
FIXED m_scale;
- VECTOR m_rotation;
+ VECTOR m_rot; // though technically "FIXED"'s, these are simply s32's
+ // where [0, 2pi] -> [0, 0xFFFF] in the x,y,z axes
VECTOR m_pos;
- std::shared_ptr<Mesh> m_mesh;
+public:
+ ModelInstance(std::shared_ptr<Mesh> mesh, FIXED scale, VECTOR m_rotation,
+ VECTOR m_pos);
+ void add_pos(VECTOR d_pos);
+ virtual void render(std::shared_ptr<Scene> scene_context);
};
#endif // MODEL_INSTANCE_HPP
diff --git a/inc/palette.hpp b/inc/palette.hpp
index 1850835..e45e9cf 100644
--- a/inc/palette.hpp
+++ b/inc/palette.hpp
@@ -10,11 +10,12 @@ constexpr std::uint8_t pal_len = 255;
constexpr std::uint16_t cube_colors[6] = {CLR_WHITE, CLR_YELLOW, CLR_RED,
CLR_ORANGE, CLR_BLUE, CLR_GREEN};
-constexpr void put_palette(std::uint16_t *palette_address) {
+void put_palette(std::uint16_t *palette_address) {
toncset16(palette_address, CLR_BLACK, 1);
- toncset16(palette_address + 1, CLR_WHITE, 1);
+ for (std::uint32_t i = 0; i < 6; ++i)
+ toncset16(palette_address + i + 1, cube_colors[i], 1);
+ // TODO: PALETTE GRADIENT IN ALPHA DIMENSION (BRIGHTNESS)
}
-
}; // namespace palette
#endif // PALETTE_HPP
diff --git a/inc/renderable.hpp b/inc/renderable.hpp
index 7f72e51..83b7596 100644
--- a/inc/renderable.hpp
+++ b/inc/renderable.hpp
@@ -7,7 +7,7 @@ class Scene;
class Renderable {
public:
- virtual void render(std::shared_ptr<Scene> scene_context);
+ virtual void render(std::shared_ptr<Scene> scene_context) = 0;
};
#endif
diff --git a/inc/scene.hpp b/inc/scene.hpp
index f84bcd7..6dd4c35 100644
--- a/inc/scene.hpp
+++ b/inc/scene.hpp
@@ -1,20 +1,29 @@
-#ifndef CANVAS_HPP
-#define CANVAS_HPP
+#ifndef SCENE_HPP
+#define SCENE_HPP
-#include "mesh.hpp"
+#include "model_instance.hpp"
+#include "renderable.hpp"
#include "vector.hpp"
#include <cstdint>
+#include <tonc.h>
class Scene {
-private:
- usu::vector<Mesh> meshes;
- std::uint32_t width;
- std::uint32_t height;
-
public:
- Scene();
+ usu::vector<std::shared_ptr<Renderable>> renderables;
+ std::tuple<std::uint32_t, std::uint32_t>
+ viewport_dimension; // <width, height>
+ std::tuple<std::uint32_t, std::uint32_t> scene_dimension;
+ VECTOR directional_light;
+ FIXED z_plane;
- void render();
+ Scene();
+ POINT project_2d(VECTOR vertex);
+ POINT viewport_to_scene(POINT p);
+ void draw_line(POINT p0, POINT p1, std::uint8_t pal_idx);
+ static inline void render(std::shared_ptr<Scene> scene_ctx) {
+ for (std::shared_ptr<Renderable> renderable : scene_ctx->renderables)
+ renderable->render(scene_ctx);
+ }
};
#endif // SCENE_HPP
diff --git a/src/cube.cpp b/src/cube.cpp
index fddc601..60422a2 100644
--- a/src/cube.cpp
+++ b/src/cube.cpp
@@ -1,6 +1,23 @@
#include "cube.hpp"
Cube::Cube() {
- for (std::uint8_t i = 0; i < 8; ++i)
- m_vertices.add({(i >> 2) & 1, (i >> 1) & 1, i & 1});
+ for (std::uint8_t i = 0; i < 8; ++i) {
+ VECTOR vertex = {int2fx((((i >> 2) & 1) << 1) - 1),
+ int2fx((((i >> 1) & 1) << 1) - 1),
+ int2fx(((i & 1) << 1) - 1)};
+ vertices.add(vertex);
+ }
+
+ triangles.add({{0, 4, 5}, 1});
+ triangles.add({{0, 1, 5}, 1});
+ triangles.add({{4, 6, 7}, 1});
+ triangles.add({{4, 5, 7}, 1});
+ triangles.add({{1, 5, 7}, 1});
+ triangles.add({{1, 3, 7}, 1});
+ triangles.add({{0, 4, 6}, 1});
+ triangles.add({{0, 2, 6}, 1});
+ triangles.add({{0, 2, 1}, 1});
+ triangles.add({{1, 2, 3}, 1});
+ triangles.add({{2, 7, 3}, 1});
+ triangles.add({{2, 5, 7}, 1});
}
diff --git a/src/main.cpp b/src/main.cpp
index f147f2f..cc21223 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,4 +1,7 @@
+#include "cube.hpp"
#include "palette.hpp"
+#include "renderable.hpp"
+#include "scene.hpp"
#include "vector.hpp"
#include <tonc.h>
@@ -7,23 +10,27 @@ int main() {
irq_init(NULL);
irq_enable(II_VBLANK);
REG_DISPCNT = DCNT_MODE4 | DCNT_BG2;
-
- // initialize our palette
palette::put_palette((std::uint16_t *)MEM_PAL);
- // begin
- bmp16_line(1, 3, 1 + SCREEN_WIDTH / 2 - 2, SCREEN_HEIGHT, 0x0101, vid_page,
- SCREEN_WIDTH);
- vid_flip();
- bmp16_line(2, 3, 2 + SCREEN_WIDTH / 2 - 2, SCREEN_HEIGHT, 0x0101, vid_page,
- SCREEN_WIDTH);
+ auto scene = std::make_shared<Scene>();
+
+ auto cube = std::shared_ptr<Mesh>((Mesh *)new Cube);
+
+ ModelInstance model_instance(cube, float2fx(0.25), {0, 0x0C00, 0},
+ {int2fx(3), int2fx(3), int2fx(3)});
+
+ auto model_instance_ptr = std::shared_ptr<Renderable>(&model_instance);
+ scene->renderables.add(model_instance_ptr);
- std::uint32_t frame = 0;
+ std::uint8_t frame = 0;
while (1) {
- frame = (frame + 1) % 60;
if (frame == 0) {
+ model_instance.add_pos({0, 0, float2fx(0.2)});
+ M4_CLEAR();
+ Scene::render(scene);
vid_flip();
}
+ frame = (frame + 1) % 10;
VBlankIntrWait();
}
diff --git a/src/mesh.hpp b/src/mesh.hpp
deleted file mode 100644
index 55b414a..0000000
--- a/src/mesh.hpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "mesh.hpp"
-#include "scene.hpp"
-#include <tuple>
-
-void Mesh::render(std::shared_ptr<Scene> scene_context) {
- for (const TRIANGLE triangle : m_triangles) {
- VECTOR v0 = m_vertices[std::get<0>(triangle.vertex_indices)];
- VECTOR v1 = m_vertices[std::get<1>(triangle.vertex_indices)];
- VECTOR v2 = m_vertices[std::get<2>(triangle.vertex_indices)];
- }
-}
diff --git a/src/model_instance.cpp b/src/model_instance.cpp
new file mode 100644
index 0000000..db28243
--- /dev/null
+++ b/src/model_instance.cpp
@@ -0,0 +1,60 @@
+#include "model_instance.hpp"
+#include "scene.hpp"
+#include <tuple>
+
+ModelInstance::ModelInstance(std::shared_ptr<Mesh> mesh, FIXED scale,
+ VECTOR rotation, VECTOR position)
+ : m_mesh(mesh), m_scale(scale), m_rot(rotation), m_pos(position) {}
+
+VECTOR rotate(VECTOR v, VECTOR rot) {
+ FIXED sin_theta_x, sin_theta_y, sin_theta_z;
+ FIXED cos_theta_x, cos_theta_y, cos_theta_z;
+
+ VECTOR res = {v.x, v.y, v.z};
+
+ if (rot.x != 0) {
+ sin_theta_x = float2fx(0.707); // lu_sin(rot.x) >> 4;
+ cos_theta_x = float2fx(0.707); // lu_cos(rot.x) >> 4;
+ res.y = fxmul(res.y, cos_theta_x) - fxmul(res.z, sin_theta_x);
+ res.z = fxmul(res.z, cos_theta_x) + fxmul(res.y, sin_theta_x);
+ }
+
+ if (rot.y != 0) {
+ sin_theta_y = lu_sin(rot.y) >> 4;
+ cos_theta_y = lu_cos(rot.y) >> 4;
+ res.x = fxmul(res.x, cos_theta_y) + fxmul(res.z, sin_theta_y);
+ res.z = fxmul(res.z, cos_theta_y) - fxmul(res.x, sin_theta_y);
+ }
+
+ if (rot.z != 0) {
+ sin_theta_z = lu_sin(rot.z) >> 4;
+ cos_theta_z = lu_cos(rot.z) >> 4;
+ res.x = fxmul(res.x, cos_theta_z) - fxmul(res.y, sin_theta_z);
+ res.y = fxmul(res.z, cos_theta_z) + fxmul(res.x, sin_theta_z);
+ }
+
+ return res;
+}
+
+void ModelInstance::render(std::shared_ptr<Scene> scene_context) {
+ usu::vector<POINT> projected(m_mesh->vertices.size());
+
+ for (std::uint32_t i = 0; i < projected.size(); i++) {
+ VECTOR transformed = rotate(m_mesh->vertices[i], m_rot);
+ vec_add(&transformed, &transformed, &m_pos);
+
+ projected[i] = scene_context->project_2d(transformed);
+ }
+
+ for (const TRIANGLE triangle : m_mesh->triangles) {
+ POINT v0 = projected[std::get<0>(triangle.vertex_indices)];
+ POINT v1 = projected[std::get<1>(triangle.vertex_indices)];
+ POINT v2 = projected[std::get<2>(triangle.vertex_indices)];
+
+ scene_context->draw_line(v0, v1, triangle.color_idx);
+ scene_context->draw_line(v1, v2, triangle.color_idx);
+ scene_context->draw_line(v2, v0, triangle.color_idx);
+ }
+}
+
+void ModelInstance::add_pos(VECTOR d_pos) { vec_add(&m_pos, &m_pos, &d_pos); }
diff --git a/src/scene.cpp b/src/scene.cpp
index e69de29..44e7028 100644
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -0,0 +1,38 @@
+#include "scene.hpp"
+
+Scene::Scene() {
+ directional_light = {0, 0, -1};
+ viewport_dimension = {3, 2};
+ scene_dimension = {SCREEN_WIDTH / 2, SCREEN_HEIGHT};
+
+ z_plane = int2fx(1);
+}
+
+POINT Scene::project_2d(VECTOR vertex) {
+ POINT pt = {0, 0};
+
+ if (vertex.z != 0) {
+ pt.x = fxdiv(z_plane, vertex.z);
+ pt.y = fxmul(vertex.y, pt.x);
+ pt.x = fxmul(vertex.x, pt.x);
+ }
+
+ return pt;
+}
+
+POINT Scene::viewport_to_scene(POINT p) {
+ FIXED x = fxmul(p.x, int2fx(std::get<0>(scene_dimension) /
+ std::get<0>(viewport_dimension)));
+ FIXED y = fxmul(p.y, int2fx(std::get<1>(scene_dimension) /
+ std::get<1>(viewport_dimension)));
+ return {x >> FIX_SHIFT, y >> FIX_SHIFT};
+}
+
+void Scene::draw_line(POINT p0, POINT p1, std::uint8_t pal_idx) {
+ POINT scene_p0 = viewport_to_scene(p0);
+ POINT scene_p1 = viewport_to_scene(p1);
+
+ std::uint16_t pixels = (pal_idx << 8) | pal_idx;
+ bmp16_line(scene_p0.x, scene_p0.y, scene_p1.x, scene_p1.y, pixels, vid_page,
+ SCREEN_WIDTH);
+}