loading an object

This commit is contained in:
Tyrel Souza 2024-04-20 22:13:56 -04:00
parent cec7699ea5
commit e267f4476a
8 changed files with 200 additions and 24 deletions

28
LICENSE Normal file
View File

@ -0,0 +1,28 @@
array.h is a fork from zauonlok's (github.com/zauonlok) darray.h file with
small syntax changes.
------------------------------------------------------------------------------
darray.h is under the following license:
MIT License
Copyright (c) 2020 Zhou Le
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

46
assets/cube.obj Normal file
View File

@ -0,0 +1,46 @@
# Blender v2.76 (sub 0) OBJ File: ''
# www.blender.org
mtllib cube.mtl
o Cube
v -1.000000 -1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v 1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
vt 1.000000 0.000000
vt 0.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 -1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
g cube
usemtl cube
s 1
f 1/1/1 2/2/1 3/3/1
f 3/3/3 2/2/1 4/4/1
s 2
f 3/1/2 4/2/2 5/3/2
f 5/3/2 4/2/2 6/4/2
s 3
f 5/4/3 6/3/3 7/2/3
f 7/2/3 6/3/3 8/1/3
s 4
f 7/1/4 8/1/4 1/3/4
f 1/3/4 8/2/4 2/4/4
s 5
f 2/1/5 8/2/5 4/3/5
f 4/3/5 8/2/5 6/4/5
s 6
f 7/1/6 1/2/6 5/3/6
f 5/3/6 1/2/6 3/4/6

40
src/array.c Normal file
View File

@ -0,0 +1,40 @@
#include <stdio.h>
#include <stdlib.h>
#include "array.h"
#define ARRAY_RAW_DATA(array) ((int*)(array) - 2)
#define ARRAY_CAPACITY(array) (ARRAY_RAW_DATA(array)[0])
#define ARRAY_OCCUPIED(array) (ARRAY_RAW_DATA(array)[1])
void* array_hold(void* array, int count, int item_size) {
if (array == NULL) {
int raw_size = (sizeof(int) * 2) + (item_size * count);
int* base = (int*)malloc(raw_size);
base[0] = count; // capacity
base[1] = count; // occupied
return base + 2;
} else if (ARRAY_OCCUPIED(array) + count <= ARRAY_CAPACITY(array)) {
ARRAY_OCCUPIED(array) += count;
return array;
} else {
int needed_size = ARRAY_OCCUPIED(array) + count;
int double_curr = ARRAY_CAPACITY(array) * 2;
int capacity = needed_size > double_curr ? needed_size : double_curr;
int occupied = needed_size;
int raw_size = sizeof(int) * 2 + item_size * capacity;
int* base = (int*)realloc(ARRAY_RAW_DATA(array), raw_size);
base[0] = capacity;
base[1] = occupied;
return base + 2;
}
}
int array_length(void* array) {
return (array != NULL) ? ARRAY_OCCUPIED(array) : 0;
}
void array_free(void* array) {
if (array != NULL) {
free(ARRAY_RAW_DATA(array));
}
}

14
src/array.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef ARRAY_H
#define ARRAY_H
#define array_push(array, value) \
do { \
(array) = array_hold((array), 1, sizeof(*(array))); \
(array)[array_length(array) - 1] = (value); \
} while (0);
void* array_hold(void* array, int count, int item_size);
int array_length(void* array);
void array_free(void* array);
#endif

View File

@ -98,7 +98,6 @@ void draw_rect(int x, int y, int width, int height, uint32_t color) {
} }
void destroy_window(void) { void destroy_window(void) {
free(color_buffer);
SDL_DestroyRenderer(renderer); SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
SDL_DestroyTexture(color_buffer_texture); SDL_DestroyTexture(color_buffer_texture);

View File

@ -4,15 +4,18 @@
#include "display.h" #include "display.h"
#include "vector.h" #include "vector.h"
#include "mesh.h" #include "mesh.h"
#include "array.h"
triangle_t* triangles_to_render = NULL;
vec3_t camera_position = {0, 0, -5}; vec3_t camera_position = {0, 0, -5};
vec3_t cube_rotation = {.x = 0, .y = 0, .z = 0};
triangle_t triangles_to_render[N_MESH_FACES];
float fov_factor = 640; float fov_factor = 640;
bool is_running = false; bool is_running = false;
uint32_t previous_frame_time = 0; uint32_t previous_frame_time = 0;
void free_resources();
void setup(void) { void setup(void) {
// Allocate the required memory in bytes to hold color buffer // Allocate the required memory in bytes to hold color buffer
color_buffer = (uint32_t *) malloc(sizeof(uint32_t) * window_width * window_height); color_buffer = (uint32_t *) malloc(sizeof(uint32_t) * window_width * window_height);
@ -25,6 +28,9 @@ void setup(void) {
window_width, window_width,
window_height window_height
); );
// load cube vertices into mesh data
load_cube_mesh_data();
} }
void process_input(void) { void process_input(void) {
@ -62,23 +68,27 @@ void update(void) {
} }
previous_frame_time = SDL_GetTicks(); previous_frame_time = SDL_GetTicks();
cube_rotation.y += 0.01f; //initialize array of triangles
cube_rotation.z += 0.01f; triangles_to_render = NULL;
cube_rotation.x += 0.01f;
for (int i = 0; i < N_MESH_FACES; i++) { mesh.rotation.y += 0.01f;
face_t mesh_face = mesh_faces[i]; mesh.rotation.z += 0.01f;
mesh.rotation.x += 0.01f;
int num_faces = array_length(mesh.faces);
for (int i = 0; i < num_faces; i++) {
face_t mesh_face = mesh.faces[i];
vec3_t face_vertices[3]; vec3_t face_vertices[3];
face_vertices[0] = mesh_vertices[mesh_face.a - 1]; face_vertices[0] = mesh.vertices[mesh_face.a - 1];
face_vertices[1] = mesh_vertices[mesh_face.b - 1]; face_vertices[1] = mesh.vertices[mesh_face.b - 1];
face_vertices[2] = mesh_vertices[mesh_face.c - 1]; face_vertices[2] = mesh.vertices[mesh_face.c - 1];
//loop all three vertices //loop all three vertices
triangle_t projected_triangle; triangle_t projected_triangle;
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
vec3_t transformed_vertex = face_vertices[j]; vec3_t transformed_vertex = face_vertices[j];
transformed_vertex = vec3_rotate_y(transformed_vertex, cube_rotation.y); transformed_vertex = vec3_rotate_y(transformed_vertex, mesh.rotation.y);
transformed_vertex = vec3_rotate_x(transformed_vertex, cube_rotation.x); transformed_vertex = vec3_rotate_x(transformed_vertex, mesh.rotation.x);
transformed_vertex = vec3_rotate_z(transformed_vertex, cube_rotation.z); transformed_vertex = vec3_rotate_z(transformed_vertex, mesh.rotation.z);
transformed_vertex.z -= camera_position.z; transformed_vertex.z -= camera_position.z;
vec2_t projected_point = project(transformed_vertex); vec2_t projected_point = project(transformed_vertex);
@ -88,16 +98,18 @@ void update(void) {
projected_triangle.points[j] = projected_point; projected_triangle.points[j] = projected_point;
} }
// save projected triangle in array of triangles to render // save projected triangle in array of triangles to render
triangles_to_render[i] = projected_triangle; array_push(triangles_to_render, projected_triangle);
} }
} }
void render(void) { void render(void) {
draw_grid(); // draw_grid();
for (int i = 0; i < N_MESH_FACES; i++) { //triangle array size
int num_triangles = array_length(triangles_to_render);
for (int i = 0; i < num_triangles; i++) {
triangle_t triangle = triangles_to_render[i]; triangle_t triangle = triangles_to_render[i];
uint32_t color = 0xFFFFFF00; uint32_t color = 0xFFFFFF00;
for (int j = 0; j < 3; j++) { for (int j = 0; j < 3; j++) {
@ -117,6 +129,13 @@ void render(void) {
} }
void free_resources() {
array_free(triangles_to_render);
array_free(mesh.vertices);
array_free(mesh.faces);
free(color_buffer);
}
int main(void) { int main(void) {
is_running = initialize_window(); is_running = initialize_window();
setup(); setup();
@ -127,5 +146,7 @@ int main(void) {
render(); render();
} }
destroy_window(); destroy_window();
free_resources();
return 0; return 0;
} }

View File

@ -1,6 +1,14 @@
#include <stdio.h>
#include "mesh.h" #include "mesh.h"
#include "array.h"
vec3_t mesh_vertices[N_MESH_VERTICES] = { mesh_t mesh = {
.vertices = NULL,
.faces = NULL,
.rotation = {0,0,0}
};
vec3_t cube_vertices[N_CUBE_VERTICES] = {
{.x = -1, .y = -1, .z = -1}, {.x = -1, .y = -1, .z = -1},
{.x = -1, .y = 1, .z = -1}, {.x = -1, .y = 1, .z = -1},
{.x = 1, .y = 1, .z = -1}, {.x = 1, .y = 1, .z = -1},
@ -11,7 +19,7 @@ vec3_t mesh_vertices[N_MESH_VERTICES] = {
{.x = -1, .y = -1, .z = 1}, {.x = -1, .y = -1, .z = 1},
}; };
face_t mesh_faces[N_MESH_FACES] = { face_t cube_faces[N_CUBE_FACES] = {
// Front // Front
{.a = 1, .b = 2, .c = 3}, {.a = 1, .b = 2, .c = 3},
{.a = 1, .b = 3, .c = 4}, {.a = 1, .b = 3, .c = 4},
@ -31,3 +39,14 @@ face_t mesh_faces[N_MESH_FACES] = {
{.a = 6, .b = 8, .c = 1}, {.a = 6, .b = 8, .c = 1},
{.a = 6, .b = 1, .c = 4}, {.a = 6, .b = 1, .c = 4},
}; };
void load_cube_mesh_data(void) {
for (int i = 0; i < N_CUBE_VERTICES; i++){
vec3_t cube_vertex = cube_vertices[i];
array_push(mesh.vertices, cube_vertex);
}
for (int i = 0; i < N_CUBE_FACES; i++){
face_t cube_face = cube_faces[i];
array_push(mesh.faces, cube_face);
}
}

View File

@ -2,10 +2,19 @@
#define RENDERER_MESH_H #define RENDERER_MESH_H
#include "vector.h" #include "vector.h"
#include "triangle.h" #include "triangle.h"
#define N_MESH_VERTICES 8 #define N_CUBE_VERTICES 8
#define N_MESH_FACES (6 * 2 ) #define N_CUBE_FACES (6 * 2)
extern vec3_t mesh_vertices[N_MESH_VERTICES]; extern vec3_t cube_vertices[N_CUBE_VERTICES];
extern face_t mesh_faces[N_MESH_FACES]; extern face_t cube_faces[N_CUBE_FACES];
typedef struct {
vec3_t* vertices;
face_t* faces;
vec3_t rotation;
} mesh_t;
extern mesh_t mesh;
void load_cube_mesh_data(void);
#endif //RENDERER_MESH_H #endif //RENDERER_MESH_H