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 <stddef.h>
|
||||||
|
|
||||||
#include "../model.h"
|
#include "model.hpp"
|
||||||
|
|
||||||
// floating-point
|
// 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},
|
{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
|
// floating-point
|
||||||
vertex_texture cube_texture[] = {
|
const vec2 cube_texture[] = {
|
||||||
{0.625, 0.5},
|
{0.625, 0.5},
|
||||||
{0.875, 0.5},
|
{0.875, 0.5},
|
||||||
{0.875, 0.75},
|
{0.875, 0.75},
|
||||||
@ -35,7 +35,7 @@ vertex_texture cube_texture[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// floating-point
|
// floating-point
|
||||||
vertex_normal cube_normal[] = {
|
const vec3 cube_normal[] = {
|
||||||
{0.0, 1.0, 0.0},
|
{0.0, 1.0, 0.0},
|
||||||
{0.0, 0.0, 1.0},
|
{0.0, 0.0, 1.0},
|
||||||
{-1.0, 0.0, 0.0},
|
{-1.0, 0.0, 0.0},
|
||||||
@ -44,7 +44,7 @@ vertex_normal cube_normal[] = {
|
|||||||
{0.0, 0.0, -1.0},
|
{0.0, 0.0, -1.0},
|
||||||
};
|
};
|
||||||
|
|
||||||
union quadrilateral cube_Cube_quadrilateral[] = {
|
const quadrilateral cube_Cube_quadrilateral[] = {
|
||||||
{ .v = {
|
{ .v = {
|
||||||
{0, 0, 0},
|
{0, 0, 0},
|
||||||
{4, 1, 0},
|
{4, 1, 0},
|
||||||
@ -83,23 +83,22 @@ union quadrilateral cube_Cube_quadrilateral[] = {
|
|||||||
}},
|
}},
|
||||||
};
|
};
|
||||||
|
|
||||||
struct object cube_Cube = {
|
const object cube_Cube = {
|
||||||
.triangle = NULL,
|
.triangle = NULL,
|
||||||
.quadrilateral = &cube_Cube_quadrilateral[0],
|
.quadrilateral = &cube_Cube_quadrilateral[0],
|
||||||
.triangle_count = 0,
|
.triangle_count = 0,
|
||||||
.quadrilateral_count = 6,
|
.quadrilateral_count = 6,
|
||||||
.material = Material,
|
.material = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct object * cube_object_list[] = {
|
const object * cube_object_list[] = {
|
||||||
&cube_Cube,
|
&cube_Cube,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct model cube_model = {
|
model cube_model = {
|
||||||
.position = &cube_position[0],
|
.position = &cube_position[0],
|
||||||
.texture = &cube_texture[0],
|
.texture = &cube_texture[0],
|
||||||
.normal = &cube_normal[0],
|
.normal = &cube_normal[0],
|
||||||
.object = &cube_object_list[0],
|
.object = &cube_object_list[0],
|
||||||
.object_count = 1,
|
.object_count = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
176
main.cpp
176
main.cpp
@ -13,11 +13,20 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
#include "math/vec2.hpp"
|
||||||
#include "math/vec3.hpp"
|
#include "math/vec3.hpp"
|
||||||
#include "math/vec4.hpp"
|
#include "math/vec4.hpp"
|
||||||
#include "math/mat3x3.hpp"
|
#include "math/mat3x3.hpp"
|
||||||
#include "math/mat4x4.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 {
|
struct glyph {
|
||||||
int32_t width;
|
int32_t width;
|
||||||
int32_t height;
|
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;
|
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 {
|
struct line {
|
||||||
vec3 a;
|
vec3 a;
|
||||||
vec3 b;
|
vec3 b;
|
||||||
@ -216,6 +220,11 @@ struct edge_normal quad[4] = {
|
|||||||
static int window_width = 1;
|
static int window_width = 1;
|
||||||
static int window_height = 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)
|
static inline int min(int a, int b)
|
||||||
{
|
{
|
||||||
return (a > b) ? b : a;
|
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));
|
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)
|
void render_basis(SDL_Renderer * renderer)
|
||||||
{
|
{
|
||||||
// magenta: Z
|
// 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);
|
render_text(renderer, ((x.x - 30) * 64), ((x.y + 10) * 64), "+x", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 update_light(SDL_Renderer * renderer)
|
||||||
|
{
|
||||||
static float ltheta = 0;
|
static float ltheta = 0;
|
||||||
|
|
||||||
void render_quad(SDL_Renderer * renderer)
|
|
||||||
{
|
|
||||||
vec3 light_origin = {0, 0, 0};
|
vec3 light_origin = {0, 0, 0};
|
||||||
vec3 light_pos = {1, 1, 1};
|
vec3 light_pos = {1, 1, 1};
|
||||||
mat3x3 rot = {
|
mat3x3 rot = {
|
||||||
@ -325,6 +339,14 @@ void render_quad(SDL_Renderer * renderer)
|
|||||||
ltheta += deg / 4;
|
ltheta += deg / 4;
|
||||||
vec3 light_vec = light_origin - light_pos;
|
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++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
float d = dot(light_vec, quad[i].normal);
|
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));
|
assert(SDL_SetRenderDrawColorFloat(renderer, 1, 0, 0, 1));
|
||||||
render_line(renderer, transform_line({origin, origin + quad[i].normal}, 0.25f));
|
render_line(renderer, transform_line({origin, origin + quad[i].normal}, 0.25f));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert(SDL_SetRenderDrawColorFloat(renderer, 0, 1, 0, 1));
|
void set_edge_coloring(uint8_t * edge_coloring,
|
||||||
render_line(renderer, transform_line({light_origin, light_pos}, 0.5f));
|
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)
|
mat3x3 rotate_to(vec3 old_normal, vec3 new_normal)
|
||||||
@ -485,8 +632,8 @@ int main()
|
|||||||
assert(success == true);
|
assert(success == true);
|
||||||
|
|
||||||
window = SDL_CreateWindow("sandbox",
|
window = SDL_CreateWindow("sandbox",
|
||||||
512, // w
|
640, // w
|
||||||
512, // h
|
480, // h
|
||||||
SDL_WINDOW_RESIZABLE);// | SDL_WINDOW_MAXIMIZED);
|
SDL_WINDOW_RESIZABLE);// | SDL_WINDOW_MAXIMIZED);
|
||||||
|
|
||||||
int num_drivers = SDL_GetNumRenderDrivers();
|
int num_drivers = SDL_GetNumRenderDrivers();
|
||||||
@ -520,9 +667,11 @@ int main()
|
|||||||
bool success = SDL_GetWindowSizeInPixels(window, &window_width, &window_height);
|
bool success = SDL_GetWindowSizeInPixels(window, &window_width, &window_height);
|
||||||
assert(success == true);
|
assert(success == true);
|
||||||
|
|
||||||
|
vec3 light_vec = update_light(renderer);
|
||||||
|
|
||||||
render_text_state(renderer);
|
render_text_state(renderer);
|
||||||
render_basis(renderer);
|
render_basis(renderer);
|
||||||
render_quad(renderer);
|
render_cube(renderer, light_vec);
|
||||||
|
|
||||||
while (SDL_GetTicks() - ticks < (1000 / 60)) { SDL_Delay(1); }
|
while (SDL_GetTicks() - ticks < (1000 / 60)) { SDL_Delay(1); }
|
||||||
SDL_RenderPresent(renderer);
|
SDL_RenderPresent(renderer);
|
||||||
@ -548,7 +697,8 @@ int main()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
update_mouse_position();
|
|
||||||
|
//update_mouse_position();
|
||||||
vtheta += deg / 10;
|
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