Browse Source

added object loading, updated test screen

IverMartinson 5 months ago
parent
commit
e1863b6e0d

+ 2 - 1
.vscode/settings.json

@@ -2,5 +2,6 @@
     "files.associations": {
     "files.associations": {
         "functions.h": "c",
         "functions.h": "c",
         "sdl.h": "c"
         "sdl.h": "c"
-    }
+    },
+    "OpenCL.explorer.localizedProperties": false
 }
 }

BIN
build/librasteriver.so


BIN
build/main.bin


+ 46 - 0
objects/cube.obj

@@ -0,0 +1,46 @@
+# Blender 4.4.3
+# 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
+vn -0.0000 1.0000 -0.0000
+vn -0.0000 -0.0000 1.0000
+vn -1.0000 -0.0000 -0.0000
+vn -0.0000 -1.0000 -0.0000
+vn 1.0000 -0.0000 -0.0000
+vn -0.0000 -0.0000 -1.0000
+vt 0.875000 0.500000
+vt 0.625000 0.750000
+vt 0.625000 0.500000
+vt 0.375000 1.000000
+vt 0.375000 0.750000
+vt 0.625000 0.000000
+vt 0.375000 0.250000
+vt 0.375000 0.000000
+vt 0.375000 0.500000
+vt 0.125000 0.750000
+vt 0.125000 0.500000
+vt 0.625000 0.250000
+vt 0.875000 0.750000
+vt 0.625000 1.000000
+s 0
+usemtl Material
+f 5/1/1 3/2/1 1/3/1
+f 3/2/2 8/4/2 4/5/2
+f 7/6/3 6/7/3 8/8/3
+f 2/9/4 8/10/4 6/11/4
+f 1/3/5 4/5/5 2/9/5
+f 5/12/6 2/9/6 6/7/6
+f 5/1/1 7/13/1 3/2/1
+f 3/2/2 7/14/2 8/4/2
+f 7/6/3 5/12/3 6/7/3
+f 2/9/4 4/5/4 8/10/4
+f 1/3/5 3/2/5 4/5/5
+f 5/12/6 1/3/6 2/9/6

+ 27 - 0
src/headers/custom_types.h

@@ -1,6 +1,33 @@
 #ifndef CUSTOM_TYPES_H
 #ifndef CUSTOM_TYPES_H
 #define CUSTOM_TYPES_H
 #define CUSTOM_TYPES_H
 
 
+#include "math.h"
 
 
+typedef struct {
+    RI_vector_3f position;
+    RI_vector_3f *normal;
+    RI_vector_2f *uv;
+} RI_vertex;
+
+typedef struct {
+    RI_vertex *vertex_0;
+    RI_vertex *vertex_1;
+    RI_vertex *vertex_2;
+} RI_face;
+
+typedef struct {
+    RI_face *faces;
+    RI_vertex *vertecies;
+    RI_vector_3f *normals;
+    RI_vector_2f *uvs;
+    int face_count;
+    int vertex_count;
+    int normal_count;
+    int uv_count;
+} RI_object_data;
+
+typedef struct {
+    RI_object_data *object_data;
+} RI_actor;
 
 
 #endif
 #endif

+ 4 - 3
src/headers/functions.h

@@ -1,8 +1,9 @@
 #ifndef FUNCTIONS_H
 #ifndef FUNCTIONS_H
 #define FUNCTIONS_H
 #define FUNCTIONS_H
 
 
-int RI_init(int RI_window_width, int RI_window_height, char *RI_window_title);
-int RI_stop(int result);
-int RI_tick();
+int RI_request_objects(int RI_number_of_requested_objects, char **filenames); // Load object file(s)
+int RI_init(int RI_window_width, int RI_window_height, char *RI_window_title); // Initialize RasterIver
+int RI_stop(int result); // Stop RasterIver safely and free memory
+int RI_tick(); // Tick RasterIver and render a frame
 
 
 #endif
 #endif

+ 15 - 0
src/headers/math.h

@@ -0,0 +1,15 @@
+#ifndef MATH_H
+#define MATH_H
+
+typedef struct {
+    float x; 
+    float y; 
+} RI_vector_2f;
+
+typedef struct {
+    float x; 
+    float y; 
+    float z; 
+} RI_vector_3f;
+
+#endif

+ 14 - 0
src/headers/rasteriver.h

@@ -3,6 +3,8 @@
 
 
 #include "functions.h"
 #include "functions.h"
 #include "values.h"
 #include "values.h"
+#include "custom_types.h"
+#include "math.h"
 #include <SDL2/SDL.h>
 #include <SDL2/SDL.h>
 
 
 typedef struct {
 typedef struct {
@@ -19,10 +21,22 @@ typedef struct {
     SDL_Event event;
     SDL_Event event;
     
     
     // RasterIver
     // RasterIver
+    RI_vertex *verticies; //data type that holds info about a vertex (positon, normal, UV coord)
+
+    RI_vector_3f *loaded_object_vetex_positions; // original vertex positions from a loaded object
+    RI_vector_3f *normals; // original normal vectors from a loaded object
+    RI_vector_2f *uvs; // UV coords from a loaded object
+    
+    RI_vector_3f *transformed_vertex_positions; // vertex positions after trasformations (object & camera rotation & position changes, scale, etc)
+    RI_vector_3f *transformed_normals; // normal vectors after rotation transformations (otherwise a normal's space would constantly be in local space instead of world space)
+
+    RI_object_data *loaded_objects;
 
 
     // miscellaneous
     // miscellaneous
+    int loaded_object_count;
     int running;
     int running;
     int frame;
     int frame;
+    char* prefix;
 } RasterIver;
 } RasterIver;
 
 
 #endif
 #endif

+ 4 - 0
src/launch_program/main.c

@@ -5,6 +5,10 @@ int main(){
 
 
     int running = 1;
     int running = 1;
 
 
+    char *filenames[] = {"objects/cube.obj"};
+
+    RI_request_objects(1, filenames);
+
     while (running){
     while (running){
         RI_tick();
         RI_tick();
     }
     }

+ 184 - 7
src/library/rasteriver.c

@@ -1,13 +1,188 @@
+#include <stdio.h>
 #include <CL/cl.h>
 #include <CL/cl.h>
 #include <SDL2/SDL.h>
 #include <SDL2/SDL.h>
 #include "../headers/rasteriver.h"
 #include "../headers/rasteriver.h"
 
 
 RasterIver ri;
 RasterIver ri;
 
 
+void debug(char *string, ...){
+    va_list args;
+    va_start(args, string);
+
+    char message[500];
+
+    strcpy(message, ri.prefix);
+
+    strcat(message, string);
+
+    vprintf(message, args);
+    printf("\n");
+
+    va_end(args);
+}
+
+int RI_request_objects(int RI_number_of_requested_objects, char **filenames){
+    int objects_already_loaded_count = ri.loaded_object_count;
+    
+    ri.loaded_object_count += RI_number_of_requested_objects;
+
+    ri.loaded_objects = realloc(ri.loaded_objects, sizeof(RI_object_data) * ri.loaded_object_count);
+
+    for (int i = 0; i < RI_number_of_requested_objects; i++){
+        RI_object_data new_object_data_struct;
+
+        new_object_data_struct.face_count = 0;
+        new_object_data_struct.vertex_count = 0;
+        new_object_data_struct.normal_count = 0;
+        new_object_data_struct.uv_count = 0;
+        
+        FILE *file = fopen(filenames[i], "r");
+
+        if (!file){
+            debug("Error! File \"%s\" not found", filenames[i]);
+            RI_stop(1);
+        }
+        
+        char line[256];
+        
+        while (fgets(line, sizeof(line), file)) {
+            if (line[0] == 'f' && line[1] == ' ') { // face
+                new_object_data_struct.face_count++;
+            }
+            else if (line[0] == 'v' && line[1] == ' ') { // vertex
+                new_object_data_struct.vertex_count++;
+            }
+            else if (line[0] == 'v' && line[1] == 'n') { // normal
+                new_object_data_struct.normal_count++;
+            }
+            else if (line[0] == 'v' && line[1] == 't') { // UV
+                new_object_data_struct.uv_count++;
+            }
+        }
+        
+        fclose(file);
+        
+        new_object_data_struct.faces = malloc(sizeof(RI_face) * new_object_data_struct.face_count);
+        new_object_data_struct.vertecies = malloc(sizeof(RI_vertex) * new_object_data_struct.vertex_count);
+        new_object_data_struct.normals = malloc(sizeof(RI_vector_3f) * new_object_data_struct.normal_count);
+        new_object_data_struct.uvs = malloc(sizeof(RI_vector_2f) * new_object_data_struct.uv_count);
+
+        file = fopen(filenames[i], "r");
+        
+        int current_face_index = 0;
+        int current_vertex_index = 0;
+        int current_normal_index = 0;
+        int current_uv_index = 0;
+
+        int has_normals, has_uvs;
+        has_normals = has_uvs = 0;
+
+        while (fgets(line, sizeof(line), file)) {
+            if (line[0] == 'f' && line[1] == ' ') {
+                int vertex_0_index, vertex_1_index, vertex_2_index, normal_0_index, normal_1_index, normal_2_index, uv_0_index, uv_1_index, uv_2_index;
+
+                int matches = sscanf(line, "f %d/%d/%d %d/%d/%d %d/%d/%d/", 
+                    &vertex_0_index, &uv_0_index, &normal_0_index, 
+                    &vertex_1_index, &uv_1_index, &normal_1_index, 
+                    &vertex_2_index, &uv_2_index, &normal_2_index);
+    
+                if (matches != 9){
+                    vertex_0_index = -1;
+                    vertex_1_index = -1;
+                    vertex_2_index = -1;
+                    
+                    normal_0_index = -1;
+                    normal_1_index = -1;
+                    normal_2_index = -1;
+                    
+                    uv_0_index = -1;
+                    uv_1_index = -1;
+                    uv_2_index = -1;
+    
+                    if (strchr(line, '/')){
+                        sscanf(line, "f %d//%d %d//%d %d//%d", 
+                            &vertex_0_index, &normal_0_index, 
+                            &vertex_1_index, &normal_1_index, 
+                            &vertex_2_index, &normal_2_index);
+                    
+                        has_normals = 1;
+                    }
+                    else {
+                        sscanf(line, "f %d %d %d", 
+                            &vertex_0_index, 
+                            &vertex_1_index, 
+                            &vertex_2_index);
+                        
+                        has_uvs = 1;
+                    }
+                }
+                else {
+                    has_normals = has_uvs = 1;
+                }
+
+                new_object_data_struct.faces[current_face_index].vertex_0 = &new_object_data_struct.vertecies[vertex_0_index - 1];
+                new_object_data_struct.faces[current_face_index].vertex_1 = &new_object_data_struct.vertecies[vertex_1_index - 1];
+                new_object_data_struct.faces[current_face_index].vertex_2 = &new_object_data_struct.vertecies[vertex_2_index - 1];
+            
+                ++current_face_index;
+            }
+            else if (line[0] == 'v' && line[1] == ' ') {
+                float x, y, z;
+                
+                sscanf(line, "v %f %f %f", &x, &y, &z);
+
+                new_object_data_struct.vertecies[current_vertex_index].position.x = x;
+                new_object_data_struct.vertecies[current_vertex_index].position.y = y;
+                new_object_data_struct.vertecies[current_vertex_index].position.z = z;
+
+                ++current_vertex_index;
+            } 
+            else if (line[0] == 'v' && line[1] == 'n') {
+                float x, y, z;
+                
+                sscanf(line, "vn %f %f %f", &x, &y, &z);
+
+                new_object_data_struct.normals[current_vertex_index].x = x;
+                new_object_data_struct.normals[current_vertex_index].y = y;
+                new_object_data_struct.normals[current_vertex_index].z = z;
+             
+                ++current_normal_index;
+            }
+            else if (line[0] == 'v' && line[1] == 't') {
+                float x, y, z;
+
+                sscanf(line, "vt %f %f %f", &x, &y, &z);
+
+                new_object_data_struct.normals[current_vertex_index].x = x;
+                new_object_data_struct.normals[current_vertex_index].y = y;
+                // UVS are almost always 2D so we don't need this (the type itself is a vector 2f) -> new_object_data_struct.normals[current_vertex_index].z = z; 
+              
+                ++current_uv_index;
+            } 
+        }
+
+        char* loading_object_notice_string;
+
+        if (has_normals && !has_uvs) loading_object_notice_string = "normals";
+        else if (!has_normals && has_uvs) loading_object_notice_string = "UVs";
+        else if (!has_normals && !has_uvs) loading_object_notice_string = "normals and UVs";
+        
+        if (!has_normals || !has_uvs) debug("Notice! Object \"%s\" is missing %s", filenames[i], loading_object_notice_string);
+        
+        fclose(file);
+
+        ri.loaded_objects[objects_already_loaded_count + i] = new_object_data_struct;    
+    }
+
+    return 0;
+}
+
 int RI_tick(){
 int RI_tick(){
     // do rendering stuff
     // do rendering stuff
     if (ri.running){
     if (ri.running){
-        ri.frame_buffer[(ri.frame * 10) % (ri.window_width * ri.window_height)] += 100;
+        for (int i = 0; i < ri.window_width; ++i){
+            ri.frame_buffer[(ri.frame % ri.window_height) * ri.window_width + i] = 0x0 + ri.frame + i * ri.frame;
+        }
 
 
         SDL_UpdateTexture(ri.texture, NULL, ri.frame_buffer, ri.window_width * sizeof(uint32_t));
         SDL_UpdateTexture(ri.texture, NULL, ri.frame_buffer, ri.window_width * sizeof(uint32_t));
 
 
@@ -21,12 +196,10 @@ int RI_tick(){
     }
     }
 
 
     // handle SDL events
     // handle SDL events
-    while (SDL_PollEvent(&ri.event))
-    {
-        switch (ri.event.type)
-        {
-        case SDL_QUIT:
-            ri.running = 0;
+    while (SDL_PollEvent(&ri.event)){
+        switch (ri.event.type){
+            case SDL_QUIT:
+                ri.running = 0;
         }
         }
     }
     }
 
 
@@ -64,10 +237,14 @@ int RI_init(int RI_window_width, int RI_window_height, char *RI_window_title){
 
 
     sdl_init(RI_window_width, RI_window_height, RI_window_title);
     sdl_init(RI_window_width, RI_window_height, RI_window_title);
 
 
+    ri.prefix = "[RasterIver]";
+
     return 0;
     return 0;
 }
 }
 
 
 int RI_stop(int result){
 int RI_stop(int result){
+    debug("Stopping...");
+    
     exit(result);
     exit(result);
 
 
     return 0;
     return 0;