draw cube with silhouette
This commit is contained in:
parent
b918082340
commit
e053b9646f
19
cube.hpp
19
cube.hpp
@ -2,10 +2,10 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../model.h"
|
||||
#include "model.hpp"
|
||||
|
||||
// floating-point
|
||||
vertex_position cube_position[] = {
|
||||
const vec3 cube_position[] = {
|
||||
{1.0, 1.0, -1.0},
|
||||
{1.0, -1.0, -1.0},
|
||||
{1.0, 1.0, 1.0},
|
||||
@ -17,7 +17,7 @@ vertex_position cube_position[] = {
|
||||
};
|
||||
|
||||
// floating-point
|
||||
vertex_texture cube_texture[] = {
|
||||
const vec2 cube_texture[] = {
|
||||
{0.625, 0.5},
|
||||
{0.875, 0.5},
|
||||
{0.875, 0.75},
|
||||
@ -35,7 +35,7 @@ vertex_texture cube_texture[] = {
|
||||
};
|
||||
|
||||
// floating-point
|
||||
vertex_normal cube_normal[] = {
|
||||
const vec3 cube_normal[] = {
|
||||
{0.0, 1.0, 0.0},
|
||||
{0.0, 0.0, 1.0},
|
||||
{-1.0, 0.0, 0.0},
|
||||
@ -44,7 +44,7 @@ vertex_normal cube_normal[] = {
|
||||
{0.0, 0.0, -1.0},
|
||||
};
|
||||
|
||||
union quadrilateral cube_Cube_quadrilateral[] = {
|
||||
const quadrilateral cube_Cube_quadrilateral[] = {
|
||||
{ .v = {
|
||||
{0, 0, 0},
|
||||
{4, 1, 0},
|
||||
@ -83,23 +83,22 @@ union quadrilateral cube_Cube_quadrilateral[] = {
|
||||
}},
|
||||
};
|
||||
|
||||
struct object cube_Cube = {
|
||||
const object cube_Cube = {
|
||||
.triangle = NULL,
|
||||
.quadrilateral = &cube_Cube_quadrilateral[0],
|
||||
.triangle_count = 0,
|
||||
.quadrilateral_count = 6,
|
||||
.material = Material,
|
||||
.material = -1,
|
||||
};
|
||||
|
||||
struct object * cube_object_list[] = {
|
||||
const object * cube_object_list[] = {
|
||||
&cube_Cube,
|
||||
};
|
||||
|
||||
struct model cube_model = {
|
||||
model cube_model = {
|
||||
.position = &cube_position[0],
|
||||
.texture = &cube_texture[0],
|
||||
.normal = &cube_normal[0],
|
||||
.object = &cube_object_list[0],
|
||||
.object_count = 1,
|
||||
};
|
||||
|
||||
|
178
main.cpp
178
main.cpp
@ -13,11 +13,20 @@
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#include "math/vec2.hpp"
|
||||
#include "math/vec3.hpp"
|
||||
#include "math/vec4.hpp"
|
||||
#include "math/mat3x3.hpp"
|
||||
#include "math/mat4x4.hpp"
|
||||
|
||||
using vec2 = vec<2, float>;
|
||||
using vec3 = vec<3, float>;
|
||||
using vec4 = vec<4, float>;
|
||||
using mat3x3 = mat<3, 3, float>;
|
||||
using mat4x4 = mat<4, 4, float>;
|
||||
|
||||
#include "cube.hpp"
|
||||
|
||||
struct glyph {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
@ -160,11 +169,6 @@ int32_t render_text(SDL_Renderer * renderer, int32_t x, int32_t y, const char *
|
||||
return x_advance;
|
||||
}
|
||||
|
||||
using vec3 = vec<3, float>;
|
||||
using vec4 = vec<4, float>;
|
||||
using mat3x3 = mat<3, 3, float>;
|
||||
using mat4x4 = mat<4, 4, float>;
|
||||
|
||||
struct line {
|
||||
vec3 a;
|
||||
vec3 b;
|
||||
@ -216,6 +220,11 @@ struct edge_normal quad[4] = {
|
||||
static int window_width = 1;
|
||||
static int window_height = 1;
|
||||
|
||||
static inline int max(int a, int b)
|
||||
{
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
static inline int min(int a, int b)
|
||||
{
|
||||
return (a > b) ? b : a;
|
||||
@ -287,6 +296,11 @@ static inline void render_line(SDL_Renderer * renderer, struct line line)
|
||||
assert(SDL_RenderLine(renderer, line.a.x, line.a.y, line.b.x, line.b.y));
|
||||
}
|
||||
|
||||
static inline void render_line_vtx(SDL_Renderer * renderer, vec3 a, vec3 b)
|
||||
{
|
||||
assert(SDL_RenderLine(renderer, a.x, a.y, b.x, b.y));
|
||||
}
|
||||
|
||||
void render_basis(SDL_Renderer * renderer)
|
||||
{
|
||||
// magenta: Z
|
||||
@ -310,10 +324,10 @@ void render_basis(SDL_Renderer * renderer)
|
||||
render_text(renderer, ((x.x - 30) * 64), ((x.y + 10) * 64), "+x", 2);
|
||||
}
|
||||
|
||||
static float ltheta = 0;
|
||||
|
||||
void render_quad(SDL_Renderer * renderer)
|
||||
vec3 update_light(SDL_Renderer * renderer)
|
||||
{
|
||||
static float ltheta = 0;
|
||||
|
||||
vec3 light_origin = {0, 0, 0};
|
||||
vec3 light_pos = {1, 1, 1};
|
||||
mat3x3 rot = {
|
||||
@ -325,6 +339,14 @@ void render_quad(SDL_Renderer * renderer)
|
||||
ltheta += deg / 4;
|
||||
vec3 light_vec = light_origin - light_pos;
|
||||
|
||||
assert(SDL_SetRenderDrawColorFloat(renderer, 0, 1, 0, 1));
|
||||
render_line(renderer, transform_line({light_origin, light_pos}, 0.5f));
|
||||
|
||||
return light_vec;
|
||||
}
|
||||
|
||||
void _render_quad(SDL_Renderer * renderer, vec3 light_vec)
|
||||
{
|
||||
for (int i = 0; i < 4; i++) {
|
||||
float d = dot(light_vec, quad[i].normal);
|
||||
|
||||
@ -338,9 +360,134 @@ void render_quad(SDL_Renderer * renderer)
|
||||
assert(SDL_SetRenderDrawColorFloat(renderer, 1, 0, 0, 1));
|
||||
render_line(renderer, transform_line({origin, origin + quad[i].normal}, 0.25f));
|
||||
}
|
||||
}
|
||||
|
||||
assert(SDL_SetRenderDrawColorFloat(renderer, 0, 1, 0, 1));
|
||||
render_line(renderer, transform_line({light_origin, light_pos}, 0.5f));
|
||||
void set_edge_coloring(uint8_t * edge_coloring,
|
||||
const int edge_stride,
|
||||
float l_dot_n, int a, int b)
|
||||
{
|
||||
bool d = l_dot_n > 0;
|
||||
|
||||
int ma = min(a, b);
|
||||
int mb = max(a, b);
|
||||
|
||||
int bit = 1 << ((int)d);
|
||||
|
||||
edge_coloring[ma * edge_stride + mb] |= bit;
|
||||
}
|
||||
|
||||
void render_quad(SDL_Renderer * renderer,
|
||||
const vec3 * position,
|
||||
const vec3 * normal,
|
||||
const quadrilateral * quadrilateral,
|
||||
const vec3 light_vec,
|
||||
uint8_t * edge_coloring,
|
||||
const int edge_stride)
|
||||
{
|
||||
vec3 n = normal[quadrilateral->a.normal];
|
||||
float l_dot_n = dot(light_vec, n);
|
||||
|
||||
if (l_dot_n > 0)
|
||||
assert(SDL_SetRenderDrawColorFloat(renderer, 1, 1, 1, 1));
|
||||
else
|
||||
assert(SDL_SetRenderDrawColorFloat(renderer, 0, 0, 1, 1));
|
||||
|
||||
float scale = 0.5f;
|
||||
|
||||
set_edge_coloring(edge_coloring,
|
||||
edge_stride,
|
||||
l_dot_n,
|
||||
quadrilateral->a.position,
|
||||
quadrilateral->b.position);
|
||||
set_edge_coloring(edge_coloring,
|
||||
edge_stride,
|
||||
l_dot_n,
|
||||
quadrilateral->b.position,
|
||||
quadrilateral->c.position);
|
||||
set_edge_coloring(edge_coloring,
|
||||
edge_stride,
|
||||
l_dot_n,
|
||||
quadrilateral->c.position,
|
||||
quadrilateral->d.position);
|
||||
set_edge_coloring(edge_coloring,
|
||||
edge_stride,
|
||||
l_dot_n,
|
||||
quadrilateral->d.position,
|
||||
quadrilateral->a.position);
|
||||
|
||||
vec3 ap = position[quadrilateral->a.position];
|
||||
vec3 bp = position[quadrilateral->b.position];
|
||||
vec3 cp = position[quadrilateral->c.position];
|
||||
vec3 dp = position[quadrilateral->d.position];
|
||||
vec3 n10 = n * 0.1f;
|
||||
|
||||
vec3 a = transform_vertex(ap + n10, scale);
|
||||
vec3 b = transform_vertex(bp + n10, scale);
|
||||
vec3 c = transform_vertex(cp + n10, scale);
|
||||
vec3 d = transform_vertex(dp + n10, scale);
|
||||
|
||||
render_line_vtx(renderer, a, b);
|
||||
render_line_vtx(renderer, b, c);
|
||||
render_line_vtx(renderer, c, d);
|
||||
render_line_vtx(renderer, d, a);
|
||||
|
||||
assert(SDL_SetRenderDrawColorFloat(renderer, 1, 0, 0, 1));
|
||||
|
||||
vec3 origin = (position[quadrilateral->a.position] +
|
||||
position[quadrilateral->b.position] +
|
||||
position[quadrilateral->c.position] +
|
||||
position[quadrilateral->d.position]) / 4.0f;
|
||||
|
||||
vec3 origin_t = transform_vertex(origin, scale);
|
||||
vec3 origin_n_t = transform_vertex(origin + n, scale);
|
||||
render_line_vtx(renderer, origin_t, origin_n_t);
|
||||
}
|
||||
|
||||
void render_silhouette(SDL_Renderer * renderer,
|
||||
const vec3 * position,
|
||||
const uint8_t * edge_coloring,
|
||||
const int edge_stride)
|
||||
{
|
||||
assert(SDL_SetRenderDrawColorFloat(renderer, 1, 0.5, 0, 1));
|
||||
|
||||
for (int a = 0; a < edge_stride; a++) {
|
||||
for (int b = 0; b < edge_stride; b++) {
|
||||
uint8_t coloring = edge_coloring[a * edge_stride + b];
|
||||
if (coloring == 0b11) {
|
||||
vec3 ap = position[a];
|
||||
vec3 bp = position[b];
|
||||
|
||||
float scale = 0.5f;
|
||||
vec3 av = transform_vertex(ap, scale);
|
||||
vec3 bv = transform_vertex(bp, scale);
|
||||
render_line_vtx(renderer, av, bv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void render_cube(SDL_Renderer * renderer, const vec3 light_vec)
|
||||
{
|
||||
const int edge_stride = 8;
|
||||
const int edge_coloring_length = edge_stride * edge_stride;
|
||||
uint8_t edge_coloring[edge_coloring_length];
|
||||
for (int i = 0; i < edge_coloring_length; i++)
|
||||
edge_coloring[i] = 0;
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
render_quad(renderer,
|
||||
cube_position,
|
||||
cube_normal,
|
||||
&cube_Cube_quadrilateral[i],
|
||||
light_vec,
|
||||
edge_coloring,
|
||||
edge_stride);
|
||||
}
|
||||
|
||||
render_silhouette(renderer,
|
||||
cube_position,
|
||||
edge_coloring,
|
||||
edge_stride);
|
||||
}
|
||||
|
||||
mat3x3 rotate_to(vec3 old_normal, vec3 new_normal)
|
||||
@ -485,8 +632,8 @@ int main()
|
||||
assert(success == true);
|
||||
|
||||
window = SDL_CreateWindow("sandbox",
|
||||
512, // w
|
||||
512, // h
|
||||
640, // w
|
||||
480, // h
|
||||
SDL_WINDOW_RESIZABLE);// | SDL_WINDOW_MAXIMIZED);
|
||||
|
||||
int num_drivers = SDL_GetNumRenderDrivers();
|
||||
@ -520,9 +667,11 @@ int main()
|
||||
bool success = SDL_GetWindowSizeInPixels(window, &window_width, &window_height);
|
||||
assert(success == true);
|
||||
|
||||
vec3 light_vec = update_light(renderer);
|
||||
|
||||
render_text_state(renderer);
|
||||
render_basis(renderer);
|
||||
render_quad(renderer);
|
||||
render_cube(renderer, light_vec);
|
||||
|
||||
while (SDL_GetTicks() - ticks < (1000 / 60)) { SDL_Delay(1); }
|
||||
SDL_RenderPresent(renderer);
|
||||
@ -548,7 +697,8 @@ int main()
|
||||
break;
|
||||
}
|
||||
}
|
||||
update_mouse_position();
|
||||
|
||||
//update_mouse_position();
|
||||
vtheta += deg / 10;
|
||||
}
|
||||
|
||||
|
51
model.hpp
Normal file
51
model.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "math/vec3.hpp"
|
||||
#include "math/vec2.hpp"
|
||||
|
||||
typedef struct index_ptn {
|
||||
uint16_t position;
|
||||
uint16_t texture;
|
||||
uint16_t normal;
|
||||
} index_ptn;
|
||||
|
||||
typedef union triangle {
|
||||
struct {
|
||||
struct index_ptn a;
|
||||
struct index_ptn b;
|
||||
struct index_ptn c;
|
||||
};
|
||||
struct index_ptn v[3];
|
||||
} triangle;
|
||||
|
||||
typedef union quadrilateral {
|
||||
struct {
|
||||
struct index_ptn a;
|
||||
struct index_ptn b;
|
||||
struct index_ptn c;
|
||||
struct index_ptn d;
|
||||
};
|
||||
struct index_ptn v[4];
|
||||
} quadrilateral;
|
||||
|
||||
using vertex_position = vec<3, float>;
|
||||
using vertex_normal = vec<3, float>;
|
||||
using vertex_texture = vec<2, float>;
|
||||
|
||||
typedef struct object {
|
||||
const union triangle * triangle;
|
||||
const union quadrilateral * quadrilateral;
|
||||
const int triangle_count;
|
||||
const int quadrilateral_count;
|
||||
const int material;
|
||||
} object;
|
||||
|
||||
typedef struct model {
|
||||
const vertex_position * position;
|
||||
const vertex_texture * texture;
|
||||
const vertex_normal * normal;
|
||||
const struct object ** object;
|
||||
const int object_count;
|
||||
} model;
|
Loading…
x
Reference in New Issue
Block a user