rasteriver.c 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107
  1. #include <stdio.h>
  2. #include <CL/cl.h>
  3. #include <SDL2/SDL.h>
  4. #include "../headers/rasteriver.h"
  5. #define STB_IMAGE_IMPLEMENTATION
  6. #include "../headers/stb_image.h"
  7. #include "stdint.h"
  8. #include <math.h>
  9. RasterIver ri = {NULL};
  10. void debug(char *string, ...){
  11. va_list args;
  12. va_start(args, string);
  13. char message[500];
  14. strcpy(message, ri.prefix);
  15. strcat(message, string);
  16. vprintf(message, args);
  17. printf("\n");
  18. va_end(args);
  19. }
  20. RasterIver* RI_get_ri(){
  21. return &ri;
  22. }
  23. #define RI_realloc(__ptr, __size) written_RI_realloc(__ptr, __size, __func__, __LINE__)
  24. #define RI_malloc(__size) written_RI_malloc(__size, __func__, __LINE__)
  25. #define RI_calloc(__nmemb, __size) written_RI_calloc(__nmemb, __size, __func__, __LINE__)
  26. #define RI_free(__ptr) written_RI_free(__ptr, __func__, __LINE__)
  27. void* written_RI_realloc(void *__ptr, size_t __size, const char *caller, int line){
  28. void *pointer = realloc(__ptr, __size);
  29. if (ri.debug_memory) {
  30. int current_allocation_index = 0;
  31. int checking = 1;
  32. while (checking){
  33. if (!ri.allocation_table[current_allocation_index].reallocated_free && ri.allocation_table[current_allocation_index].pointer == __ptr){
  34. ri.allocation_table[current_allocation_index].reallocated_free = 1;
  35. checking = 0;
  36. }
  37. current_allocation_index++;
  38. if (current_allocation_index >= ri.allocation_search_limit){
  39. checking = 0;
  40. }
  41. }
  42. debug("[Memory Manager] Allocated (realloc) %zu bytes (func \"%s\":%d)", __size, caller, line);
  43. if (ri.current_allocation_index >= ri.allocation_table_length){
  44. ri.allocation_table_length += 50;
  45. ri.allocation_search_limit += 50;
  46. ri.allocation_table = RI_realloc(ri.allocation_table, sizeof(RI_memory_allocation) * ri.allocation_table_length);
  47. }
  48. ri.allocation_table[ri.current_allocation_index].allocated = 1;
  49. ri.allocation_table[ri.current_allocation_index].reallocated_alloc = 1;
  50. ri.allocation_table[ri.current_allocation_index].reallocated_free = 0;
  51. ri.allocation_table[ri.current_allocation_index].freed = 0;
  52. ri.allocation_table[ri.current_allocation_index].line = line;
  53. ri.allocation_table[ri.current_allocation_index].pointer = pointer;
  54. ri.allocation_table[ri.current_allocation_index].size = __size;
  55. ri.current_allocation_index++;
  56. }
  57. return pointer;
  58. }
  59. void* written_RI_malloc(size_t __size, const char *caller, int line){
  60. void *pointer = malloc(__size);
  61. if (ri.debug_memory) {
  62. debug("[Memory Manager] Allocated (malloc) %zu bytes (func \"%s\":%d)", __size, caller, line);
  63. if (ri.current_allocation_index >= ri.allocation_table_length){
  64. ri.allocation_table_length += 50;
  65. ri.allocation_search_limit += 50;
  66. ri.allocation_table = RI_realloc(ri.allocation_table, sizeof(RI_memory_allocation) * ri.allocation_table_length);
  67. }
  68. ri.allocation_table[ri.current_allocation_index].allocated = 1;
  69. ri.allocation_table[ri.current_allocation_index].reallocated_free = 0;
  70. ri.allocation_table[ri.current_allocation_index].reallocated_alloc = 0;
  71. ri.allocation_table[ri.current_allocation_index].freed = 0;
  72. ri.allocation_table[ri.current_allocation_index].line = line;
  73. ri.allocation_table[ri.current_allocation_index].pointer = pointer;
  74. ri.allocation_table[ri.current_allocation_index].size = __size;
  75. ri.current_allocation_index++;
  76. }
  77. return pointer;
  78. }
  79. void* written_RI_calloc(size_t __nmemb, size_t __size, const char *caller, int line){
  80. void *pointer = calloc(__nmemb, __size);
  81. if (ri.debug_memory) {
  82. debug("[Memory Manager] Allocated (calloc) %zu bytes (func \"%s\":%d)", __size * __nmemb, caller, line);
  83. if (ri.current_allocation_index >= ri.allocation_table_length){
  84. ri.allocation_table_length += 50;
  85. ri.allocation_search_limit += 50;
  86. ri.allocation_table = RI_realloc(ri.allocation_table, sizeof(RI_memory_allocation) * ri.allocation_table_length);
  87. }
  88. ri.allocation_table[ri.current_allocation_index].allocated = 1;
  89. ri.allocation_table[ri.current_allocation_index].reallocated_free = 0;
  90. ri.allocation_table[ri.current_allocation_index].reallocated_alloc = 0;
  91. ri.allocation_table[ri.current_allocation_index].freed = 0;
  92. ri.allocation_table[ri.current_allocation_index].line = line;
  93. ri.allocation_table[ri.current_allocation_index].pointer = pointer;
  94. ri.allocation_table[ri.current_allocation_index].size = __size * __nmemb;
  95. ri.current_allocation_index++;
  96. }
  97. return pointer;
  98. }
  99. void written_RI_free(void *__ptr, const char *caller, int line){
  100. if (ri.debug_memory) {
  101. size_t size = 0;
  102. int current_allocation_index = 0;
  103. int checking = 1;
  104. while (checking){
  105. if (!ri.allocation_table[current_allocation_index].reallocated_free && ri.allocation_table[current_allocation_index].pointer == __ptr){
  106. size = ri.allocation_table[current_allocation_index].size;
  107. ri.allocation_table[current_allocation_index].freed = 1;
  108. checking = 0;
  109. }
  110. current_allocation_index++;
  111. if (current_allocation_index >= ri.allocation_search_limit){
  112. checking = 0;
  113. }
  114. }
  115. debug("[Memory Manager] Freed %zu bytes (func \"%s\":%d)", size, caller, line);
  116. }
  117. free(__ptr);
  118. }
  119. int RI_add_actors_to_scene(int RI_number_of_actors_to_add_to_scene, RI_actor *actors, RI_scene *scene){
  120. int previous_actor_count = scene->actor_count;
  121. scene->actor_count += RI_number_of_actors_to_add_to_scene;
  122. scene->actors = RI_realloc(scene->actors, sizeof(RI_actor *) * scene->actor_count);
  123. for (int i = 0; i < RI_number_of_actors_to_add_to_scene; ++i){
  124. scene->actors[i + previous_actor_count] = &actors[i];
  125. }
  126. return 0;
  127. }
  128. RI_scene* RI_request_scenes(int RI_number_of_requested_scenes){
  129. int previous_scene_count = ri.scene_count;
  130. ri.scene_count += RI_number_of_requested_scenes;
  131. ri.scenes = RI_realloc(ri.scenes, sizeof(RI_scene) * ri.scene_count);
  132. for (int i = 0; i < RI_number_of_requested_scenes; ++i){
  133. RI_scene new_scene = {0};
  134. new_scene.actor_count = 0;
  135. new_scene.actors = NULL;
  136. new_scene.faces_to_render = NULL;
  137. ri.scenes[i + previous_scene_count] = new_scene;
  138. }
  139. return ri.scenes;
  140. }
  141. RI_actor* RI_request_actors(int RI_number_of_requested_actors){
  142. int previous_actor_count = ri.actor_count;
  143. ri.actor_count += RI_number_of_requested_actors;
  144. ri.actors = RI_realloc(ri.actors, sizeof(RI_actor) * ri.actor_count);
  145. for (int i = 0; i < RI_number_of_requested_actors; ++i){
  146. RI_actor new_actor = {0};
  147. new_actor.mesh_reference = NULL;
  148. new_actor.material_reference = NULL;
  149. ri.actors[i + previous_actor_count] = new_actor;
  150. }
  151. return ri.actors;
  152. }
  153. RI_material* RI_request_materials(int RI_number_of_requested_materials){
  154. ri.material_count += RI_number_of_requested_materials;
  155. ri.materials = RI_realloc(ri.materials, sizeof(RI_material) * ri.material_count);
  156. return ri.materials;
  157. }
  158. RI_texture* RI_request_textures(int RI_number_of_requested_textures, RI_texture_creation_data *texture_creation_data){
  159. int previous_loaded_texture_count = ri.loaded_texture_count;
  160. ri.loaded_texture_count += RI_number_of_requested_textures;
  161. ri.loaded_textures = RI_realloc(ri.loaded_textures, sizeof(RI_texture) * ri.loaded_texture_count);
  162. for (int i = 0; i < RI_number_of_requested_textures; i++){
  163. RI_texture new_texture = {0};
  164. char *current_texture_filename = texture_creation_data[i].filename;
  165. unsigned char* temp_texture = stbi_load(current_texture_filename, &new_texture.resolution.x, &new_texture.resolution.y, NULL, 4);
  166. if(stbi_failure_reason()){
  167. new_texture = ri.error_texture;
  168. }
  169. else {
  170. new_texture.image_buffer = RI_malloc(sizeof(uint32_t) * new_texture.resolution.x * new_texture.resolution.y);
  171. for (int i = 0; i < new_texture.resolution.x * new_texture.resolution.y; ++i){
  172. unsigned char r = temp_texture[i * 4];
  173. unsigned char g = temp_texture[i * 4 + 1];
  174. unsigned char b = temp_texture[i * 4 + 2];
  175. unsigned char a = temp_texture[i * 4 + 3];
  176. new_texture.image_buffer[i] = (a << 24 | r << 16 | g << 8 | b);
  177. }
  178. }
  179. ri.loaded_textures[previous_loaded_texture_count + i] = new_texture;
  180. stbi_image_free(temp_texture);
  181. }
  182. return ri.loaded_textures;
  183. }
  184. RI_mesh* RI_request_meshes(int RI_number_of_requested_meshes, char **filenames, int RI_return_just_mesh){
  185. int meshes_already_loaded_count = ri.loaded_mesh_count;
  186. RI_mesh* mesh;
  187. if (!RI_return_just_mesh) {
  188. ri.loaded_mesh_count += RI_number_of_requested_meshes;
  189. ri.loaded_meshes = RI_realloc(ri.loaded_meshes, sizeof(RI_mesh) * ri.loaded_mesh_count);
  190. }
  191. else {
  192. mesh = RI_malloc(sizeof(RI_mesh));
  193. }
  194. for (int i = 0; i < RI_number_of_requested_meshes; i++){
  195. RI_mesh new_mesh_data_struct = {0};
  196. FILE *file = fopen(filenames[i], "r");
  197. if (!file){
  198. debug("[Mesh Loader] Error! File \"%s\" not found", filenames[i]);
  199. RI_stop(1);
  200. }
  201. char line[512];
  202. while (fgets(line, sizeof(line), file)) {
  203. if (line[0] == 'f' && line[1] == ' ') { // face
  204. new_mesh_data_struct.face_count++;
  205. }
  206. else if (line[0] == 'v' && line[1] == ' ') { // vertex
  207. new_mesh_data_struct.vertex_count++;
  208. }
  209. else if (line[0] == 'v' && line[1] == 'n') { // normal
  210. new_mesh_data_struct.normal_count++;
  211. }
  212. else if (line[0] == 'v' && line[1] == 't') { // UV
  213. new_mesh_data_struct.uv_count++;
  214. }
  215. }
  216. fclose(file);
  217. new_mesh_data_struct.faces = RI_malloc(sizeof(RI_face) * new_mesh_data_struct.face_count);
  218. new_mesh_data_struct.vertex_positions = RI_malloc(sizeof(RI_vector_3f) * new_mesh_data_struct.vertex_count);
  219. new_mesh_data_struct.normals = RI_malloc(sizeof(RI_vector_3f) * new_mesh_data_struct.normal_count);
  220. new_mesh_data_struct.uvs = RI_malloc(sizeof(RI_vector_2f) * new_mesh_data_struct.uv_count);
  221. FILE *file_again = fopen(filenames[i], "r");
  222. int current_face_index = 0;
  223. int current_vertex_index = 0;
  224. int current_normal_index = 0;
  225. int current_uv_index = 0;
  226. int has_normals, has_uvs;
  227. has_normals = has_uvs = 0;
  228. while (fgets(line, sizeof(line), file_again)) {
  229. if (line[0] == 'f' && line[1] == ' ') {
  230. 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;
  231. int matches = sscanf(line, "f %d/%d/%d %d/%d/%d %d/%d/%d/",
  232. &vertex_0_index, &uv_0_index, &normal_0_index,
  233. &vertex_1_index, &uv_1_index, &normal_1_index,
  234. &vertex_2_index, &uv_2_index, &normal_2_index);
  235. if (matches != 9){
  236. vertex_0_index = -1;
  237. vertex_1_index = -1;
  238. vertex_2_index = -1;
  239. normal_0_index = -1;
  240. normal_1_index = -1;
  241. normal_2_index = -1;
  242. uv_0_index = -1;
  243. uv_1_index = -1;
  244. uv_2_index = -1;
  245. if (strchr(line, '/')){
  246. sscanf(line, "f %d//%d %d//%d %d//%d",
  247. &vertex_0_index, &normal_0_index,
  248. &vertex_1_index, &normal_1_index,
  249. &vertex_2_index, &normal_2_index);
  250. has_normals = 1;
  251. }
  252. else {
  253. sscanf(line, "f %d %d %d",
  254. &vertex_0_index,
  255. &vertex_1_index,
  256. &vertex_2_index);
  257. }
  258. }
  259. else {
  260. has_normals = has_uvs = 1;
  261. }
  262. new_mesh_data_struct.faces[current_face_index].position_0_index = vertex_0_index - 1;
  263. new_mesh_data_struct.faces[current_face_index].position_1_index = vertex_1_index - 1;
  264. new_mesh_data_struct.faces[current_face_index].position_2_index = vertex_2_index - 1;
  265. new_mesh_data_struct.faces[current_face_index].normal_0_index = normal_0_index - 1;
  266. new_mesh_data_struct.faces[current_face_index].normal_1_index = normal_1_index - 1;
  267. new_mesh_data_struct.faces[current_face_index].normal_2_index = normal_2_index - 1;
  268. new_mesh_data_struct.faces[current_face_index].uv_0_index = uv_0_index - 1;
  269. new_mesh_data_struct.faces[current_face_index].uv_1_index = uv_1_index - 1;
  270. new_mesh_data_struct.faces[current_face_index].uv_2_index = uv_2_index - 1;
  271. new_mesh_data_struct.faces[current_face_index].should_render = 1;
  272. ++current_face_index;
  273. }
  274. else if (line[0] == 'v' && line[1] == ' ') {
  275. double x, y, z;
  276. sscanf(line, "v %lf %lf %lf", &x, &y, &z);
  277. new_mesh_data_struct.vertex_positions[current_vertex_index].x = x;
  278. new_mesh_data_struct.vertex_positions[current_vertex_index].y = y;
  279. new_mesh_data_struct.vertex_positions[current_vertex_index].z = z;
  280. ++current_vertex_index;
  281. }
  282. else if (line[0] == 'v' && line[1] == 'n') {
  283. double x, y, z;
  284. sscanf(line, "vn %lf %lf %lf", &x, &y, &z);
  285. new_mesh_data_struct.normals[current_normal_index].x = x;
  286. new_mesh_data_struct.normals[current_normal_index].y = y;
  287. new_mesh_data_struct.normals[current_normal_index].z = z;
  288. ++current_normal_index;
  289. }
  290. else if (line[0] == 'v' && line[1] == 't') {
  291. double x, y, z;
  292. sscanf(line, "vt %lf %lf %lf", &x, &y, &z);
  293. new_mesh_data_struct.uvs[current_uv_index].x = x;
  294. new_mesh_data_struct.uvs[current_uv_index].y = y;
  295. // UVS are almost always 2D so we don't need Z (the type itself is a vector 2f, not 3f)
  296. ++current_uv_index;
  297. }
  298. }
  299. char* loading_mesh_notice_string;
  300. if (has_normals && !has_uvs) loading_mesh_notice_string = "normals";
  301. else if (!has_normals && has_uvs) loading_mesh_notice_string = "UVs";
  302. else if (!has_normals && !has_uvs) loading_mesh_notice_string = "normals and UVs";
  303. if (!has_normals || !has_uvs) debug("[Mesh Loader] Notice! Mesh \"%s\" is missing %s", filenames[i], loading_mesh_notice_string);
  304. new_mesh_data_struct.has_normals = has_normals;
  305. new_mesh_data_struct.has_uvs = has_uvs;
  306. // fclose(file_again);
  307. if (!RI_return_just_mesh) {
  308. ri.loaded_meshes[meshes_already_loaded_count + i] = new_mesh_data_struct;
  309. debug("[Mesh Loader] Loaded mesh \"%s\"! %d faces, %d verticies, %d normals, %d uvs", filenames[i], current_face_index, current_vertex_index, current_normal_index, current_uv_index);
  310. }
  311. else {
  312. *mesh = new_mesh_data_struct;
  313. }
  314. }
  315. if (!RI_return_just_mesh) return ri.loaded_meshes;
  316. else return mesh;
  317. }
  318. void quaternion_rotate(RI_vector_3f *position, RI_vector_4f rotation){
  319. RI_vector_4f pos_quat = {0, position->x, position->y, position->z};
  320. RI_vector_4f rotation_conjugation = rotation;
  321. quaternion_conjugate(&rotation_conjugation);
  322. quaternion_multiply(&rotation, pos_quat);
  323. quaternion_multiply(&rotation, rotation_conjugation);
  324. *position = (RI_vector_3f){rotation.x, rotation.y, rotation.z};
  325. }
  326. void RI_euler_rotation_to_quaternion(RI_vector_4f *quaternion, RI_vector_3f euler_rotation){
  327. double cx = cosf(euler_rotation.x * 0.5f);
  328. double sx = sinf(euler_rotation.x * 0.5f);
  329. double cy = cosf(euler_rotation.y * 0.5f);
  330. double sy = sinf(euler_rotation.y * 0.5f);
  331. double cz = cosf(euler_rotation.z * 0.5f);
  332. double sz = sinf(euler_rotation.z * 0.5f);
  333. quaternion->w = cx * cy * cz + sx * sy * sz;
  334. quaternion->x = sx * cy * cz - cx * sy * sz;
  335. quaternion->y = cx * sy * cz + sx * cy * sz;
  336. quaternion->z = cx * cy * sz - sx * sy * cz;
  337. }
  338. double mod(double a, double b){
  339. if(b < 0.0)
  340. return -mod(-a, -b);
  341. double ret = fmod(a, b);
  342. if(ret < 0.0)
  343. ret+=b;
  344. return ret;
  345. }
  346. int RI_render(RI_scene *scene, RI_texture *target_texture){
  347. // do rendering stuff
  348. if (ri.running){
  349. double horizontal_fov_factor = target_texture->resolution.x / tanf(0.5 * scene->FOV);
  350. double vertical_fov_factor = target_texture->resolution.y / tanf(0.5 * scene->FOV);
  351. scene->min_clip = scene->minimum_clip_distance;
  352. if (!scene->faces_to_render){
  353. int total_faces = 0;
  354. for (int actor_index = 0; actor_index < scene->actor_count; ++actor_index){
  355. total_faces += scene->actors[actor_index]->mesh_reference->face_count;
  356. }
  357. scene->faces_to_render = RI_malloc(sizeof(RI_renderable_face) * total_faces * 2); // x2 because faces can be split
  358. scene->face_count = total_faces;
  359. }
  360. memset(scene->faces_to_render, 0, sizeof(RI_renderable_face) * scene->face_count * 2);
  361. int current_renderable_face_index = 0;
  362. int current_split_renderable_face_index = 0;
  363. for (int actor_index = 0; actor_index < scene->actor_count; ++actor_index){
  364. RI_actor *current_actor = scene->actors[actor_index];
  365. for (int face_index = 0; face_index < current_actor->mesh_reference->face_count; ++face_index){
  366. RI_face *cur_face = &current_actor->mesh_reference->faces[face_index];
  367. if (!cur_face->should_render){
  368. continue;
  369. }
  370. int vert_pos_0_index = cur_face->position_0_index;
  371. int vert_pos_1_index = cur_face->position_1_index;
  372. int vert_pos_2_index = cur_face->position_2_index;
  373. int normal_0_index = cur_face->normal_0_index;
  374. int normal_1_index = cur_face->normal_1_index;
  375. int normal_2_index = cur_face->normal_2_index;
  376. int uv_0_index = cur_face->uv_0_index;
  377. int uv_1_index = cur_face->uv_1_index;
  378. int uv_2_index = cur_face->uv_2_index;
  379. RI_renderable_face *cur_r_face = &scene->faces_to_render[current_renderable_face_index];
  380. cur_r_face->material_reference = current_actor->material_reference;
  381. cur_r_face->position_0 = current_actor->mesh_reference->vertex_positions[vert_pos_0_index];
  382. cur_r_face->position_1 = current_actor->mesh_reference->vertex_positions[vert_pos_1_index];
  383. cur_r_face->position_2 = current_actor->mesh_reference->vertex_positions[vert_pos_2_index];
  384. if (current_actor->mesh_reference->has_uvs){
  385. cur_r_face->uv_0 = current_actor->mesh_reference->uvs[uv_0_index];
  386. cur_r_face->uv_1 = current_actor->mesh_reference->uvs[uv_1_index];
  387. cur_r_face->uv_2 = current_actor->mesh_reference->uvs[uv_2_index];
  388. }
  389. // scale
  390. vector_3f_hadamard(&cur_r_face->position_0, current_actor->transform.scale);
  391. vector_3f_hadamard(&cur_r_face->position_1, current_actor->transform.scale);
  392. vector_3f_hadamard(&cur_r_face->position_2, current_actor->transform.scale);
  393. // actor rotation
  394. quaternion_rotate(&cur_r_face->position_0, current_actor->transform.rotation);
  395. quaternion_rotate(&cur_r_face->position_1, current_actor->transform.rotation);
  396. quaternion_rotate(&cur_r_face->position_2, current_actor->transform.rotation);
  397. // object position
  398. vector_3f_element_wise_add(&cur_r_face->position_0, current_actor->transform.position);
  399. vector_3f_element_wise_add(&cur_r_face->position_1, current_actor->transform.position);
  400. vector_3f_element_wise_add(&cur_r_face->position_2, current_actor->transform.position);
  401. // camera rotation
  402. vector_3f_element_wise_subtract(&cur_r_face->position_0, scene->camera_position);
  403. vector_3f_element_wise_subtract(&cur_r_face->position_1, scene->camera_position);
  404. vector_3f_element_wise_subtract(&cur_r_face->position_2, scene->camera_position);
  405. quaternion_rotate(&cur_r_face->position_0, scene->camera_rotation);
  406. quaternion_rotate(&cur_r_face->position_1, scene->camera_rotation);
  407. quaternion_rotate(&cur_r_face->position_2, scene->camera_rotation);
  408. // camera position
  409. // vector_3f_element_wise_subtract(&cur_r_face->position_0, scene->camera_position);
  410. // vector_3f_element_wise_subtract(&cur_r_face->position_1, scene->camera_position);
  411. // vector_3f_element_wise_subtract(&cur_r_face->position_2, scene->camera_position);
  412. RI_vector_3f *pos_0 = &cur_r_face->position_0;
  413. RI_vector_3f *pos_1 = &cur_r_face->position_1;
  414. RI_vector_3f *pos_2 = &cur_r_face->position_2;
  415. int is_0_clipped = pos_0->z < scene->min_clip;
  416. int is_1_clipped = pos_1->z < scene->min_clip;
  417. int is_2_clipped = pos_2->z < scene->min_clip;
  418. int clip_count = is_0_clipped + is_1_clipped + is_2_clipped;
  419. cur_r_face->should_render = 1;
  420. switch(clip_count){
  421. case 3: // ignore polygon, it's behind the camera
  422. continue;
  423. break;
  424. case 2:{ // shrink poylgon
  425. RI_vector_3f *unclipped_point, *point_a, *point_b;
  426. RI_vector_3f *unclipped_normal, *normal_a, *normal_b;
  427. RI_vector_2f *unclipped_uv, *uv_a, *uv_b;
  428. if (!is_0_clipped){
  429. unclipped_point = &cur_r_face->position_0;
  430. point_a = &cur_r_face->position_1;
  431. point_b = &cur_r_face->position_2;
  432. unclipped_normal = &cur_r_face->normal_0;
  433. normal_a = &cur_r_face->normal_1;
  434. normal_b = &cur_r_face->normal_2;
  435. unclipped_uv = &cur_r_face->uv_0;
  436. uv_a = &cur_r_face->uv_1;
  437. uv_b = &cur_r_face->uv_2;
  438. }
  439. else if (!is_1_clipped){
  440. unclipped_point = &cur_r_face->position_1;
  441. point_a = &cur_r_face->position_2;
  442. point_b = &cur_r_face->position_0;
  443. unclipped_normal = &cur_r_face->normal_1;
  444. normal_a = &cur_r_face->normal_2;
  445. normal_b = &cur_r_face->normal_0;
  446. unclipped_uv = &cur_r_face->uv_1;
  447. uv_a = &cur_r_face->uv_2;
  448. uv_b = &cur_r_face->uv_0;
  449. }
  450. else if (!is_2_clipped){
  451. unclipped_point = &cur_r_face->position_2;
  452. point_a = &cur_r_face->position_0;
  453. point_b = &cur_r_face->position_1;
  454. unclipped_normal = &cur_r_face->normal_2;
  455. normal_a = &cur_r_face->normal_0;
  456. normal_b = &cur_r_face->normal_1;
  457. unclipped_uv = &cur_r_face->uv_2;
  458. uv_a = &cur_r_face->uv_0;
  459. uv_b = &cur_r_face->uv_1;
  460. }
  461. double fraction_a_to_unclip = (scene->min_clip - unclipped_point->z) / (point_a->z - unclipped_point->z);
  462. double fraction_b_to_unclip = (scene->min_clip - unclipped_point->z) / (point_b->z - unclipped_point->z);
  463. vector_3f_lerp(*unclipped_point, *point_a, point_a, fraction_a_to_unclip);
  464. vector_3f_lerp(*unclipped_point, *point_b, point_b, fraction_b_to_unclip);
  465. vector_3f_lerp(*unclipped_normal, *normal_a, normal_a, fraction_a_to_unclip);
  466. vector_3f_lerp(*unclipped_normal, *normal_b, normal_b, fraction_b_to_unclip);
  467. vector_2f_lerp(*unclipped_uv, *uv_a, uv_a, fraction_a_to_unclip);
  468. vector_2f_lerp(*unclipped_uv, *uv_b, uv_b, fraction_b_to_unclip);
  469. break;}
  470. case 1: // split polygon
  471. RI_vector_3f clipped_point, point_a, point_b;
  472. RI_vector_3f clipped_normal, normal_a, normal_b;
  473. RI_vector_2f clipped_uv, uv_a, uv_b;
  474. if (is_0_clipped){
  475. clipped_point = cur_r_face->position_0;
  476. point_a = cur_r_face->position_1;
  477. point_b = cur_r_face->position_2;
  478. clipped_normal = cur_r_face->normal_0;
  479. normal_a = cur_r_face->normal_1;
  480. normal_b = cur_r_face->normal_2;
  481. clipped_uv = cur_r_face->uv_0;
  482. uv_a = cur_r_face->uv_1;
  483. uv_b = cur_r_face->uv_2;
  484. }
  485. else if (is_1_clipped){
  486. clipped_point = cur_r_face->position_1;
  487. point_a = cur_r_face->position_2;
  488. point_b = cur_r_face->position_0;
  489. clipped_normal = cur_r_face->normal_1;
  490. normal_a = cur_r_face->normal_2;
  491. normal_b = cur_r_face->normal_0;
  492. clipped_uv = cur_r_face->uv_1;
  493. uv_a = cur_r_face->uv_2;
  494. uv_b = cur_r_face->uv_0;
  495. }
  496. else if (is_2_clipped){
  497. clipped_point = cur_r_face->position_2;
  498. point_a = cur_r_face->position_0;
  499. point_b = cur_r_face->position_1;
  500. clipped_normal = cur_r_face->normal_2;
  501. normal_a = cur_r_face->normal_0;
  502. normal_b = cur_r_face->normal_1;
  503. clipped_uv = cur_r_face->uv_2;
  504. uv_a = cur_r_face->uv_0;
  505. uv_b = cur_r_face->uv_1;
  506. }
  507. double fraction_a_to_clip = (scene->min_clip - clipped_point.z) / (point_a.z - clipped_point.z);
  508. double fraction_b_to_clip = (scene->min_clip - clipped_point.z) / (point_b.z - clipped_point.z);
  509. RI_vector_3f new_point_a, new_point_b; // the new points that move along the polygon's edge to match the z value of min_clip.
  510. RI_vector_3f new_normal_a, new_normal_b; // they come from the clipped point which was originally only 1
  511. RI_vector_2f new_uv_a, new_uv_b;
  512. vector_3f_lerp(clipped_point, point_a, &new_point_a, fraction_a_to_clip);
  513. vector_3f_lerp(clipped_point, point_b, &new_point_b, fraction_b_to_clip);
  514. vector_3f_lerp(clipped_normal, normal_a, &new_normal_a, fraction_a_to_clip);
  515. vector_3f_lerp(clipped_normal, normal_b, &new_normal_b, fraction_b_to_clip);
  516. vector_2f_lerp(clipped_uv, uv_a, &new_uv_a, fraction_a_to_clip);
  517. vector_2f_lerp(clipped_uv, uv_b, &new_uv_b, fraction_b_to_clip);
  518. // okay, now we have a quad (in clockwise order, point a, point b, new point b, new point a)
  519. // quads are easy to turn into tris >w<
  520. RI_renderable_face *cur_r_split_face = &scene->faces_to_render[scene->face_count + current_split_renderable_face_index];
  521. cur_r_split_face->should_render = 1;
  522. cur_r_split_face->material_reference = cur_r_face->material_reference;
  523. cur_r_face->position_0 = point_a;
  524. cur_r_face->position_1 = point_b;
  525. cur_r_face->position_2 = new_point_a;
  526. cur_r_face->normal_0 = normal_a;
  527. cur_r_face->normal_1 = normal_b;
  528. cur_r_face->normal_2 = new_normal_a;
  529. cur_r_face->uv_0 = uv_a;
  530. cur_r_face->uv_1 = uv_b;
  531. cur_r_face->uv_2 = new_uv_a;
  532. cur_r_split_face->position_0 = point_b;
  533. cur_r_split_face->position_1 = new_point_b;
  534. cur_r_split_face->position_2 = new_point_a;
  535. cur_r_split_face->normal_0 = normal_b;
  536. cur_r_split_face->normal_1 = new_normal_b;
  537. cur_r_split_face->normal_2 = new_normal_a;
  538. cur_r_split_face->uv_0 = uv_b;
  539. cur_r_split_face->uv_1 = new_uv_b;
  540. cur_r_split_face->uv_2 = new_uv_a;
  541. cur_r_split_face->position_0.x = cur_r_split_face->position_0.x / cur_r_split_face->position_0.z * horizontal_fov_factor;
  542. cur_r_split_face->position_0.y = cur_r_split_face->position_0.y / cur_r_split_face->position_0.z * vertical_fov_factor;
  543. cur_r_split_face->position_1.x = cur_r_split_face->position_1.x / cur_r_split_face->position_1.z * horizontal_fov_factor;
  544. cur_r_split_face->position_1.y = cur_r_split_face->position_1.y / cur_r_split_face->position_1.z * vertical_fov_factor;
  545. cur_r_split_face->position_2.x = cur_r_split_face->position_2.x / cur_r_split_face->position_2.z * horizontal_fov_factor;
  546. cur_r_split_face->position_2.y = cur_r_split_face->position_2.y / cur_r_split_face->position_2.z * vertical_fov_factor;
  547. cur_r_split_face->min_screen_x = cur_r_split_face->position_0.x;
  548. if (cur_r_split_face->position_1.x < cur_r_split_face->min_screen_x) cur_r_split_face->min_screen_x = cur_r_split_face->position_1.x;
  549. if (cur_r_split_face->position_2.x < cur_r_split_face->min_screen_x) cur_r_split_face->min_screen_x = cur_r_split_face->position_2.x;
  550. cur_r_split_face->min_screen_x = fmax(cur_r_split_face->min_screen_x, -target_texture->resolution.x / 2);
  551. cur_r_split_face->max_screen_x = cur_r_split_face->position_0.x;
  552. if (cur_r_split_face->position_1.x > cur_r_split_face->max_screen_x) cur_r_split_face->max_screen_x = cur_r_split_face->position_1.x;
  553. if (cur_r_split_face->position_2.x > cur_r_split_face->max_screen_x) cur_r_split_face->max_screen_x = cur_r_split_face->position_2.x;
  554. cur_r_split_face->max_screen_x = fmin(cur_r_split_face->max_screen_x, target_texture->resolution.x / 2);
  555. cur_r_split_face->min_screen_y = cur_r_split_face->position_0.y;
  556. if (cur_r_split_face->position_1.y < cur_r_split_face->min_screen_y) cur_r_split_face->min_screen_y = cur_r_split_face->position_1.y;
  557. if (cur_r_split_face->position_2.y < cur_r_split_face->min_screen_y) cur_r_split_face->min_screen_y = cur_r_split_face->position_2.y;
  558. cur_r_split_face->min_screen_y = fmax(cur_r_split_face->min_screen_y, -target_texture->resolution.y / 2);
  559. cur_r_split_face->max_screen_y = cur_r_split_face->position_0.y;
  560. if (cur_r_split_face->position_1.y > cur_r_split_face->max_screen_y) cur_r_split_face->max_screen_y = cur_r_split_face->position_1.y;
  561. if (cur_r_split_face->position_2.y > cur_r_split_face->max_screen_y) cur_r_split_face->max_screen_y = cur_r_split_face->position_2.y;
  562. cur_r_split_face->max_screen_y = fmin(cur_r_split_face->max_screen_y, target_texture->resolution.y / 2);
  563. ++current_split_renderable_face_index;
  564. break;
  565. case 0: // no issues, ignore
  566. break;
  567. }
  568. cur_r_face->position_0.x = cur_r_face->position_0.x / cur_r_face->position_0.z * horizontal_fov_factor;
  569. cur_r_face->position_0.y = cur_r_face->position_0.y / cur_r_face->position_0.z * vertical_fov_factor;
  570. cur_r_face->position_1.x = cur_r_face->position_1.x / cur_r_face->position_1.z * horizontal_fov_factor;
  571. cur_r_face->position_1.y = cur_r_face->position_1.y / cur_r_face->position_1.z * vertical_fov_factor;
  572. cur_r_face->position_2.x = cur_r_face->position_2.x / cur_r_face->position_2.z * horizontal_fov_factor;
  573. cur_r_face->position_2.y = cur_r_face->position_2.y / cur_r_face->position_2.z * vertical_fov_factor;
  574. cur_r_face->min_screen_x = pos_0->x;
  575. if (pos_1->x < cur_r_face->min_screen_x) cur_r_face->min_screen_x = pos_1->x;
  576. if (pos_2->x < cur_r_face->min_screen_x) cur_r_face->min_screen_x = pos_2->x;
  577. cur_r_face->min_screen_x = fmax(cur_r_face->min_screen_x, -target_texture->resolution.x / 2);
  578. cur_r_face->max_screen_x = pos_0->x;
  579. if (pos_1->x > cur_r_face->max_screen_x) cur_r_face->max_screen_x = pos_1->x;
  580. if (pos_2->x > cur_r_face->max_screen_x) cur_r_face->max_screen_x = pos_2->x;
  581. cur_r_face->max_screen_x = fmin(cur_r_face->max_screen_x, target_texture->resolution.x / 2);
  582. cur_r_face->min_screen_y = pos_0->y;
  583. if (pos_1->y < cur_r_face->min_screen_y) cur_r_face->min_screen_y = pos_1->y;
  584. if (pos_2->y < cur_r_face->min_screen_y) cur_r_face->min_screen_y = pos_2->y;
  585. cur_r_face->min_screen_y = fmax(cur_r_face->min_screen_y, -target_texture->resolution.y / 2);
  586. cur_r_face->max_screen_y = pos_0->y;
  587. if (pos_1->y > cur_r_face->max_screen_y) cur_r_face->max_screen_y = pos_1->y;
  588. if (pos_2->y > cur_r_face->max_screen_y) cur_r_face->max_screen_y = pos_2->y;
  589. cur_r_face->max_screen_y = fmin(cur_r_face->max_screen_y, target_texture->resolution.y / 2);
  590. ++current_renderable_face_index;
  591. }
  592. }
  593. if (ri.z_buffer_resolution.x * ri.z_buffer_resolution.y < target_texture->resolution.x * target_texture->resolution.y){
  594. ri.z_buffer = RI_realloc(ri.z_buffer, sizeof(double) * target_texture->resolution.x * target_texture->resolution.y);
  595. }
  596. for (int pixel_index = 0; pixel_index < target_texture->resolution.x * target_texture->resolution.y; ++pixel_index){
  597. target_texture->image_buffer[pixel_index] = 0xFF333333;
  598. ri.z_buffer[pixel_index] = 999999999;
  599. }
  600. for (int face_index = 0; face_index < current_renderable_face_index * 2; ++face_index){
  601. RI_renderable_face *current_face = &scene->faces_to_render[face_index];
  602. if (!current_face->should_render) continue;
  603. RI_material *mat = current_face->material_reference;
  604. RI_vector_2f *uv_0 = &current_face->uv_0;;
  605. RI_vector_2f *uv_1 = &current_face->uv_1;;
  606. RI_vector_2f *uv_2 = &current_face->uv_2;;
  607. if (mat == NULL){
  608. mat = &ri.error_material;
  609. }
  610. if(mat->flags & RI_MATERIAL_HAS_TEXTURE && mat->texture_reference == NULL){
  611. mat->texture_reference = &ri.error_texture;
  612. }
  613. if(mat->flags & RI_MATERIAL_HAS_BUMP_MAP && mat->bump_map_reference == NULL){
  614. mat->bump_map_reference = &ri.error_bump_map;
  615. }
  616. if(mat->flags & RI_MATERIAL_HAS_NORMAL_MAP && mat->normal_map_reference == NULL){
  617. mat->normal_map_reference = &ri.error_normal_map;
  618. }
  619. RI_vector_3f *pos_0 = &current_face->position_0;
  620. RI_vector_3f *pos_1 = &current_face->position_1;
  621. RI_vector_3f *pos_2 = &current_face->position_2;
  622. for (int pixel_y_index = current_face->min_screen_y; pixel_y_index < current_face->max_screen_y; ++pixel_y_index){
  623. for (int pixel_x_index = current_face->min_screen_x; pixel_x_index < current_face->max_screen_x; ++pixel_x_index){
  624. int x = pixel_x_index + target_texture->resolution.x / 2;
  625. int y = pixel_y_index + target_texture->resolution.y / 2;
  626. if (x < 0 || x >= target_texture->resolution.x || y < 0 || y >= target_texture->resolution.y) continue;
  627. double denominator, w0, w1, w2;
  628. denominator = (pos_1->y - pos_2->y) * (pos_0->x - pos_2->x) + (pos_2->x - pos_1->x) * (pos_0->y - pos_2->y);
  629. w0 = ((pos_1->y - pos_2->y) * (pixel_x_index - pos_2->x) + (pos_2->x - pos_1->x) * (pixel_y_index - pos_2->y)) / denominator;
  630. w1 = ((pos_2->y - pos_0->y) * (pixel_x_index - pos_0->x) + (pos_0->x - pos_2->x) * (pixel_y_index - pos_0->y)) / denominator;
  631. w2 = 1.0 - w0 - w1;
  632. if (!(mat->flags & RI_MATERIAL_DOUBLE_SIDED) && denominator > 0){
  633. continue;
  634. }
  635. double w_over_z = (w0 / pos_0->z + w1 / pos_1->z + w2 / pos_2->z);
  636. double interpolated_z = 1.0 / w_over_z;
  637. if (!(w0 >= 0 && w1 >= 0 && w2 >= 0) || (mat->flags & RI_MATERIAL_WIREFRAME && (w0 >= mat->wireframe_width && w1 >= mat->wireframe_width && w2 >= mat->wireframe_width))){
  638. continue;
  639. }
  640. if (!(mat->flags & RI_MATERIAL_DONT_DEPTH_TEST) && interpolated_z >= ri.z_buffer[y * target_texture->resolution.x + x]){
  641. continue;
  642. }
  643. if (!(mat->flags & RI_MATERIAL_DONT_DEPTH_WRITE)){
  644. ri.z_buffer[y * target_texture->resolution.x + x] = interpolated_z;
  645. }
  646. uint32_t pixel_color = 0xFF000000;
  647. if (mat->flags & RI_MATERIAL_HAS_TEXTURE && uv_0 && uv_1 && uv_2){
  648. double ux = (w0 * (uv_0->x / pos_0->z) + w1 * (uv_1->x / pos_1->z) + w2 * (uv_2->x / pos_2->z)) / w_over_z;
  649. double uy = (w0 * (uv_0->y / pos_0->z) + w1 * (uv_1->y / pos_1->z) + w2 * (uv_2->y / pos_2->z)) / w_over_z;
  650. if (mat->flags & RI_MATERIAL_USE_UV_LOOP_MULTIPLIER){
  651. ux *= mat->uv_loop_multiplier.x;
  652. uy *= mat->uv_loop_multiplier.y;
  653. }
  654. if (mat->flags & RI_MATERIAL_USE_UV_RENDER_RESOLUTION){
  655. ux *= mat->texture_reference->resolution.x / mat->texture_render_size.x;
  656. uy *= mat->texture_reference->resolution.y / mat->texture_render_size.y;
  657. }
  658. ux = mod(ux, 1.0);
  659. uy = mod(-uy, 1.0);
  660. RI_vector_2 texel_position = {mat->texture_reference->resolution.x * ux, mat->texture_reference->resolution.y * uy};
  661. if (texel_position.y * mat->texture_reference->resolution.x + texel_position.x < 0 || texel_position.y * mat->texture_reference->resolution.x + texel_position.x >= mat->texture_reference->resolution.x * mat->texture_reference->resolution.y)
  662. pixel_color = 0xFFFF00FF;
  663. else
  664. pixel_color = mat->texture_reference->image_buffer[texel_position.y * mat->texture_reference->resolution.x + texel_position.x];
  665. }
  666. else { // must be only an albedo
  667. if (mat->albedo) pixel_color = mat->albedo;
  668. else pixel_color = 0xFFFF77FF;
  669. }
  670. // tri culling debug
  671. // if (face_index >= current_renderable_face_index) pixel_color = 0xFF7777FF;
  672. // if (face_index < scene->face_count) pixel_color = 0xFF77FF77;
  673. // flip the texture
  674. // x = target_texture->resolution.x - 1 - x;
  675. // y = target_texture->resolution.y - 1 - y;
  676. if (x >= 0 && y >= 0 && x < target_texture->resolution.x && y < target_texture->resolution.y){
  677. target_texture->image_buffer[y * target_texture->resolution.x + x] = pixel_color;
  678. }
  679. }
  680. }
  681. }
  682. }
  683. else{
  684. RI_stop(0);
  685. }
  686. return 0;
  687. }
  688. void RI_tick(){
  689. SDL_UpdateTexture(ri.texture, NULL, ri.frame_buffer->image_buffer, ri.window_width * sizeof(uint32_t));
  690. SDL_RenderClear(ri.renderer);
  691. SDL_RenderCopyEx(ri.renderer, ri.texture, NULL, NULL, 0, NULL, SDL_FLIP_VERTICAL);
  692. SDL_RenderPresent(ri.renderer);
  693. // handle SDL events
  694. while (SDL_PollEvent(&ri.event)){
  695. switch (ri.event.type){
  696. case SDL_QUIT:
  697. ri.running = 0;
  698. }
  699. }
  700. ++ri.frame;
  701. }
  702. int opencl_init(){
  703. return 0;
  704. }
  705. int sdl_init(int RI_window_width, int RI_window_height, char *RI_window_title){
  706. ri.window_width = RI_window_width;
  707. ri.window_height = RI_window_height;
  708. ri.window_title = RI_window_title;
  709. ri.frame_buffer = RI_malloc(sizeof(RI_texture));
  710. ri.frame_buffer->image_buffer = RI_malloc(sizeof(uint32_t) * ri.window_width * ri.window_height);
  711. ri.frame_buffer->resolution = (RI_vector_2){ri.window_width, ri.window_height};
  712. ri.z_buffer = RI_malloc(sizeof(double) * ri.window_width * ri.window_height);
  713. ri.z_buffer_resolution = (RI_vector_2){ri.window_width, ri.window_height};
  714. SDL_Init(SDL_INIT_VIDEO);
  715. ri.window = SDL_CreateWindow(RI_window_title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, ri.window_width, ri.window_height, SDL_WINDOW_OPENGL);
  716. ri.renderer = SDL_CreateRenderer(ri.window, -1, SDL_RENDERER_ACCELERATED);
  717. ri.texture = SDL_CreateTexture(ri.renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, ri.window_width, ri.window_height);
  718. return 0;
  719. }
  720. int RI_init(int RI_window_width, int RI_window_height, char *RI_window_title){
  721. ri.running = 1;
  722. ri.prefix = "[RasterIver] ";
  723. if (ri.debug_memory){
  724. ri.current_allocation_index = 0;
  725. ri.allocation_search_limit = 100;
  726. ri.allocation_table_length = 100;
  727. size_t __size = sizeof(RI_memory_allocation) * ri.allocation_table_length;
  728. ri.allocation_table = malloc(__size);
  729. debug("[Memory Manager] Allocated (malloc) %zu bytes", __size);
  730. ri.allocation_table[ri.current_allocation_index].allocated = 1;
  731. ri.allocation_table[ri.current_allocation_index].freed = 0;
  732. ri.allocation_table[ri.current_allocation_index].reallocated_alloc = 0;
  733. ri.allocation_table[ri.current_allocation_index].reallocated_free = 0;
  734. ri.allocation_table[ri.current_allocation_index].pointer = ri.allocation_table;
  735. ri.allocation_table[ri.current_allocation_index].size = __size;
  736. ri.current_allocation_index++;
  737. }
  738. opencl_init();
  739. sdl_init(RI_window_width, RI_window_height, RI_window_title);
  740. ri.loaded_mesh_count = 0;
  741. ri.loaded_texture_count = 0;
  742. ri.actor_count = 0;
  743. char **error_cube_file = RI_malloc(sizeof(char *));
  744. error_cube_file[0] = "objects/unit_cube.obj";
  745. RI_mesh* error_mesh = RI_request_meshes(1, error_cube_file, 1);
  746. ri.error_mesh = *error_mesh;
  747. RI_free(error_mesh);
  748. RI_free(error_cube_file);
  749. ri.error_texture.image_buffer = RI_malloc(sizeof(uint32_t));
  750. ri.error_texture.image_buffer[0] = 0xFFFF00FF;
  751. ri.error_texture.resolution = (RI_vector_2){1, 1};
  752. ri.error_material.texture_reference = &ri.error_texture;
  753. ri.error_material.albedo = 0xFF5522CC;
  754. ri.error_material.flags = RI_MATERIAL_UNLIT | RI_MATERIAL_DONT_DEPTH_TEST | RI_MATERIAL_DONT_RECEIVE_SHADOW | RI_MATERIAL_HAS_TEXTURE | RI_MATERIAL_DOUBLE_SIDED;
  755. return 0;
  756. }
  757. int RI_stop(int result){
  758. debug("[Notice] Stopping...");
  759. for (int scene_index = 0; scene_index < ri.scene_count; ++scene_index){
  760. RI_free(ri.scenes[scene_index].faces_to_render);
  761. RI_free(ri.scenes[scene_index].actors);
  762. }
  763. for (int mesh_index = 0; mesh_index < ri.loaded_mesh_count; ++mesh_index){
  764. RI_free(ri.loaded_meshes[mesh_index].faces);
  765. RI_free(ri.loaded_meshes[mesh_index].vertex_positions);
  766. RI_free(ri.loaded_meshes[mesh_index].normals);
  767. RI_free(ri.loaded_meshes[mesh_index].uvs);
  768. }
  769. for (int texture_index = 0; texture_index < ri.loaded_texture_count; ++texture_index){
  770. RI_free(ri.loaded_textures[texture_index].image_buffer);
  771. }
  772. RI_free(ri.loaded_meshes);
  773. RI_free(ri.loaded_textures);
  774. RI_free(ri.materials);
  775. RI_free(ri.actors);
  776. RI_free(ri.scenes);
  777. RI_free(ri.error_texture.image_buffer);
  778. RI_free(ri.frame_buffer->image_buffer);
  779. RI_free(ri.frame_buffer);
  780. RI_free(ri.z_buffer);
  781. RI_free(ri.error_mesh.faces);
  782. RI_free(ri.error_mesh.vertex_positions);
  783. RI_free(ri.error_mesh.normals);
  784. RI_free(ri.error_mesh.uvs);
  785. if (ri.debug_memory){
  786. size_t total_allocated = 0;
  787. size_t allocated = 0;
  788. size_t alloc_realloc = 0;
  789. size_t total_freed = 0;
  790. size_t freed = 0;
  791. size_t reallocated = 0;
  792. for (int i = 1; i < ri.allocation_table_length; ++i) {
  793. if (ri.allocation_table[i].allocated != 1) continue;
  794. else if (ri.allocation_table[i].freed)
  795. freed += ri.allocation_table[i].size;
  796. else debug("[Memory Manager] Memory allocated at line %d wasn't freed (%zu bytes)", ri.allocation_table[i].line, ri.allocation_table[i].size);
  797. if (!ri.allocation_table[i].reallocated_free && !ri.allocation_table[i].reallocated_alloc)
  798. allocated += ri.allocation_table[i].size;
  799. else if (ri.allocation_table[i].reallocated_alloc)
  800. alloc_realloc += ri.allocation_table[i].size;
  801. else if (ri.allocation_table[i].reallocated_free)
  802. reallocated += ri.allocation_table[i].size;
  803. }
  804. total_allocated = allocated + alloc_realloc;
  805. total_freed = freed + reallocated;
  806. debug("[Memory Manager] [Total Bytes Allocated] M(c)alloc & Realloc(): %zu -- M(c)alloc(): %zu -- Realloc(): %zu", total_allocated, allocated, alloc_realloc);
  807. debug("[Memory Manager] [Total Bytes Freed] Free() & Realloc(): %zu -- Free(): %zu -- Realloc(): %zu", total_freed, freed, reallocated);
  808. if (total_allocated != total_freed){
  809. debug("[Memory Manager] %zu bytes not freed", total_allocated - total_freed);
  810. }
  811. debug("[Memory Manager] Freeing allocation table...");
  812. RI_free(ri.allocation_table);
  813. }
  814. exit(result);
  815. return 0;
  816. }