Browse Source

added obj parser and basic object functions/variables

IverMartinson 8 months ago
parent
commit
af060b7ad5

+ 3 - 3
Makefile

@@ -1,10 +1,10 @@
 COMPILER=gcc
 FLAGS_ALL=-g -Wall -Wextra
-FLAGS_EXAMPLE=-Lbuilds/final\ binaries -lrasteriver -Wl,-rpath=builds/final\ binaries/
+FLAGS_EXAMPLE=-Lbuilds/final\ binaries -lrasteriver -Wl,-rpath=builds/final\ binaries/ -lm
 FLAGS_LIB=-D CL_TARGET_OPENCL_VERSION=120 -fPIC -shared -lc -lSDL2 -lSDL2_ttf -lm -lOpenCL
 
-example.bin: rasteriver.so
-	$(COMPILER) $(FLAGS_ALL) src/test\ programs/example.c -o builds/final\ binaries/example.bin $(FLAGS_EXAMPLE) 
+main.bin: rasteriver.so
+	$(COMPILER) $(FLAGS_ALL) src/launch\ program/main.c -o builds/final\ binaries/main.bin $(FLAGS_EXAMPLE) 
 
 rasteriver.so:
 	$(COMPILER) $(FLAGS_ALL) src/RasterIver/source\ code/rasteriver.c -o builds/final\ binaries/librasteriver.so $(FLAGS_LIB) 

BIN
builds/final binaries/example.bin


BIN
builds/final binaries/librasteriver.so


BIN
builds/final binaries/main.bin


+ 1 - 1
dbg

@@ -1 +1 @@
-gdb -ex run builds/final\ binaries/example.bin
+gdb -ex run builds/final\ binaries/main.bin

+ 46 - 0
obj_file.obj

@@ -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 -0.999999
+v 0.999999 1.000000 1.000001
+v -1.000000 1.000000 1.000000
+v -1.000000 1.000000 -1.000000
+vt 1.000000 0.333333
+vt 1.000000 0.666667
+vt 0.666667 0.666667
+vt 0.666667 0.333333
+vt 0.666667 0.000000
+vt 0.000000 0.333333
+vt 0.000000 0.000000
+vt 0.333333 0.000000
+vt 0.333333 1.000000
+vt 0.000000 1.000000
+vt 0.000000 0.666667
+vt 0.333333 0.333333
+vt 0.333333 0.666667
+vt 1.000000 0.000000
+vn 0.000000 -1.000000 0.000000
+vn 0.000000 1.000000 0.000000
+vn 1.000000 0.000000 0.000000
+vn -0.000000 0.000000 1.000000
+vn -1.000000 -0.000000 -0.000000
+vn 0.000000 0.000000 -1.000000
+usemtl Material
+s off
+f 2/1/1 3/2/1 4/3/1
+f 8/1/2 7/4/2 6/5/2
+f 5/6/3 6/7/3 2/8/3
+f 6/8/4 7/5/4 3/4/4
+f 3/9/5 7/10/5 8/11/5
+f 1/12/6 4/13/6 8/11/6
+f 1/4/1 2/1/1 4/3/1
+f 5/14/2 8/1/2 6/5/2
+f 1/12/3 5/6/3 2/8/3
+f 2/12/4 6/8/4 3/4/4
+f 4/13/5 3/9/5 8/11/5
+f 5/6/6 1/12/6 8/11/6

+ 1 - 1
run

@@ -1 +1 @@
-./builds/final\ binaries/example.bin
+./builds/final\ binaries/main.bin

+ 321 - 0
src/RasterIver/headers/rasteriver.h

@@ -7,6 +7,33 @@ typedef int RI_result;
 typedef int RI_flag;
 typedef uint32_t RI_uint;
 typedef float* RI_polygons;
+typedef float* RI_verticies;
+typedef int* RI_triangles;
+typedef int* RI_objects;
+typedef char* RI_textures;
+
+// the size of each object instance in the objects array
+// xyz + rot(xyz) + scale(xyz) = 9
+// 9 + polygon count + polygon index + texture index = 12
+#define object_size 12
+
+// vertex size
+// the size of each instance of verticies
+#define vs 3
+
+// triangle size
+// 3 xyz 3 normals 3 uvs 
+#define ts 9
+
+typedef struct {
+    float x, y, z, r_x, r_y, r_z, s_x, s_y, s_z;
+    char file_path[40];
+    char texture[40];
+} RI_newObject;
+
+typedef struct {
+    int verticies, normals, uvs, faces, length_of_texture;
+} load_object_return;
 
 // RI_result
 typedef enum {
@@ -26,12 +53,14 @@ typedef enum {
     RI_FLAG_DEBUG_FPS           = 4,
     RI_FLAG_CLEAN_POLYGONS      = 5,
     RI_FLAG_POPULATE_POLYGONS   = 6,
+    RI_FLAG_BE_MASTER_RENDERER  = 7,
 } RI_flag_enum;
 
 RI_result   RI_Init();
 RI_result   RI_Stop();
 RI_result   RI_IsRunning();
 RI_polygons RI_RequestPolygons(int RI_PolygonsToRequest);
+RI_result   RI_RequestObjects(RI_newObject *RI_ObjectBuffer, int RI_ObjectsToRequest);
 RI_result   RI_Tick();
 RI_result   RI_SetBackground(RI_uint RI_BackgroundColor);
 RI_result   RI_ShowZBuffer(int RI_ShowZBufferFlag);
@@ -39,4 +68,296 @@ RI_result   RI_SetFlag(RI_flag RI_FlagToSet, int RI_Value);
 RI_result   RI_SetFpsCap(int RI_FpsCap);
 RI_result   RI_ListFlags();
 
+const char *kernel_source_non_master = " \
+int is_intersecting(float a, float b, float c, float d, float p, float q, float r, float s) { \
+    float det, gamma, lambda; \
+    \
+    det = (c - a) * (s - q) - (r - p) * (d - b); \
+    \
+    if (det == 0) { \
+        return 1; \
+    }  \
+    else { \
+        lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det; \
+        gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det; \
+        return (0 < lambda && lambda < 1) && (0 < gamma && gamma < 1); \
+    } \
+} \
+\
+void norm(float dest[2], float a[2]){ \
+    float magnitude = sqrt(a[0] * a[0] + a[1] * a[1]); \
+    \
+    dest[0] = a[0] / magnitude; \
+    dest[1] = a[1] / magnitude; \
+    } \
+    \
+    void sub(float dest[2], float a[2], float b[2]){ \
+    dest[0] = a[0] - b[0]; \
+    dest[1] = a[1] - b[1]; \
+    } \
+    \
+    void add(float dest[2], float a[2], float b[2]){ \
+    dest[0] = a[0] + b[0]; \
+    dest[1] = a[1] + b[1]; \
+} \
+\
+__kernel void raster_kernel(__global float* polygons, __global uint* frame_buffer, int polygon_count, int width, int height, int show_z_buffer, float highest_z){ \
+    int id_x = get_global_id(0); \
+    int id_y = get_global_id(1); \
+    \
+    float z_pixel = 0; \
+    uint frame_pixel = 0x22222222; \
+    \
+    float biggest_z = 0;\
+    \
+    for (int polygon = 0; polygon < polygon_count; polygon++){ \
+        int base = polygon * 9; \
+        float x0 = polygons[base]; \
+        float y0 = polygons[base + 1]; \
+        float z0 = polygons[base + 2]; \
+        float x1 = polygons[base + 3]; \
+        float y1 = polygons[base + 4]; \
+        float z1 = polygons[base + 5]; \
+        float x2 = polygons[base + 6]; \
+        float y2 = polygons[base + 7]; \
+        float z2 = polygons[base + 8]; \
+        \
+        if (isinf(x0) || isinf(y0) || isinf(z0) || isinf(x1) || isinf(y1) || isinf(z1) || isinf(x2) || isinf(y2) || isinf(z2)){\
+            return;\
+        }\
+        \
+        float smallest_x = x0; \
+        float largest_x = x0; \
+        float smallest_y = y0; \
+        float largest_y = y0; \
+        \
+        for (int point = 0; point < 3; point++){ \
+            float x = polygons[base + point * 3]; \
+            float y = polygons[base + point * 3 + 1]; \
+            \
+            if (x > largest_x){ \
+                largest_x = x; \
+            } \
+            \
+            if (x < smallest_x){ \
+                smallest_x = x; \
+            } \
+            \
+            if (y > largest_y){ \
+                largest_y = y; \
+            } \
+            \
+            if (y < smallest_y){\
+                smallest_y = y;\
+            } \
+        } \
+        \
+        smallest_x = fmin(smallest_x, 0); \
+        largest_x = fmax(largest_x, width); \
+        smallest_y = fmin(smallest_y, 0); \
+        largest_y = fmax(largest_y, height); \
+        \
+        if (id_x >= smallest_x && id_x <= largest_x && id_y >= smallest_y && id_y <= largest_y){ \
+            int intersections = 0; \
+            \
+            intersections += is_intersecting(id_x, id_y, 10000, 100000, x0, y0, x1, y1); \
+            intersections += is_intersecting(id_x, id_y, 10000, 100000, x1, y1, x2, y2); \
+            intersections += is_intersecting(id_x, id_y, 10000, 100000, x2, y2, x0, y0); \
+            \
+            if (intersections % 2 == 0){ \
+                continue; \
+            } \
+            \
+            float denominator = (y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2); \
+            float w0 = ((y1 - y2) * (id_x - x2) + (x2 - x1) * (id_y - y2)) / denominator; \
+            float w1 = ((y2 - y0) * (id_x - x0) + (x0 - x2) * (id_y - y2)) / denominator; \
+            float w2 = 1.0 - w0 - w1; \
+            \
+            if (denominator < 0) { \
+                w0 = -w0; \
+                w1 = -w1; \
+                w2 = -w2; \
+                denominator = -denominator; \
+            } \
+            \
+            float z = w0 * z0 + w1 * z1 + w2 * z2; \
+            \
+            if (z < 0){ \
+                z *= -1; \
+            } \
+            \
+            if (z > z_pixel){ \
+                z_pixel = z; \
+            } \
+             \
+            else { \
+                continue; \
+            } \
+            \
+            frame_pixel = 0xFFFFFFFF / polygon_count * (polygon + 1); \
+        } \
+    } \
+    \
+    if (id_y * width + id_x > width * height){\
+    return;\
+    }\
+    frame_buffer[id_y * width + id_x] = frame_pixel; \
+    \
+    if (!show_z_buffer){return;}\
+    \
+    float z = clamp(z_pixel, 0.0f, highest_z);\
+    \
+    float norm_z = z / highest_z;\
+    \
+    uchar intensity = (uchar)(norm_z * 255.0f);\
+    \
+    frame_buffer[id_y * width + id_x] = 0xFF000000 | (intensity << 16) | (intensity << 8) | intensity;\
+}\n";
+
+const char *kernel_source_master = " \
+int is_intersecting(float a, float b, float c, float d, float p, float q, float r, float s) { \
+    float det, gamma, lambda; \
+    \
+    det = (c - a) * (s - q) - (r - p) * (d - b); \
+    \
+    if (det == 0) { \
+        return 1; \
+    }  \
+    else { \
+        lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det; \
+        gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det; \
+        return (0 < lambda && lambda < 1) && (0 < gamma && gamma < 1); \
+    } \
+} \
+\
+void norm(float dest[2], float a[2]){ \
+    float magnitude = sqrt(a[0] * a[0] + a[1] * a[1]); \
+    \
+    dest[0] = a[0] / magnitude; \
+    dest[1] = a[1] / magnitude; \
+    } \
+    \
+    void sub(float dest[2], float a[2], float b[2]){ \
+    dest[0] = a[0] - b[0]; \
+    dest[1] = a[1] - b[1]; \
+    } \
+    \
+    void add(float dest[2], float a[2], float b[2]){ \
+    dest[0] = a[0] + b[0]; \
+    dest[1] = a[1] + b[1]; \
+} \
+\
+__kernel void raster_kernel(__global float* polygons, __global uint* frame_buffer, int polygon_count, int width, int height, int show_z_buffer, float highest_z){ \
+    int id_x = get_global_id(0); \
+    int id_y = get_global_id(1); \
+    \
+    float z_pixel = 0; \
+    uint frame_pixel = 0x22222222; \
+    \
+    float biggest_z = 0;\
+    \
+    for (int polygon = 0; polygon < polygon_count; polygon++){ \
+        int base = polygon * 9; \
+        float x0 = polygons[base]; \
+        float y0 = polygons[base + 1]; \
+        float z0 = polygons[base + 2]; \
+        float x1 = polygons[base + 3]; \
+        float y1 = polygons[base + 4]; \
+        float z1 = polygons[base + 5]; \
+        float x2 = polygons[base + 6]; \
+        float y2 = polygons[base + 7]; \
+        float z2 = polygons[base + 8]; \
+        \
+        if (isinf(x0) || isinf(y0) || isinf(z0) || isinf(x1) || isinf(y1) || isinf(z1) || isinf(x2) || isinf(y2) || isinf(z2)){\
+            return;\
+        }\
+        \
+        float smallest_x = x0; \
+        float largest_x = x0; \
+        float smallest_y = y0; \
+        float largest_y = y0; \
+        \
+        for (int point = 0; point < 3; point++){ \
+            float x = polygons[base + point * 3]; \
+            float y = polygons[base + point * 3 + 1]; \
+            \
+            if (x > largest_x){ \
+                largest_x = x; \
+            } \
+            \
+            if (x < smallest_x){ \
+                smallest_x = x; \
+            } \
+            \
+            if (y > largest_y){ \
+                largest_y = y; \
+            } \
+            \
+            if (y < smallest_y){\
+                smallest_y = y;\
+            } \
+        } \
+        \
+        smallest_x = fmin(smallest_x, 0); \
+        largest_x = fmax(largest_x, width); \
+        smallest_y = fmin(smallest_y, 0); \
+        largest_y = fmax(largest_y, height); \
+        \
+        if (id_x >= smallest_x && id_x <= largest_x && id_y >= smallest_y && id_y <= largest_y){ \
+            int intersections = 0; \
+            \
+            intersections += is_intersecting(id_x, id_y, 10000, 100000, x0, y0, x1, y1); \
+            intersections += is_intersecting(id_x, id_y, 10000, 100000, x1, y1, x2, y2); \
+            intersections += is_intersecting(id_x, id_y, 10000, 100000, x2, y2, x0, y0); \
+            \
+            if (intersections % 2 == 0){ \
+                continue; \
+            } \
+            \
+            float denominator = (y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2); \
+            float w0 = ((y1 - y2) * (id_x - x2) + (x2 - x1) * (id_y - y2)) / denominator; \
+            float w1 = ((y2 - y0) * (id_x - x0) + (x0 - x2) * (id_y - y2)) / denominator; \
+            float w2 = 1.0 - w0 - w1; \
+            \
+            if (denominator < 0) { \
+                w0 = -w0; \
+                w1 = -w1; \
+                w2 = -w2; \
+                denominator = -denominator; \
+            } \
+            \
+            float z = w0 * z0 + w1 * z1 + w2 * z2; \
+            \
+            if (z < 0){ \
+                z *= -1; \
+            } \
+            \
+            if (z > z_pixel){ \
+                z_pixel = z; \
+            } \
+             \
+            else { \
+                continue; \
+            } \
+            \
+            frame_pixel = 0xFFFFFFFF / polygon_count * (polygon + 1); \
+        } \
+    } \
+    \
+    if (id_y * width + id_x > width * height){\
+    return;\
+    }\
+    frame_buffer[id_y * width + id_x] = frame_pixel; \
+    \
+    if (!show_z_buffer){return;}\
+    \
+    float z = clamp(z_pixel, 0.0f, highest_z);\
+    \
+    float norm_z = z / highest_z;\
+    \
+    uchar intensity = (uchar)(norm_z * 255.0f);\
+    \
+    frame_buffer[id_y * width + id_x] = 0xFF000000 | (intensity << 16) | (intensity << 8) | intensity;\
+}\n";
+
 #endif // RASTERIVER_H

+ 359 - 195
src/RasterIver/source code/rasteriver.c

@@ -5,154 +5,9 @@
 #include <CL/cl.h>
 #include "../headers/rasteriver.h"
 #include <stdarg.h>
+#include <stdio.h>
 #include <SDL2/SDL_ttf.h>
 
-const char *kernel_source = " \
-int is_intersecting(float a, float b, float c, float d, float p, float q, float r, float s) { \
-    float det, gamma, lambda; \
-    \
-    det = (c - a) * (s - q) - (r - p) * (d - b); \
-    \
-    if (det == 0) { \
-        return 1; \
-    }  \
-    else { \
-        lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det; \
-        gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det; \
-        return (0 < lambda && lambda < 1) && (0 < gamma && gamma < 1); \
-    } \
-} \
-\
-void norm(float dest[2], float a[2]){ \
-    float magnitude = sqrt(a[0] * a[0] + a[1] * a[1]); \
-    \
-    dest[0] = a[0] / magnitude; \
-    dest[1] = a[1] / magnitude; \
-    } \
-    \
-    void sub(float dest[2], float a[2], float b[2]){ \
-    dest[0] = a[0] - b[0]; \
-    dest[1] = a[1] - b[1]; \
-    } \
-    \
-    void add(float dest[2], float a[2], float b[2]){ \
-    dest[0] = a[0] + b[0]; \
-    dest[1] = a[1] + b[1]; \
-} \
-\
-__kernel void raster_kernel(__global float* polygons, __global uint* frame_buffer, int polygon_count, int width, int height, int show_z_buffer, float highest_z){ \
-    int id_x = get_global_id(0); \
-    int id_y = get_global_id(1); \
-    \
-    float z_pixel = 0; \
-    uint frame_pixel = 0x22222222; \
-    \
-    float biggest_z = 0;\
-    \
-    for (int polygon = 0; polygon < polygon_count; polygon++){ \
-        int base = polygon * 9; \
-        float x0 = polygons[base]; \
-        float y0 = polygons[base + 1]; \
-        float z0 = polygons[base + 2]; \
-        float x1 = polygons[base + 3]; \
-        float y1 = polygons[base + 4]; \
-        float z1 = polygons[base + 5]; \
-        float x2 = polygons[base + 6]; \
-        float y2 = polygons[base + 7]; \
-        float z2 = polygons[base + 8]; \
-        \
-        if (isinf(x0) || isinf(y0) || isinf(z0) || isinf(x1) || isinf(y1) || isinf(z1) || isinf(x2) || isinf(y2) || isinf(z2)){\
-            return;\
-        }\
-        \
-        float smallest_x = x0; \
-        float largest_x = x0; \
-        float smallest_y = y0; \
-        float largest_y = y0; \
-        \
-        for (int point = 0; point < 3; point++){ \
-            float x = polygons[base + point * 3]; \
-            float y = polygons[base + point * 3 + 1]; \
-            \
-            if (x > largest_x){ \
-                largest_x = x; \
-            } \
-            \
-            if (x < smallest_x){ \
-                smallest_x = x; \
-            } \
-            \
-            if (y > largest_y){ \
-                largest_y = y; \
-            } \
-            \
-            if (y < smallest_y){\
-                smallest_y = y;\
-            } \
-        } \
-        \
-        smallest_x = fmin(smallest_x, 0); \
-        largest_x = fmax(largest_x, width); \
-        smallest_y = fmin(smallest_y, 0); \
-        largest_y = fmax(largest_y, height); \
-        \
-        if (id_x >= smallest_x && id_x <= largest_x && id_y >= smallest_y && id_y <= largest_y){ \
-            int intersections = 0; \
-            \
-            intersections += is_intersecting(id_x, id_y, 10000, 100000, x0, y0, x1, y1); \
-            intersections += is_intersecting(id_x, id_y, 10000, 100000, x1, y1, x2, y2); \
-            intersections += is_intersecting(id_x, id_y, 10000, 100000, x2, y2, x0, y0); \
-            \
-            if (intersections % 2 == 0){ \
-                continue; \
-            } \
-            \
-            float denominator = (y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2); \
-            float w0 = ((y1 - y2) * (id_x - x2) + (x2 - x1) * (id_y - y2)) / denominator; \
-            float w1 = ((y2 - y0) * (id_x - x0) + (x0 - x2) * (id_y - y2)) / denominator; \
-            float w2 = 1.0 - w0 - w1; \
-            \
-            if (denominator < 0) { \
-                w0 = -w0; \
-                w1 = -w1; \
-                w2 = -w2; \
-                denominator = -denominator; \
-            } \
-            \
-            float z = w0 * z0 + w1 * z1 + w2 * z2; \
-            \
-            if (z < 0){ \
-                z *= -1; \
-            } \
-            \
-            if (z > z_pixel){ \
-                z_pixel = z; \
-            } \
-             \
-            else { \
-                continue; \
-            } \
-            \
-            frame_pixel = 0xFFFFFFFF / polygon_count * (polygon + 1); \
-        } \
-    } \
-    \
-    if (id_y * width + id_x > width * height){\
-    return;\
-    }\
-    frame_buffer[id_y * width + id_x] = frame_pixel; \
-    \
-    if (!show_z_buffer){return;}\
-    \
-    float z = clamp(z_pixel, 0.0f, highest_z);\
-    \
-    float norm_z = z / highest_z;\
-    \
-    uchar intensity = (uchar)(norm_z * 255.0f);\
-    \
-    frame_buffer[id_y * width + id_x] = 0xFF000000 | (intensity << 16) | (intensity << 8) | intensity;\
-}\n";
-
 // ----- Internal Variables
 int width;
 int height;
@@ -163,6 +18,14 @@ float highest_z = 0;
 int polygon_count;
 RI_polygons polygons = NULL;
 
+int object_count;
+RI_objects objects;
+RI_verticies verticies;
+RI_verticies normals;
+RI_verticies uvs;
+RI_triangles triangles;
+RI_textures textures;
+
 int running = 1;
 int frame = 0;
 
@@ -172,6 +35,7 @@ int show_fps = 0;
 int debug_fps = 0;
 int clean_polygons = 0;
 int populate_polygons = 0;
+int be_master_renderer = 0;
 
 Uint64 start_time;
 double frame_time_ms;
@@ -211,8 +75,17 @@ cl_command_queue queue;
 cl_mem input_memory_buffer;
 cl_mem output_memory_buffer;
 
-cl_program kernel_program;
-cl_kernel compiled_kernel;
+cl_mem object_memory_buffer;
+cl_mem triangles_memory_buffer;
+cl_mem verticies_memory_buffer;
+cl_mem normals_memory_buffer;
+cl_mem uvs_memory_buffer;
+
+cl_program kernel_program_non_master;
+cl_kernel compiled_kernel_non_master;
+
+cl_program kernel_program_master;
+cl_kernel compiled_kernel_master;
 
 size_t size_2d[2];
 size_t local_size;
@@ -248,7 +121,7 @@ RI_result erchk_func(cl_int error, int line, char *file)
     {
         debug(0, "OpenCL Error: %d at line %d at file %s", error, line, file);
 
-        RI_Stop();
+        RI_Stop(0);
     }
 
     return RI_SUCCESS;
@@ -278,6 +151,7 @@ RI_result RI_ListFlags(){
     printf("RI_FLAG_DEBUG_FPS: Debug FPS into the console");
     printf("RI_FLAG_CLEAN_POLYGONS: When requesting polygons, write INF to the array. (INF means a triangle doesn't exist. Useful for if you allocate more space than there are triangles, but inefficient if you call RI_RequestPolygons frequently\n)");
     printf("RI_FLAG_POPULATE_POLYGONS: When requesting polygons, populate the array with random triangles (useful for testing/benchmark)\n");
+    printf("RI_FLAG_BE_MASTER_RENDERER: If this is 0, RasterIver only acts as a polygon renderer. If 1, you get all the features like objects and rotations.\n");
 
     return RI_SUCCESS;
 }
@@ -316,6 +190,10 @@ RI_result RI_SetFlag(RI_flag RI_FlagToSet, int RI_Value)
         populate_polygons = RI_Value;
         break;
 
+    case RI_FLAG_BE_MASTER_RENDERER:
+        be_master_renderer = RI_Value;
+        break;
+
     default:
         return RI_INVALID_FLAG;
     }
@@ -367,14 +245,256 @@ RI_polygons RI_RequestPolygons(int RI_PolygonsToRequest){
     
     if (input_memory_buffer == NULL)
     {
-        debug(0, "OpenCL buffer creation Failed for polygons.");
+        debug(0, "clCreateBuffer Failed for Requested Polygons");
     }
+
+    erchk(error);
     
     debug(1, "Request for %d Polygons Granted", polygon_count);
     
     return polygons;
 }
 
+int num_verticies = 0;
+int num_normals = 0;
+int num_uvs = 0;
+int num_faces = 0;
+
+int cur_verticies = 0;
+int cur_normals = 0;
+int cur_uvs = 0;
+int cur_faces = 0;
+
+void slice(char *string, char *result, int start, int end){
+    strncpy(result, string + start, end - start);
+}
+
+void malloc_objects(int objects, char **file_names){
+    for (int i = 0; i < objects; i++){
+        FILE *file = fopen(file_names[i], "r");
+
+        if(file == NULL){
+            debug(0, "Error Opening Object File");
+            RI_Stop(0);
+        }
+
+        char line[256];
+
+        while (fgets(line, sizeof(line), file)) {
+            if (line[0] == 'f' && line[1] == ' ') {
+                num_faces++;
+            } 
+            else if (line[0] == 'v' && line[1] == ' ') {
+                num_verticies++;
+            } 
+            else if (line[0] == 'v' && line[1] == 'n') {
+                num_normals++;
+            } 
+            else if (line[0] == 'v' && line[1] == 't') {
+                num_uvs++;
+            } 
+        }
+
+        fclose(file);
+    }
+
+    if(verticies != NULL){
+        free(verticies);
+    } 
+
+    if(normals != NULL){
+        free(normals);
+    } 
+    
+    if(uvs != NULL){
+        free(uvs);
+    } 
+
+    if(triangles != NULL){
+        free(triangles);
+    } 
+
+    verticies = malloc(sizeof(RI_verticies) * num_verticies * vs);
+    normals = malloc(sizeof(RI_verticies) * num_normals * vs);
+    uvs = malloc(sizeof(RI_verticies) * num_uvs * vs);
+    triangles = malloc(sizeof(RI_triangles) * num_faces * ts);
+
+    debug(0, "vert %d", num_verticies);
+    debug(0, "norm %d", num_normals);
+    debug(0, "uvs %d", num_uvs);
+    debug(0, "tri %d", num_faces);
+
+    return;
+}
+
+load_object_return load_object(char *object_path, int object_offset){
+    debug(1, "Loading Object #%d...", object_offset + 1);
+
+    debug(1, "Opening File \"%s\"...", object_path);
+
+    FILE *file = fopen(object_path, "r");
+
+    if(file == NULL){
+        debug(0, "Error Opening Object File");
+        RI_Stop(0);
+    }
+
+    char line[256];
+    
+
+    // current triangle
+    int ct = 0;
+    int cn = 0;
+    int cv = 0;
+    int cu = 0;
+
+    while (fgets(line, sizeof(line), file)) {
+        if (line[0] == 'f' && line[1] == ' ') {
+
+            int matches = sscanf(line, "f %d/%d/%d %d/%d/%d %d/%d/%d/", 
+                &triangles[(ct + cur_faces) * ts + 0], &triangles[(ct + cur_faces) * ts + 3], &triangles[(ct + cur_faces) * ts + 6], 
+                &triangles[(ct + cur_faces) * ts + 1], &triangles[(ct + cur_faces) * ts + 4], &triangles[(ct + cur_faces) * ts + 7], 
+                &triangles[(ct + cur_faces) * ts + 2], &triangles[(ct + cur_faces) * ts + 5], &triangles[(ct + cur_faces) * ts + 8]);
+            
+            if (matches != 9){
+                triangles[(ct + cur_faces) * ts + 0] = -1;
+                triangles[(ct + cur_faces) * ts + 1] = -1;
+                triangles[(ct + cur_faces) * ts + 2] = -1;
+                
+                triangles[(ct + cur_faces) * ts + 3] = -1;
+                triangles[(ct + cur_faces) * ts + 4] = -1;
+                triangles[(ct + cur_faces) * ts + 5] = -1;
+                
+                triangles[(ct + cur_faces) * ts + 6] = -1;
+                triangles[(ct + cur_faces) * ts + 7] = -1;
+                triangles[(ct + cur_faces) * ts + 8] = -1;
+
+                if (matches == 6){
+                    sscanf(line, "f %d//%d %d//%d %d//%d", 
+                        &triangles[(ct + cur_faces) * ts + 0], &triangles[(ct + cur_faces) * ts + 6], 
+                        &triangles[(ct + cur_faces) * ts + 1], &triangles[(ct + cur_faces) * ts + 7], 
+                        &triangles[(ct + cur_faces) * ts + 2], &triangles[(ct + cur_faces) * ts + 8]);
+                }
+                else if (matches == 3){
+                    sscanf(line, "f %d %d %d", 
+                        &triangles[(ct + cur_faces) * ts + 0], 
+                        &triangles[(ct + cur_faces) * ts + 1], 
+                        &triangles[(ct + cur_faces) * ts + 2]);
+                }
+            }
+
+            ct++;
+        }
+        else if (line[0] == 'v' && line[1] == ' ') {
+            sscanf(line, "v %f %f %f", &verticies[(cv + cur_verticies) * vs + 0], &verticies[(cv + cur_verticies) * vs + 1], &verticies[(cv + cur_verticies) * vs + 2]);
+
+            cv++;
+        } 
+        else if (line[0] == 'v' && line[1] == 'n') {
+            cn++;
+        } 
+        else if (line[0] == 'v' && line[1] == 't') {
+            cu++;
+        } 
+    }
+
+    cur_faces += ct;
+    cur_verticies += cv;
+    cur_normals += cn;
+    cur_uvs += cu;
+
+    fclose(file);
+
+    load_object_return return_values = {
+        0, 0, 0, 0, 0
+    };
+
+    debug(1, "Done");
+
+    return return_values;
+}
+
+RI_result RI_RequestObjects(RI_newObject *RI_ObjectBuffer, int RI_ObjectsToRequest){
+    object_count = RI_ObjectsToRequest;
+    
+    debug(1, "Requesting %d Objects...", object_count);
+
+    if (objects != NULL)
+    {
+        free(objects);
+    }
+
+    int size = sizeof(int) * object_size * RI_ObjectsToRequest;
+
+    objects = malloc(size);
+    
+    if (objects == NULL){
+        debug(0, "Malloc Error");
+    }
+
+    char **file_names = malloc(RI_ObjectsToRequest * sizeof(char *));
+
+    for (int object = 0; object < object_count; object++){
+        file_names[object] = RI_ObjectBuffer[object].file_path;
+    }
+
+    malloc_objects(RI_ObjectsToRequest, file_names);
+    
+    free(file_names);
+
+    cur_verticies = 0;
+    cur_normals = 0;
+    cur_uvs = 0;
+    cur_faces = 0;
+
+    for (int object = 0; object < object_count; object++){
+        RI_newObject cur_object = RI_ObjectBuffer[object];
+        
+        load_object_return return_values = load_object((char *)cur_object.file_path, object);
+    }
+    
+    debug(0, "%d", sizeof(RI_verticies) * num_uvs * vs + sizeof(RI_triangles) * num_faces * vs + sizeof(RI_verticies) * num_verticies * vs + sizeof(RI_verticies) * num_normals * vs + size);
+
+    object_memory_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, size, objects, &error);
+    erchk(error);
+    
+    if (object_memory_buffer == NULL){
+        debug(0, "clCreateBuffer Failed for Objects Buffer");
+    }
+
+    triangles_memory_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(RI_triangles) * num_faces * ts, triangles, &error);
+    erchk(error);
+    
+    if (triangles_memory_buffer == NULL){
+        debug(0, "clCreateBuffer Failed for Triangles Buffer");
+    }
+
+    verticies_memory_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(RI_verticies) * num_verticies * vs, verticies, &error);
+    erchk(error);
+    
+    if (verticies_memory_buffer == NULL){
+        debug(0, "clCreateBuffer Failed for Verticies Buffer");
+    }
+    
+    normals_memory_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(RI_verticies) * num_normals * vs, normals, &error);
+    erchk(error);
+    
+    if (normals_memory_buffer == NULL){
+        debug(0, "clCreateBuffer Failed for Normals Buffer");
+    }
+    
+    uvs_memory_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(RI_verticies) * num_uvs * vs, uvs, &error);
+    erchk(error);
+
+    if (uvs_memory_buffer == NULL){
+        debug(0, "clCreateBuffer Failed for UVS Buffer");
+    }
+    
+    debug(1, "Request for %d Objects Granted", object_count);
+    
+    return objects;
+}
+
 RI_result RI_SetFpsCap(int RI_FpsCap){
     fps_cap = RI_FpsCap;
 
@@ -421,59 +541,62 @@ RI_result RI_Tick(){
     
     if (running)
     {
-        if (polygons == NULL)
-        {
-            debug(0, "Polygons is not Allocated");
-            return RI_ERROR;
-        }
-
         if (frame_buffer == NULL)
         {
             debug(0, "Frame Buffer is not Allocated");
             return RI_ERROR;
         }
-        
-        if (show_z_buffer){
-            for (int p = 2; p < polygon_count * 9; p+=3){
-                if (polygons[p] > highest_z){
-                    highest_z = polygons[p];
-                }
-            }
+
+        if (be_master_renderer){
             
-            debug(1, "Highest Z: %f", highest_z);
         }
+        else{
+            if (polygons == NULL)
+            {
+                debug(0, "Polygons is not Allocated");
+                return RI_ERROR;
+            }
+            
+            if (show_z_buffer){
+                for (int p = 2; p < polygon_count * 9; p+=3){
+                    if (polygons[p] > highest_z){
+                        highest_z = polygons[p];
+                    }
+                }
+                
+                debug(1, "Highest Z: %f", highest_z);
+            }
 
-        erchk(clSetKernelArg(compiled_kernel, 0, sizeof(cl_mem), &input_memory_buffer));
-        erchk(clSetKernelArg(compiled_kernel, 1, sizeof(cl_mem), &output_memory_buffer));
-        erchk(clSetKernelArg(compiled_kernel, 2, sizeof(int), (void*)&polygon_count));
-        erchk(clSetKernelArg(compiled_kernel, 3, sizeof(int), (void*)&width));
-        erchk(clSetKernelArg(compiled_kernel, 4, sizeof(int), (void*)&height));
-        erchk(clSetKernelArg(compiled_kernel, 5, sizeof(int), (void*)&show_z_buffer)); 
-        erchk(clSetKernelArg(compiled_kernel, 6, sizeof(float), (void*)&highest_z));
-
-        erchk(clEnqueueWriteBuffer(queue, input_memory_buffer, CL_TRUE, 0, sizeof(float) * 3 * 3 * polygon_count, polygons, 0, NULL, NULL));
-        erchk(clFinish(queue));
+            erchk(clSetKernelArg(compiled_kernel_non_master, 0, sizeof(cl_mem), &input_memory_buffer));
+            erchk(clSetKernelArg(compiled_kernel_non_master, 1, sizeof(cl_mem), &output_memory_buffer));
+            erchk(clSetKernelArg(compiled_kernel_non_master, 2, sizeof(int), (void*)&polygon_count));
+            erchk(clSetKernelArg(compiled_kernel_non_master, 3, sizeof(int), (void*)&width));
+            erchk(clSetKernelArg(compiled_kernel_non_master, 4, sizeof(int), (void*)&height));
+            erchk(clSetKernelArg(compiled_kernel_non_master, 5, sizeof(int), (void*)&show_z_buffer)); 
+            erchk(clSetKernelArg(compiled_kernel_non_master, 6, sizeof(float), (void*)&highest_z));
 
-        debug(1, "Wrote Polygon Buffer");
+            erchk(clEnqueueWriteBuffer(queue, input_memory_buffer, CL_TRUE, 0, sizeof(float) * 3 * 3 * polygon_count, polygons, 0, NULL, NULL));
+            erchk(clFinish(queue));
 
-        erchk(clEnqueueFillBuffer(queue, output_memory_buffer, &pattern, sizeof(RI_uint), 0, sizeof(RI_uint) * width * height, 0, NULL, NULL));
-        erchk(clFinish(queue));
+            debug(1, "Wrote Polygon Buffer");
 
-        debug(1, "Cleared Frame Buffer");
+            erchk(clEnqueueFillBuffer(queue, output_memory_buffer, &pattern, sizeof(RI_uint), 0, sizeof(RI_uint) * width * height, 0, NULL, NULL));
+            erchk(clFinish(queue));
 
-        size_t local_size_2d[2] = {sqrt(local_size), sqrt(local_size)};
+            debug(1, "Cleared Frame Buffer");
 
-        // for (int i = 0; i < passes; i++)
-        // {
-        erchk(clEnqueueNDRangeKernel(queue, compiled_kernel, 2, NULL, size_2d, local_size_2d, 0, NULL, NULL));
-        erchk(clFinish(queue));
+            size_t local_size_2d[2] = {sqrt(local_size), sqrt(local_size)};
 
-            // debug(1, "Ran Kernel (pass %d/%d)", i + 1, passes);
-        // }
+            // for (int i = 0; i < passes; i++)
+            // {
+            erchk(clEnqueueNDRangeKernel(queue, compiled_kernel_non_master, 2, NULL, size_2d, local_size_2d, 0, NULL, NULL));
+        
+            erchk(clFinish(queue));
 
-        erchk(clEnqueueReadBuffer(queue, output_memory_buffer, CL_TRUE, 0, sizeof(RI_uint) * width * height, frame_buffer, 0, NULL, NULL));
-        erchk(clFinish(queue));
-        debug(1, "Read Frame Buffer");
+            erchk(clEnqueueReadBuffer(queue, output_memory_buffer, CL_TRUE, 0, sizeof(RI_uint) * width * height, frame_buffer, 0, NULL, NULL));
+            erchk(clFinish(queue));
+            debug(1, "Read Frame Buffer");
+        }
 
         SDL_Event event;
         while (SDL_PollEvent(&event))
@@ -539,7 +662,7 @@ RI_result RI_Tick(){
     }
 }
 
-RI_result RI_Stop()
+RI_result RI_Stop(int quit)
 {
     debug(0, "Stopping...");
 
@@ -547,8 +670,15 @@ RI_result RI_Stop()
 
     clReleaseMemObject(input_memory_buffer);
     clReleaseMemObject(output_memory_buffer);
-    clReleaseKernel(compiled_kernel);
-    clReleaseProgram(kernel_program);
+    clReleaseMemObject(object_memory_buffer);
+    clReleaseMemObject(verticies_memory_buffer);
+    clReleaseMemObject(normals_memory_buffer);
+    clReleaseMemObject(uvs_memory_buffer);
+    clReleaseMemObject(triangles_memory_buffer);
+    clReleaseKernel(compiled_kernel_non_master);
+    clReleaseProgram(kernel_program_non_master);
+    clReleaseKernel(compiled_kernel_master);
+    clReleaseProgram(kernel_program_master);
     clReleaseCommandQueue(queue);
     clReleaseContext(context);
 
@@ -573,8 +703,32 @@ RI_result RI_Stop()
     else
         debug(0, "Frame-Buffer Was Unset on Stop");
 
+    if (objects != NULL)
+        free(objects);
+    else
+        debug(0, "Objects Was Unset on Stop");
+
+    if (verticies != NULL)
+        free(verticies);
+    else
+        debug(0, "Verticies Was Unset on Stop");
+
+    if (normals != NULL)
+        free(normals);
+    else
+        debug(0, "Normals Was Unset on Stop");
+
+    if (uvs != NULL)
+        free(uvs);
+    else
+        debug(0, "UVS Was Unset on Stop");
+
     debug(0, "Stopped");
 
+    if (quit){
+        exit(0);
+    }
+
     return RI_SUCCESS;
 }
 // ----- Renderer Action Functions
@@ -676,16 +830,26 @@ RI_result OpenCL_init(){
     output_memory_buffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(RI_uint) * width * height, NULL, &error);
     erchk(error);
 
-    kernel_program = clCreateProgramWithSource(context, 1, &kernel_source, NULL, &error);
+    kernel_program_non_master = clCreateProgramWithSource(context, 1, &kernel_source_non_master, NULL, &error);
+    erchk(error);
+
+    error = clBuildProgram(kernel_program_non_master, 1, &device, NULL, NULL, NULL);
+    erchk(error);
+
+    compiled_kernel_non_master = clCreateKernel(kernel_program_non_master, "raster_kernel", &error);
+    erchk(error);
+
+
+    kernel_program_master = clCreateProgramWithSource(context, 1, &kernel_source_master, NULL, &error);
     erchk(error);
 
-    error = clBuildProgram(kernel_program, 1, &device, NULL, NULL, NULL);
+    error = clBuildProgram(kernel_program_master, 1, &device, NULL, NULL, NULL);
     erchk(error);
 
-    compiled_kernel = clCreateKernel(kernel_program, "raster_kernel", &error);
+    compiled_kernel_master = clCreateKernel(kernel_program_master, "raster_kernel", &error);
     erchk(error);
 
-    erchk(clGetKernelWorkGroupInfo(compiled_kernel, device, CL_KERNEL_WORK_GROUP_SIZE, sizeof(local_size), &local_size, NULL));
+    erchk(clGetKernelWorkGroupInfo(compiled_kernel_master, device, CL_KERNEL_WORK_GROUP_SIZE, sizeof(local_size), &local_size, NULL));
 
     debug(1, "Local Size: %d", local_size);
 

+ 13 - 9
src/test programs/example.c → src/launch program/main.c

@@ -10,25 +10,29 @@ int main(){
     srand(time(NULL));                                                         
 
     RI_SetFlag(RI_FLAG_DEBUG, 1);
-    RI_SetFlag(RI_FLAG_DEBUG_VERBOSE, 0);
+    RI_SetFlag(RI_FLAG_DEBUG_VERBOSE, 1);
     RI_SetFlag(RI_FLAG_DEBUG_FPS, 0);
     RI_SetFlag(RI_FLAG_SHOW_FPS, 1);
     RI_SetFlag(RI_FLAG_SHOW_Z_BUFFER, 0);
     RI_SetFlag(RI_FLAG_CLEAN_POLYGONS, 1);
+    RI_SetFlag(RI_FLAG_POPULATE_POLYGONS, 0);
+    RI_SetFlag(RI_FLAG_BE_MASTER_RENDERER, 1);
     RI_SetFpsCap(120);
-    
+
     if (RI_Init(width, height, "Rasteriver Test") == RI_ERROR){
         return 1;
     }
 
-    RI_polygons polygons = RI_RequestPolygons(1);  
+    RI_newObject object_buffer[5] = {
+        {0, 0, 0, 0, 0, 0, 1, 1, 1, "obj_file.obj", "texture.png"},
+        {0, 0, 0, 0, 0, 0, 1, 1, 1, "obj_file.obj", "texture.png"},
+        {0, 0, 0, 0, 0, 0, 1, 1, 1, "obj_file.obj", "texture.png"},
+        {0, 0, 0, 0, 0, 0, 1, 1, 1, "obj_file.obj", "texture.png"},
+        {0, 0, 0, 0, 0, 0, 1, 1, 1, "obj_file.obj", "texture.png"},
+    };
+
+    RI_RequestObjects(object_buffer, 2);
 
-    for (int p = 0; p < 9; p += 3){ 
-        polygons[p] = rand() % width;
-        polygons[p + 1] = rand() % height;
-        polygons[p + 2] = rand() % ((width + height) / 2);
-    }
-    
     while (RI_IsRunning() == RI_RUNNING){
         RI_Tick();
     }

+ 72 - 0
testdisk.log

@@ -0,0 +1,72 @@
+
+
+Wed Apr 30 18:45:04 2025
+Command line: TestDisk
+
+TestDisk 7.1, Data Recovery Utility, July 2019
+Christophe GRENIER <grenier@cgsecurity.org>
+https://www.cgsecurity.org
+OS: Linux, kernel 6.1.0-33-amd64 (#1 SMP PREEMPT_DYNAMIC Debian 6.1.133-1 (2025-04-10)) x86_64
+Compiler: GCC 12.2
+ext2fs lib: 1.47.0, ntfs lib: libntfs-3g, reiserfs lib: none, ewf lib: none, curses lib: ncurses 6.3
+/dev/sdb: LBA, HPA, LBA48, DCO support
+/dev/sdb: size       3907029168 sectors
+/dev/sdb: user_max   3907029168 sectors
+/dev/sdb: native_max 3907029168 sectors
+/dev/sdd: LBA, HPA, LBA48, DCO support
+/dev/sdd: size       156301488 sectors
+/dev/sdd: user_max   156301488 sectors
+/dev/sdd: native_max 156301488 sectors
+/dev/sdd: dco        156301488 sectors
+Warning: can't get size for Disk /dev/mapper/control - 0 B - 0 sectors, sector size=512
+Warning: can't get size for Disk /dev/loop0 - 0 B - 0 sectors, sector size=512
+Warning: can't get size for Disk /dev/loop1 - 0 B - 0 sectors, sector size=512
+Warning: can't get size for Disk /dev/loop2 - 0 B - 0 sectors, sector size=512
+Warning: can't get size for Disk /dev/loop3 - 0 B - 0 sectors, sector size=512
+Warning: can't get size for Disk /dev/loop4 - 0 B - 0 sectors, sector size=512
+Warning: can't get size for Disk /dev/loop5 - 0 B - 0 sectors, sector size=512
+Warning: can't get size for Disk /dev/loop6 - 0 B - 0 sectors, sector size=512
+Warning: can't get size for Disk /dev/loop7 - 0 B - 0 sectors, sector size=512
+Hard disk list
+Disk /dev/sdb - 2000 GB / 1863 GiB - CHS 243201 255 63, sector size=512 - ST2000DM008-2UB102, S/N:ZFL6NT65, FW:0001
+Disk /dev/sdc - 1000 GB / 931 GiB - CHS 121601 255 63, sector size=512 - ASMT 2115
+Disk /dev/sdd - 80 GB / 74 GiB - CHS 9729 255 63, sector size=512 - TOSHIBA MK8051GSY, S/N:487JT0SST, FW:LD201D
+Disk /dev/nvme0n1 - 4000 GB / 3726 GiB - CHS 3815447 64 32, sector size=512
+Disk /dev/nvme1n1 - 2000 GB / 1863 GiB - CHS 1907729 64 32, sector size=512
+
+Partition table type defaults to Intel
+Disk /dev/sdd - 80 GB / 74 GiB - TOSHIBA MK8051GSY
+Partition table type: Intel
+
+Interface Advanced
+
+Analyse Disk /dev/sdd - 80 GB / 74 GiB - CHS 9729 255 63
+Current partition structure:
+
+Partition sector doesn't have the endmark 0xAA55
+
+search_part()
+Disk /dev/sdd - 80 GB / 74 GiB - CHS 9729 255 63
+
+Results
+
+interface_write()
+ 
+No partition found or selected for recovery
+
+search_part()
+Disk /dev/sdd - 80 GB / 74 GiB - CHS 9729 255 63
+Search for partition aborted
+
+Results
+
+interface_write()
+ 
+No partition found or selected for recovery
+simulate write!
+
+write_mbr_i386: starting...
+Store new MBR code
+write_all_log_i386: starting...
+No extended partition
+SIGINT detected! TestDisk has been killed.