flat shading
This commit is contained in:
parent
28c30a7fcf
commit
5b72bd3337
@ -10,6 +10,7 @@ add_executable(${PROJECT_NAME} scripts/main.c
|
||||
scripts/matrix.c
|
||||
scripts/mesh.c
|
||||
scripts/triangle.c
|
||||
scripts/light.c
|
||||
scripts/display.c)
|
||||
|
||||
# --- SDL2 SETUP ---
|
||||
|
||||
@ -29,6 +29,8 @@ enum cull_methods {
|
||||
CULL_BACKFACE,
|
||||
};
|
||||
|
||||
typedef uint32_t color_t;
|
||||
|
||||
bool initialize_window(void);
|
||||
void draw_grid(void);
|
||||
void draw_pixel(int x, int y, uint32_t color);
|
||||
|
||||
13
scripts/light.c
Normal file
13
scripts/light.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t light_apply_intensity(uint32_t original_color, float p) {
|
||||
if (p < 0) p = 0;
|
||||
if (p > 1) p = 1;
|
||||
|
||||
uint32_t a = (original_color & 0xFF000000);
|
||||
uint32_t r = (original_color & 0x00FF0000) * p;
|
||||
uint32_t g = (original_color & 0x0000FF00) * p;
|
||||
uint32_t b = (original_color & 0x000000FF) * p;
|
||||
|
||||
return (a | (r & 0x00FF0000) | (g & 0x0000FF00) | (b & 0x000000FF));
|
||||
}
|
||||
14
scripts/light.h
Normal file
14
scripts/light.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef LIGHT_H
|
||||
#define LIGHT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "vector.h"
|
||||
|
||||
typedef struct {
|
||||
vec3_t direction;
|
||||
} light_t;
|
||||
|
||||
uint32_t light_apply_intensity(uint32_t original_color, float p);
|
||||
|
||||
#endif
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include "vector.h"
|
||||
#include "array.h"
|
||||
#include "matrix.h"
|
||||
#include "light.h"
|
||||
|
||||
#define STEP 0.075
|
||||
|
||||
@ -31,10 +32,12 @@ triangle_t* triangles_to_render = NULL; //[N_MESH_FACES];
|
||||
vec3_t camera_position = { 0, 0, 0 };
|
||||
|
||||
mat4_t proj_matrix;
|
||||
light_t light = { .direction = { .x = 0, .y = 0, .z = 1 }};
|
||||
|
||||
bool is_running = false;
|
||||
|
||||
int cull_method = CULL_BACKFACE;
|
||||
int render_method = RENDER_WIRE_VERTEX;
|
||||
int render_method = RENDER_FILL_TRIANGLE;
|
||||
bool sort_faces = true;
|
||||
|
||||
uint32_t previous_frame_time = 0;
|
||||
@ -56,11 +59,12 @@ void setup(void) {
|
||||
float aspect = (float)window_height / (float)window_width;
|
||||
float znear = 0.0f;
|
||||
float zfar = 100.0f;
|
||||
|
||||
proj_matrix = mat4_make_perspective(fov, aspect, znear, zfar);
|
||||
|
||||
// load cube mesh data
|
||||
//load_file("..\\assets\\tank.obj");
|
||||
load_cube_mesh_data();
|
||||
load_file("..\\assets\\f22.obj");
|
||||
//load_cube_mesh_data();
|
||||
|
||||
}
|
||||
|
||||
@ -137,14 +141,14 @@ void update(void) {
|
||||
|
||||
previous_frame_time = SDL_GetTicks();
|
||||
|
||||
mesh.rotation.y += 0.01f;
|
||||
//mesh.rotation.y += 0.01f;
|
||||
mesh.rotation.x -= 0.01f;
|
||||
mesh.rotation.z += 0.01f;
|
||||
//mesh.rotation.z += 0.01f;
|
||||
|
||||
mesh.translation.x += 0.004f;
|
||||
//mesh.translation.x += 0.004f;
|
||||
mesh.translation.z = 5.0f;
|
||||
|
||||
mesh.scale.x += 0.002f;
|
||||
//mesh.scale.x += 0.002f;
|
||||
//mesh.scale.y += 0.002f;
|
||||
|
||||
// create scale matrix that will be used
|
||||
@ -190,8 +194,6 @@ void update(void) {
|
||||
transformed_vertices[j] = transformed_vertex;
|
||||
}
|
||||
|
||||
if (cull_method == CULL_BACKFACE) {
|
||||
// check backface culling
|
||||
vec3_t vector_a = vec3_from_vec4(transformed_vertices[0]); /* A */
|
||||
vec3_t vector_b = vec3_from_vec4(transformed_vertices[1]); /* / \ */
|
||||
vec3_t vector_c = vec3_from_vec4(transformed_vertices[2]); /* C---B */
|
||||
@ -206,6 +208,9 @@ void update(void) {
|
||||
vec3_t normal = vec3_cross(vector_ab, vector_ac);
|
||||
vec3_normalize(&normal);
|
||||
|
||||
if (cull_method == CULL_BACKFACE) {
|
||||
// check backface culling
|
||||
|
||||
// find the vector between a point in the triangle and the camera origin
|
||||
vec3_t camera_ray = vec3_subtract(camera_position, vector_a);
|
||||
|
||||
@ -224,26 +229,31 @@ void update(void) {
|
||||
projected_points[j] = mat4_mul_vec4_project(proj_matrix, transformed_vertices[j]);
|
||||
|
||||
// Scale into the view
|
||||
projected_points[j].x *= roundf(window_width / 2.0);
|
||||
projected_points[j].y *= roundf(window_height / 2.0);
|
||||
projected_points[j].x *= (window_width / 2.0);
|
||||
projected_points[j].y *= (window_height / 2.0);
|
||||
|
||||
// Translate the projected points to the middle of the screen
|
||||
projected_points[j].x += roundf(window_width / 2.0);
|
||||
projected_points[j].y += roundf(window_height / 2.0);
|
||||
projected_points[j].x += (window_width / 2.0);
|
||||
projected_points[j].y += (window_height / 2.0);
|
||||
|
||||
//projected_triangle.points[j] = projected_point;
|
||||
}
|
||||
|
||||
// calculate color using normal and light direction, then invert
|
||||
float dot_color_p = -vec3_dot(normal, light.direction);
|
||||
|
||||
color_t flat_shaded_color = light_apply_intensity(0xFFFFFFFF, dot_color_p);
|
||||
|
||||
// calculate the average depth of the triangle
|
||||
float avg_depth = (transformed_vertices[0].z + transformed_vertices[1].z + transformed_vertices[2].z) / 3.0f;
|
||||
|
||||
#define FUNC3 roundf
|
||||
triangle_t projected_triangle = {
|
||||
.points = {
|
||||
{ projected_points[0].x, projected_points[0].y },
|
||||
{ projected_points[1].x, projected_points[1].y },
|
||||
{ projected_points[2].x, projected_points[2].y },
|
||||
{ FUNC3(projected_points[0].x), FUNC3(projected_points[0].y) },
|
||||
{ FUNC3(projected_points[1].x), FUNC3(projected_points[1].y) },
|
||||
{ FUNC3(projected_points[2].x), FUNC3(projected_points[2].y) },
|
||||
},
|
||||
.color = mesh_face.color,
|
||||
.color = flat_shaded_color,
|
||||
.average_depth = avg_depth,
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user