summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cube.cpp13
-rw-r--r--src/main.cpp30
-rw-r--r--src/model_instance.cpp131
-rw-r--r--src/scene.cpp29
4 files changed, 64 insertions, 139 deletions
diff --git a/src/cube.cpp b/src/cube.cpp
index 2fe855a..c181794 100644
--- a/src/cube.cpp
+++ b/src/cube.cpp
@@ -3,4 +3,17 @@
Cube::Cube() {
for (std::uint8_t i = 0; i < 8; ++i)
vertices.add({(i >> 2) & 1, (i >> 1) & 1, i & 1});
+
+ 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..0c91536 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,29 +1,33 @@
+#include "cube.hpp"
#include "palette.hpp"
+#include "renderable.hpp"
+#include "scene.hpp"
#include "vector.hpp"
#include <tonc.h>
+class Box : public Renderable {
+public:
+ virtual void render(std::shared_ptr<Scene> scene) {
+ scene->draw_line({0, 0}, {2 << FIX_SHIFT, 3 << FIX_SHIFT}, 1);
+ }
+};
+
int main() {
// interrupt & mode 4 foo
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<Renderable>((Renderable *)new Cube());
+ // scene->renderables.add(cube);
+ auto box = std::shared_ptr<Renderable>((Renderable *)new Box());
+
+ scene->renderables.add(box);
- std::uint32_t frame = 0;
while (1) {
- frame = (frame + 1) % 60;
- if (frame == 0) {
- vid_flip();
- }
+ Scene::render(scene);
VBlankIntrWait();
}
diff --git a/src/model_instance.cpp b/src/model_instance.cpp
index 48703a5..65ed6a8 100644
--- a/src/model_instance.cpp
+++ b/src/model_instance.cpp
@@ -2,118 +2,9 @@
#include "scene.hpp"
#include <tuple>
-/**
-static inline POINT viewportToScreen (POINT *point) {
- // Convert a viewport coordinate to screen x, y
- return createPoint(fixed_multiply(point->x, fixed_divide(WINDOW_WIDTH <<
-FIX_SHIFT, viewport_width << FIX_SHIFT)), fixed_multiply(point->y,
-fixed_divide(WINDOW_HEIGHT << FIX_SHIFT, viewport_height << FIX_SHIFT))
- );
-}
-
-static inline POINT projectVertex(VERTEX *vertex) {
- // Project a vertex to a point
- POINT temp;
- if (vertex->z != 0) {
- // Make sure we don't divide by zero
- temp = createPoint(fixed_multiply(vertex->x, fixed_divide(ZPlane <<
-FIX_SHIFT, vertex->z)), fixed_multiply(vertex->y, fixed_divide(ZPlane <<
-FIX_SHIFT, vertex->z))
- );
- }
- else {
- temp = createPoint(0, 0);
- }
- temp = viewportToScreen(&temp);
- return temp;
-}
-
-void renderInstance(INSTANCE *instance, SDL_Renderer *renderer) {
- // Render an instance
- // Array for projected points
- POINT projected[instance->model->vertices_length];
- // Pointers for transformed vertices
- VERTEX *transformed = malloc(sizeof(VERTEX) *
-instance->model->vertices_length);
-
- for (int i = 0; i < instance->model->vertices_length; i++) {
- // Apply translation and rotation
- *(transformed + i) = *(instance->model->vertices + i);
- applyXRotation((transformed + i), *instance->xRotation);
- applyYRotation((transformed + i), *instance->yRotation);
- applyZRotation((transformed + i), *instance->zRotation);
- *(transformed + i) = addVertices((transformed + i),
-instance->position);
- // Project vertices
- projected[i] = projectVertex(transformed + i);
- }
- VERTEX n, copyV;
- // A directional light source
- VERTEX playerLight = createVertex(0, 0, -1 << FIX_SHIFT);
- normalizeVertex(&playerLight);
- TRIANGLE *addr;
- FIXED intensity;
- COLOR clr;
- for (int i = 0; i < instance->model->triangles_length; i++) {
- // Render the triangle
- addr = (instance->model->triangles + i);
- n = computeNormal(transformed, addr);
- normalizeVertex(&n);
- // Intensity of light on the triangle
- intensity = fixed_multiply(dotProduct(&n, &playerLight) + (1 <<
-FIX_SHIFT), 127 << FIX_SHIFT); copyV = *(transformed + addr->v2);
- normalizeVertex(&copyV);
-
- // Grayscale color of the triangle from light intensity
- clr = createColor(intensity >> FIX_SHIFT, intensity >> FIX_SHIFT,
-intensity >> FIX_SHIFT);
-
- if (dotProduct(&n, &copyV) < 0) {
- // The triangle is viewable by the camera
- drawFilledTriangle(
- &(projected[addr->v0]),
- &(projected[addr->v1]),
- &(projected[addr->v2]),
- &clr,
- renderer
- );
-
- }
- }
- transformed = NULL;
- free(transformed);
-
-
-
-
- static inline void applyXRotation(VERTEX *vertex, FIXED xRotation) {
- // Apply rotation to vertex on x-axis
- FIXED sinTheta = float_to_fixed(sin(fixed_to_float(xRotation) * (3.14159 /
-180))); FIXED cosTheta = float_to_fixed(cos(fixed_to_float(xRotation) * (3.14159
-/ 180))); FIXED y = vertex->y; FIXED z = vertex->z; vertex->y =
-fixed_multiply(y, cosTheta) - fixed_multiply(z, sinTheta); vertex->z =
-fixed_multiply(z, cosTheta) + fixed_multiply(y, sinTheta);
-}
-
-static inline void applyYRotation(VERTEX *vertex, FIXED yRotation) {
- // Apply rotation to vertex on y-axis
- FIXED sinTheta = float_to_fixed(sin(fixed_to_float(yRotation) * (3.14159 /
-180))); FIXED cosTheta = float_to_fixed(cos(fixed_to_float(yRotation) * (3.14159
-/ 180))); FIXED x = vertex->x; FIXED z = vertex->z; vertex->x =
-fixed_multiply(x, cosTheta) + fixed_multiply(z, sinTheta); vertex->z =
-fixed_multiply(z, cosTheta) - fixed_multiply(x, sinTheta);
-}
-
-static inline void applyZRotation(VERTEX *vertex, FIXED zRotation) {
- // Apply rotation to vertex on z-axis
- FIXED sinTheta = float_to_fixed(sin(fixed_to_float(zRotation) * (3.14159 /
-180))); FIXED cosTheta = float_to_fixed(cos(fixed_to_float(zRotation) * (3.14159
-/ 180))); FIXED x = vertex->x; FIXED y = vertex->y; vertex->x =
-fixed_multiply(x, cosTheta) - fixed_multiply(y, sinTheta); vertex->y =
-fixed_multiply(y, cosTheta) + fixed_multiply(x, sinTheta);
-}
-}
- */
+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;
@@ -142,20 +33,26 @@ VECTOR rotate(VECTOR v, VECTOR rot) {
}
return res;
-};
+}
void ModelInstance::render(std::shared_ptr<Scene> scene_context) {
usu::vector<VECTOR> transformed(m_mesh->vertices.size());
usu::vector<POINT> projected(transformed.size());
for (std::uint32_t i = 0; i < transformed.size(); i++) {
- transformed[i] = rotate(m_mesh->vertices[i], m_rotation);
+ VECTOR rotated = rotate(m_mesh->vertices[i], m_rot);
+ vec_add(&transformed[i], &rotated, &m_pos);
+
projected[i] = scene_context->project_2d(m_mesh->vertices[i]);
}
for (const TRIANGLE triangle : m_mesh->triangles) {
- VECTOR v0 = transformed[std::get<0>(triangle.vertex_indices)];
- VECTOR v1 = transformed[std::get<1>(triangle.vertex_indices)];
- VECTOR v2 = transformed[std::get<2>(triangle.vertex_indices)];
+ 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);
}
}
diff --git a/src/scene.cpp b/src/scene.cpp
index b52553a..f69398d 100644
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -1,21 +1,13 @@
#include "scene.hpp"
-#include <memory>
Scene::Scene() {
directional_light = {0, 0, -1};
viewport_dimension = {2, 3};
- scene_dimension = {SCREEN_WIDTH, SCREEN_HEIGHT};
+ scene_dimension = {SCREEN_WIDTH / 2, SCREEN_HEIGHT};
z_plane = int2fx(1);
}
-void Scene::render() {
- auto this_ptr = std::make_shared<Scene>(this);
- for (auto renderable : renderables) {
- renderable.render(this_ptr);
- }
-}
-
POINT Scene::project_2d(VECTOR vertex) {
POINT pt = {0, 0};
@@ -27,3 +19,22 @@ POINT Scene::project_2d(VECTOR vertex) {
return pt;
}
+
+POINT Scene::viewport_to_scene(POINT p) {
+ FIXED x = fxmul(
+ p.x, (std::get<0>(scene_dimension) / std::get<0>(viewport_dimension))
+ << FIX_SHIFT);
+ FIXED y = fxmul(
+ p.y, (std::get<1>(scene_dimension) / std::get<1>(viewport_dimension))
+ << FIX_SHIFT);
+ return {x, y};
+}
+
+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,
+ M4_WIDTH);
+}