cube foo init
This commit is contained in:
parent
ebc517c800
commit
f4a7739a40
@ -14,9 +14,9 @@ typedef struct TRIANGLE {
|
|||||||
} TRIANGLE;
|
} TRIANGLE;
|
||||||
|
|
||||||
class Mesh {
|
class Mesh {
|
||||||
protected:
|
public:
|
||||||
usu::vector<VECTOR> m_vertices;
|
usu::vector<VECTOR> vertices;
|
||||||
usu::vector<TRIANGLE> m_triangles;
|
usu::vector<TRIANGLE> triangles;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MESH_HPP
|
#endif // MESH_HPP
|
||||||
|
@ -8,10 +8,14 @@
|
|||||||
class ModelInstance : Renderable {
|
class ModelInstance : Renderable {
|
||||||
private:
|
private:
|
||||||
FIXED m_scale;
|
FIXED m_scale;
|
||||||
VECTOR m_rotation;
|
VECTOR m_rotation; // though technically "FIXED"'s, these are simply s32's
|
||||||
|
// where [0, 2pi] -> [0, 0xFFFF] in the x,y,z axes
|
||||||
VECTOR m_pos;
|
VECTOR m_pos;
|
||||||
|
|
||||||
std::shared_ptr<Mesh> m_mesh;
|
std::shared_ptr<Mesh> m_mesh;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void render(std::shared_ptr<Scene> scene_context);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MODEL_INSTANCE_HPP
|
#endif // MODEL_INSTANCE_HPP
|
||||||
|
@ -1,20 +1,23 @@
|
|||||||
#ifndef CANVAS_HPP
|
#ifndef SCENE_HPP
|
||||||
#define CANVAS_HPP
|
#define SCENE_HPP
|
||||||
|
|
||||||
#include "mesh.hpp"
|
#include "model_instance.hpp"
|
||||||
#include "vector.hpp"
|
#include "vector.hpp"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <tonc.h>
|
||||||
|
|
||||||
class Scene {
|
class Scene {
|
||||||
private:
|
|
||||||
usu::vector<Mesh> meshes;
|
|
||||||
std::uint32_t width;
|
|
||||||
std::uint32_t height;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Scene();
|
usu::vector<Renderable> renderables;
|
||||||
|
std::tuple<std::uint16_t, std::uint16_t>
|
||||||
|
viewport_dimension; // <width, height>
|
||||||
|
std::tuple<std::uint16_t, std::uint16_t> scene_dimension;
|
||||||
|
VECTOR directional_light;
|
||||||
|
FIXED z_plane;
|
||||||
|
|
||||||
|
Scene();
|
||||||
void render();
|
void render();
|
||||||
|
POINT project_2d(VECTOR vertex);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SCENE_HPP
|
#endif // SCENE_HPP
|
||||||
|
@ -2,5 +2,5 @@
|
|||||||
|
|
||||||
Cube::Cube() {
|
Cube::Cube() {
|
||||||
for (std::uint8_t i = 0; i < 8; ++i)
|
for (std::uint8_t i = 0; i < 8; ++i)
|
||||||
m_vertices.add({(i >> 2) & 1, (i >> 1) & 1, i & 1});
|
vertices.add({(i >> 2) & 1, (i >> 1) & 1, i & 1});
|
||||||
}
|
}
|
||||||
|
11
src/mesh.hpp
11
src/mesh.hpp
@ -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)];
|
|
||||||
}
|
|
||||||
}
|
|
161
src/model_instance.cpp
Normal file
161
src/model_instance.cpp
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
#include "model_instance.hpp"
|
||||||
|
#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(©V);
|
||||||
|
|
||||||
|
// Grayscale color of the triangle from light intensity
|
||||||
|
clr = createColor(intensity >> FIX_SHIFT, intensity >> FIX_SHIFT,
|
||||||
|
intensity >> FIX_SHIFT);
|
||||||
|
|
||||||
|
if (dotProduct(&n, ©V) < 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 = lu_sin(rot.x) >> 4;
|
||||||
|
cos_theta_x = 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<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);
|
||||||
|
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)];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
#include "scene.hpp"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
Scene::Scene() {
|
||||||
|
directional_light = {0, 0, -1};
|
||||||
|
viewport_dimension = {2, 3};
|
||||||
|
scene_dimension = {SCREEN_WIDTH, 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};
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user