| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167 |
- // rasteriver.c
- #include <CL/cl.h>
- #include <SDL2/SDL.h>
- #include "../headers/rasteriver.h"
- #include "../headers/memory.h"
- #include "../headers/pitmap.h"
- #include <time.h>
- cl_int clerror;
- cl_event clevent;
- RI_context context;
- #define RI_realloc(__ptr, __size) written_RI_realloc(__ptr, __size, __func__, __LINE__, context)
- #define RI_malloc(__size) written_RI_malloc(__size, __func__, __LINE__, context)
- #define RI_calloc(__nmemb, __size) written_RI_calloc(__nmemb, __size, __func__, __LINE__, context)
- #define RI_free(__ptr) written_RI_free(__ptr, __func__, __LINE__, context)
- #define PI 3.14159265359
- #define PI2 1.57079632679
- void debug(char *string, int debug_flag, ...){
- if (!(context.debug_flags & debug_flag))
- return;
- va_list args;
- va_start(args, debug_flag);
- char message[500];
- strcpy(message, context.debug_prefix);
- strcat(message, string);
- vprintf(message, args);
- printf("\n");
- va_end(args);
- }
- RI_texture* RI_load_image(char* filename){
- PM_image* image = PM_load_image(filename);
- RI_texture* texture = RI_malloc(sizeof(RI_texture));
- int previous_length_of_textures_array = context.opencl.length_of_textures_array;
- texture->width = image->width;
- texture->height = image->height;
- texture->index = previous_length_of_textures_array;
- context.opencl.length_of_textures_array += image->width * image->height;
- context.opencl.textures = RI_realloc(context.opencl.textures, context.opencl.length_of_textures_array * sizeof(uint32_t));
- printf("%d\n", previous_length_of_textures_array);
- memcpy(context.opencl.textures + previous_length_of_textures_array, image->frame_buffer, sizeof(uint32_t) * image->width * image->height);
- if (context.opencl.textures_mem_buffer) clReleaseMemObject(context.opencl.textures_mem_buffer);
- context.opencl.textures_mem_buffer = clCreateBuffer(
- context.opencl.context,
- CL_MEM_READ_WRITE,
- sizeof(uint32_t) * context.opencl.length_of_textures_array,
- NULL, NULL
- );
-
- clEnqueueWriteBuffer(
- context.opencl.queue,
- context.opencl.textures_mem_buffer,
- CL_TRUE,
- 0,
- sizeof(uint32_t) * context.opencl.length_of_textures_array,
- context.opencl.textures,
- 0, NULL, NULL
- );
-
- clFinish(context.opencl.queue);
- clSetKernelArg(
- context.opencl.rasterization_kernel,
- 1,
- sizeof(cl_mem),
- &context.opencl.textures_mem_buffer
- );
- free(image->frame_buffer);
- free(image);
- return texture;
- }
- RI_material *RI_new_material(){
- RI_material *new_material = RI_malloc(sizeof(RI_material));
- new_material->albedo = 0xFFFF00FF;
- return new_material;
- }
- RI_actor *RI_new_actor(){
- RI_actor *new_actor = RI_malloc(sizeof(RI_actor));
- if (context.defaults.default_actor){
- *new_actor = *context.defaults.default_actor;
- } else {
- new_actor->position = (RI_vector_3){0, 0, 0};
- new_actor->scale = (RI_vector_3){1, 1, 1};
- new_actor->rotation = (RI_vector_4){1, 0, 0, 0};
- new_actor->active = 1;
- }
- return new_actor;
- }
- RI_scene *RI_new_scene(){
- RI_scene *new_scene = RI_malloc(sizeof(RI_scene));
- new_scene->camera.FOV = PI2;
- new_scene->camera.max_clip = 100000;
- new_scene->camera.min_clip = 0.01;
- new_scene->camera.position = (RI_vector_3){0, 0, 0};
- new_scene->camera.rotation = (RI_vector_4){1, 0, 0, 0};
- return new_scene;
- }
- RI_mesh *RI_load_mesh(char *filename){
- clock_t start_time, end_time;
-
- start_time = clock();
- RI_mesh *new_mesh = RI_malloc(sizeof(RI_mesh));
- int previous_face_count = context.opencl.face_count;
- int previous_vertecies_count = context.opencl.vertex_count;
- int previous_normals_count = context.opencl.normal_count;
- int previous_uvs_count = context.opencl.uv_count;
- FILE *file = fopen(filename, "r");
- if (!file){
- debug("[Mesh Loader] Error! File \"%s\" not found", RI_DEBUG_MESH_LOADER_ERROR, filename);
- return NULL;
- }
-
- char line[512];
-
- int face_count = 0;
- int object_face_count = 0;
- int object_vertecies_count = 0;
- int object_normals_count = 0;
- int object_uvs_count = 0;
- while (fgets(line, sizeof(line), file)) {
- if (line[0] == 'f' && line[1] == ' ') { // face
- ++face_count;
- ++context.opencl.face_count;
- ++object_face_count;
- }
- else if (line[0] == 'v'){
- if (line[1] == ' ') { // vertex
- ++context.opencl.vertex_count;
- ++object_vertecies_count;
- }
- else if (line[1] == 'n') { // normal
- ++context.opencl.normal_count;
- ++object_normals_count;
- }
- else if (line[1] == 't') { // UV
- ++context.opencl.uv_count;
- ++object_uvs_count;
- }
- }
- }
- rewind(file);
- debug(
- "%d faces %d vertecies %d normals %d uvs",
- RI_DEBUG_MESH_LOADER_FACE_VERT_NORM_UV_COUNT,
- object_face_count,
- object_vertecies_count,
- object_normals_count,
- object_uvs_count
- );
- context.opencl.faces = RI_realloc(context.opencl.faces, sizeof(RI_face) * context.opencl.face_count);
- context.opencl.temp_faces = RI_malloc(sizeof(RI_face) * object_face_count);
- context.opencl.temp_vertecies = RI_malloc(sizeof(RI_vector_3) * object_vertecies_count);
- if (object_normals_count > 0) context.opencl.temp_normals = RI_malloc(
- sizeof(RI_vector_3) * object_normals_count
- );
- if (object_uvs_count > 0) context.opencl.temp_uvs = RI_malloc(sizeof(RI_vector_2) * object_uvs_count);
- 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);
- }
- }
- else {
- has_normals = has_uvs = 1;
- }
- context.opencl.temp_faces[current_face_index].position_0_index = vertex_0_index - 1;
- context.opencl.temp_faces[current_face_index].position_1_index = vertex_1_index - 1;
- context.opencl.temp_faces[current_face_index].position_2_index = vertex_2_index - 1;
- context.opencl.temp_faces[current_face_index].normal_0_index = normal_0_index - 1;
- context.opencl.temp_faces[current_face_index].normal_1_index = normal_1_index - 1;
- context.opencl.temp_faces[current_face_index].normal_2_index = normal_2_index - 1;
-
- context.opencl.temp_faces[current_face_index].uv_0_index = uv_0_index - 1;
- context.opencl.temp_faces[current_face_index].uv_1_index = uv_1_index - 1;
- context.opencl.temp_faces[current_face_index].uv_2_index = uv_2_index - 1;
- context.opencl.faces[current_face_index].should_render = 1;
- ++current_face_index;
- }
- else if (line[0] == 'v' && line[1] == ' ') {
- double x, y, z;
-
- sscanf(line, "v %lf %lf %lf", &x, &y, &z);
- context.opencl.temp_vertecies[current_vertex_index].x = x;
- context.opencl.temp_vertecies[current_vertex_index].y = y;
- context.opencl.temp_vertecies[current_vertex_index].z = z;
- ++current_vertex_index;
- }
- else if (line[0] == 'v' && line[1] == 'n') {
- double x, y, z;
-
- sscanf(line, "vn %lf %lf %lf", &x, &y, &z);
- context.opencl.temp_normals[current_normal_index].x = x;
- context.opencl.temp_normals[current_normal_index].y = y;
- context.opencl.temp_normals[current_normal_index].z = z;
- ++current_normal_index;
- }
- else if (line[0] == 'v' && line[1] == 't') {
- double x, y, z;
- sscanf(line, "vt %lf %lf %lf", &x, &y, &z);
- context.opencl.temp_uvs[current_uv_index].x = x;
- context.opencl.temp_uvs[current_uv_index].y = y;
- // UVS are almost always 2D so we don't need Z (the type itself is a vector 2f, not 3f)
- ++current_uv_index;
- }
- }
- for (int i = 0; i < object_face_count; ++i){
- context.opencl.faces[i + previous_face_count].position_0 = context.opencl.temp_vertecies[context.opencl.temp_faces[i].position_0_index];
- context.opencl.faces[i + previous_face_count].position_1 = context.opencl.temp_vertecies[context.opencl.temp_faces[i].position_1_index];
- context.opencl.faces[i + previous_face_count].position_2 = context.opencl.temp_vertecies[context.opencl.temp_faces[i].position_2_index];
- context.opencl.faces[i + previous_face_count].normal_0 = context.opencl.temp_normals[context.opencl.temp_faces[i].normal_0_index];
- context.opencl.faces[i + previous_face_count].normal_1 = context.opencl.temp_normals[context.opencl.temp_faces[i].normal_1_index];
- context.opencl.faces[i + previous_face_count].normal_2 = context.opencl.temp_normals[context.opencl.temp_faces[i].normal_2_index];
- context.opencl.faces[i + previous_face_count].uv_0 = context.opencl.temp_uvs[context.opencl.temp_faces[i].uv_0_index];
- context.opencl.faces[i + previous_face_count].uv_1 = context.opencl.temp_uvs[context.opencl.temp_faces[i].uv_1_index];
- context.opencl.faces[i + previous_face_count].uv_2 = context.opencl.temp_uvs[context.opencl.temp_faces[i].uv_2_index];
- }
- free(context.opencl.temp_faces);
- free(context.opencl.temp_vertecies);
- if (object_normals_count > 0) free(context.opencl.temp_normals);
- if (object_uvs_count > 0) free(context.opencl.temp_uvs);
- char* loading_mesh_notice_string;
- if (has_normals && !has_uvs) loading_mesh_notice_string = "normals";
- else if (!has_normals && has_uvs) loading_mesh_notice_string = "UVs";
- else if (!has_normals && !has_uvs) loading_mesh_notice_string = "normals and UVs";
-
- if (!has_normals || !has_uvs) debug(
- "[Mesh Loader] Notice! Mesh \"%s\" is missing %s",
- RI_DEBUG_MESH_LOADER_ERROR,
- filename,
- loading_mesh_notice_string
- );
-
- new_mesh->has_normals = has_normals;
- new_mesh->has_uvs = has_uvs;
- new_mesh->face_count = object_face_count;
- new_mesh->face_index = previous_face_count;
- debug(
- "[Mesh Loader] Loaded mesh \"%s\"! %d faces, %d verticies, %d normals, %d uvs",
- RI_DEBUG_MESH_LOADER_LOADED_MESH,
- filename,
- current_face_index,
- current_vertex_index,
- current_normal_index,
- current_uv_index
- );
- clFinish(context.opencl.queue);
- if (previous_face_count != context.opencl.face_count) {
- if (context.opencl.faces_mem_buffer) clReleaseMemObject(context.opencl.faces_mem_buffer);
- context.opencl.faces_mem_buffer = clCreateBuffer(
- context.opencl.context,
- CL_MEM_READ_WRITE,
- sizeof(RI_face) * context.opencl.face_count,
- NULL, NULL
- );
-
- clEnqueueWriteBuffer(
- context.opencl.queue,
- context.opencl.faces_mem_buffer,
- CL_TRUE,
- 0,
- sizeof(RI_face) * context.opencl.face_count,
- context.opencl.faces,
- 0, NULL, NULL
- );
- clFinish(context.opencl.queue);
- clSetKernelArg(
- context.opencl.transformation_kernel,
- 0,
- sizeof(cl_mem),
- &context.opencl.faces_mem_buffer
- );
-
- if (context.opencl.face_count * 2 > context.opencl.length_of_renderable_faces_array){
- debug(
- "old renderable faces count (%d) less than current (%d). Reallocating...",
- RI_DEBUG_MESH_LOADER_REALLOCATION,
- context.opencl.length_of_renderable_faces_array,
- context.opencl.face_count * 2
- );
- context.opencl.length_of_renderable_faces_array = context.opencl.face_count * 2;
-
- debug(
- "reallocating %f mb (%d renderable faces)",
- RI_DEBUG_MESH_LOADER_REALLOCATION,
- sizeof(RI_renderable_face) * context.opencl.length_of_renderable_faces_array / 1048576.0,
- context.opencl.length_of_renderable_faces_array
- );
- context.opencl.faces_to_render = RI_malloc(
- sizeof(RI_renderable_face) * context.opencl.length_of_renderable_faces_array
- );
- clerror = clReleaseMemObject(context.opencl.renderable_faces_mem_buffer);
- if (clerror != CL_SUCCESS){
- debug("couldn't free renderable faces memory buffer (error %d)",
- RI_DEBUG_MESH_LOADER_ERROR,
- clerror);
-
- exit(1);
- }
- context.opencl.renderable_faces_mem_buffer = clCreateBuffer(
- context.opencl.context,
- CL_MEM_READ_WRITE,
- sizeof(RI_renderable_face) * context.opencl.length_of_renderable_faces_array,
- NULL, &clerror
- );
-
- if (clerror != CL_SUCCESS){
- debug("couldn't reallocate renderable faces memory buffer (error %d)",
- RI_DEBUG_MESH_LOADER_ERROR,
- clerror);
- exit(1);
- }
- }
- }
- fclose(file);
-
- end_time = clock();
- debug("loading mesh took %lf seconds",
- RI_DEBUG_MESH_LOADER_TIME,
- (double)(end_time - start_time) / CLOCKS_PER_SEC);
- return new_mesh;
- }
- void RI_render(RI_scene *scene){
- clock_t start_time, end_time;
-
- start_time = clock();
-
- debug("---FRAME START-------------------------------------------\n",
- RI_DEBUG_FRAME_START_END_MARKERS
- );
- // transformer
-
- double horizontal_fov_factor = (double)context.window.width / tanf(0.5 * scene->camera.FOV);
- double vertical_fov_factor = (double)context.window.height / tanf(0.5 * scene->camera.FOV);
- if (context.window.aspect_mode == RI_ASPECT_MODE_LETTERBOX) horizontal_fov_factor /= horizontal_fov_factor / vertical_fov_factor;
- // kernel args
-
- // 18, double horizontal_fov_factor
- clSetKernelArg(context.opencl.transformation_kernel, 18, sizeof(double), &horizontal_fov_factor);
- // 19, double vertical_fov_factor
- clSetKernelArg(context.opencl.transformation_kernel, 19, sizeof(double), &vertical_fov_factor);
- // 20, double min_clip
- clSetKernelArg(context.opencl.transformation_kernel, 20, sizeof(float), &scene->camera.min_clip);
- // 21, double max_clip
- clSetKernelArg(context.opencl.transformation_kernel, 21, sizeof(float), &scene->camera.max_clip);
- // 22, double camera_x
- clSetKernelArg(context.opencl.transformation_kernel, 22, sizeof(double), &scene->camera.position.x);
- // 23, double camera_y
- clSetKernelArg(context.opencl.transformation_kernel, 23, sizeof(double), &scene->camera.position.y);
- // 24, double camera_z
- clSetKernelArg(context.opencl.transformation_kernel, 24, sizeof(double), &scene->camera.position.z);
- // 25, double camera_r_w
- clSetKernelArg(context.opencl.transformation_kernel, 25, sizeof(double), &scene->camera.rotation.w);
- // 26, double camera_r_x
- clSetKernelArg(context.opencl.transformation_kernel, 26, sizeof(double), &scene->camera.rotation.x);
- // 27, double camera_r_y
- clSetKernelArg(context.opencl.transformation_kernel, 27, sizeof(double), &scene->camera.rotation.y);
- // 28, double camera_r_z
- clSetKernelArg(context.opencl.transformation_kernel, 28, sizeof(double), &scene->camera.rotation.z);
- int local_group_size_x = 16;
- int local_group_size_y = 16;
- // count faces
- scene->face_count = 0;
- for (int actor_index = 0; actor_index < scene->length_of_actors_array; ++actor_index){
- scene->face_count += scene->actors[actor_index]->mesh->face_count;
- }
- // allocate faces_to_render if face count increases
- if (scene->face_count * 2 > context.opencl.length_of_renderable_faces_array){
- context.opencl.faces_to_render = RI_realloc(
- context.opencl.faces_to_render,
- sizeof(RI_renderable_face) * scene->face_count * 2
- ); // x2 because faces can be split
-
- context.opencl.length_of_renderable_faces_array = scene->face_count * 2;
- debug(
- "old renderable faces count (%d) less than current (%d). Reallocating %f mb",
- RI_DEBUG_RENDER_REALLOCATION,
- context.opencl.length_of_renderable_faces_array, scene->face_count * 2,
- sizeof(RI_renderable_face) * context.opencl.length_of_renderable_faces_array / 1048576.0
- );
- context.opencl.faces_to_render = RI_malloc(
- sizeof(RI_renderable_face) * context.opencl.length_of_renderable_faces_array
- );
- clerror = clReleaseMemObject(context.opencl.renderable_faces_mem_buffer);
- if (clerror != CL_SUCCESS){
- debug("couldn't free renderable faces memory buffer (error %d)",
- RI_DEBUG_RENDER_ERROR,
- clerror);
-
- exit(1);
- }
- context.opencl.renderable_faces_mem_buffer = clCreateBuffer(
- context.opencl.context,
- CL_MEM_READ_WRITE,
- sizeof(RI_renderable_face) * context.opencl.length_of_renderable_faces_array,
- NULL, &clerror
- );
- if (clerror != CL_SUCCESS){
- debug("couldn't reallocate renderable faces memory buffer (error %d)",
- RI_DEBUG_RENDER_ERROR,
- clerror);
- exit(1);
- }
- }
-
- // set faces_to_render to zero
- memset(context.opencl.faces_to_render, 0, sizeof(RI_renderable_face) * scene->face_count * 2);
- clSetKernelArg(
- context.opencl.transformation_kernel,
- 1,
- sizeof(cl_mem),
- &context.opencl.renderable_faces_mem_buffer
- );
- context.current_renderable_face_index = 0;
- context.current_split_renderable_face_index = 0;
- debug("transforming polygons...", RI_DEBUG_TRANSFORMER_MESSAGE);
- int renderable_face_index = 0;
- cl_ulong start, end;
- // transform polygons
- for (int actor_index = 0; actor_index < scene->length_of_actors_array; ++actor_index){
- RI_actor *actor = scene->actors[actor_index];
-
- debug("actor index: %d face count: %d",
- RI_DEBUG_TRANSFORMER_CURRENT_ACTOR,
- actor_index,
- actor->mesh->face_count
- );
- if (scene->actors[actor_index]->mesh->face_count <= 0) continue;
-
- int face_sqrt = ceil(sqrt(scene->actors[actor_index]->mesh->face_count));
- int local_t_size = (int)fmin(face_sqrt, local_group_size_x);
- const size_t t_global_work_size[2] = {
- local_t_size * ceil(face_sqrt / (float)local_t_size),
- local_t_size * ceil(face_sqrt / (float)local_t_size)
- };
- const size_t t_local_work_size[2] = {
- (int)fmin(face_sqrt, local_group_size_x),
- (int)fmin(face_sqrt, local_group_size_y)
- };
- debug("transformer global work size: {%d, %d}",
- RI_DEBUG_TRANSFORMER_GLOBAL_SIZE,
- t_global_work_size[0],
- t_global_work_size[1]
- );
- debug("transformer local work size: {%d, %d}",
- RI_DEBUG_TRANSFORMER_LOCAL_SIZE,
- t_local_work_size[0],
- t_local_work_size[1]
- );
- debug(
- "(%d extra work items; %d items (%dx%d) - %d faces)",
- RI_DEBUG_TRANSFORMER_EXTRA_WORK_ITEMS,
- t_global_work_size[0] * t_global_work_size[1] - scene->actors[actor_index]->mesh->face_count,
- t_global_work_size[0] * t_global_work_size[1],
- t_global_work_size[0],
- t_global_work_size[1],
- scene->actors[actor_index]->mesh->face_count
- );
- // 2, double actor_x
- clSetKernelArg(context.opencl.transformation_kernel, 2, sizeof(double), &actor->position.x);
- // 3, double actor_y
- clSetKernelArg(context.opencl.transformation_kernel, 3, sizeof(double), &actor->position.y);
- // 4, double actor_z
- clSetKernelArg(context.opencl.transformation_kernel, 4, sizeof(double), &actor->position.z);
- // 5, double actor_r_w
- clSetKernelArg(context.opencl.transformation_kernel, 5, sizeof(double), &actor->rotation.w);
- // 6, double actor_r_x
- clSetKernelArg(context.opencl.transformation_kernel, 6, sizeof(double), &actor->rotation.x);
- // 7, double actor_r_y
- clSetKernelArg(context.opencl.transformation_kernel, 7, sizeof(double), &actor->rotation.y);
- // 8, double actor_r_z
- clSetKernelArg(context.opencl.transformation_kernel, 8, sizeof(double), &actor->rotation.z);
- // 9, double actor_s_x
- clSetKernelArg(context.opencl.transformation_kernel, 9, sizeof(double), &actor->scale.x);
- // 10, double actor_s_y
- clSetKernelArg(context.opencl.transformation_kernel, 10, sizeof(double), &actor->scale.y);
- // 11, double actor_s_z
- clSetKernelArg(context.opencl.transformation_kernel, 11, sizeof(double), &actor->scale.z);
- // 12, int has_normals
- clSetKernelArg(context.opencl.transformation_kernel, 12, sizeof(int), &actor->mesh->has_normals);
- // 13, int has_uvs
- clSetKernelArg(context.opencl.transformation_kernel, 13, sizeof(int), &actor->mesh->has_uvs);
- // 14, int face_array_offset_index
- clSetKernelArg(context.opencl.transformation_kernel, 14, sizeof(int), &actor->mesh->face_index);
- // 15, int face_count
- clSetKernelArg(context.opencl.transformation_kernel, 15, sizeof(int), &actor->mesh->face_count);
- // 29, int renderable_face_offset
- clSetKernelArg(context.opencl.transformation_kernel, 29, sizeof(int), &renderable_face_index);
-
- // 30, int face_sqrt
- clSetKernelArg(context.opencl.transformation_kernel, 30, sizeof(int), &face_sqrt);
- debug("texture width: %d texture height: %d texture index %d", RI_DEBUG_TRANSFORMER_TEXTURE, actor->texture->width, actor->texture->height, actor->texture->index);
- // 31: uint16_t texture_width
- clSetKernelArg(context.opencl.transformation_kernel, 31, sizeof(uint16_t), &actor->texture->width);
- // 32: uint16_t texture_height
- clSetKernelArg(context.opencl.transformation_kernel, 32, sizeof(uint16_t), &actor->texture->height);
- // 33: uint32_t texture_index
- clSetKernelArg(context.opencl.transformation_kernel, 33, sizeof(uint32_t), &actor->texture->index);
- debug("running actor #%d's transformation kernel...",
- RI_DEBUG_TRANSFORMER_MESSAGE,
- actor_index
- );
- clerror = clEnqueueNDRangeKernel(
- context.opencl.queue,
- context.opencl.transformation_kernel,
- 2,
- NULL,
- t_global_work_size,
- t_local_work_size,
- 0, NULL, &clevent
- );
- if (clerror != CL_SUCCESS)
- debug("error enqueing kernel (%d)",
- RI_DEBUG_TRANSFORMER_ERROR,
- clerror
- );
-
- clFinish(context.opencl.queue);
- clGetEventProfilingInfo(clevent, CL_PROFILING_COMMAND_START, sizeof(start), &start, NULL);
- clGetEventProfilingInfo(clevent, CL_PROFILING_COMMAND_END, sizeof(end), &end, NULL);
- double ns = (double)(end - start);
- debug("actor #%d's transformation kernel took %f seconds\n",
- RI_DEBUG_TRANSFORMER_TIME,
- actor_index,
- ns / 1e9
- );
-
- renderable_face_index += actor->mesh->face_count * 2;
- }
- // rasterize
- // set width, height and kernel width, height
- int x = context.window.width;
- int y = context.window.height;
- int x_div_32 = ceil(context.window.width / (float)local_group_size_x);
- int y_div_32 = ceil(context.window.height / (float)local_group_size_y);
- if (context.window.width % local_group_size_x != 0)
- x = local_group_size_x * x_div_32;
- if (context.window.height % local_group_size_y != 0)
- y = local_group_size_y * y_div_32;
- const size_t r_global_work_size[2] = {x, y};
- const size_t r_local_work_size[2] = {local_group_size_x, local_group_size_y};
- debug("rasterizer global work size: {%d, %d}",
- RI_DEBUG_RASTERIZER_GLOBAL_SIZE,
- x,
- y
- );
- debug("rasterizer local work size: {%d, %d}",
- RI_DEBUG_RASTERIZER_GLOBAL_SIZE,
- local_group_size_x,
- local_group_size_y
- );
- // kernel args
- clSetKernelArg(
- context.opencl.rasterization_kernel,
- 0,
- sizeof(cl_mem),
- &context.opencl.renderable_faces_mem_buffer
- );
- clSetKernelArg(context.opencl.rasterization_kernel, 7, sizeof(int), &scene->face_count);
- clSetKernelArg(
- context.opencl.rasterization_kernel,
- 8,
- sizeof(int),
- &context.current_split_renderable_face_index
- );
- debug("rasterizing...", RI_DEBUG_RASTERIZER_MESSAGE);
- // run raster kernel
- clEnqueueNDRangeKernel(
- context.opencl.queue,
- context.opencl.rasterization_kernel,
- 2,
- NULL,
- r_global_work_size,
- r_local_work_size,
- 0, NULL, &clevent
- );
- clFinish(context.opencl.queue);
- clGetEventProfilingInfo(clevent, CL_PROFILING_COMMAND_START, sizeof(start), &start, NULL);
- clGetEventProfilingInfo(clevent, CL_PROFILING_COMMAND_END, sizeof(end), &end, NULL);
- debug("rasterization kernel took %f seconds\n",
- RI_DEBUG_RASTERIZER_TIME,
- (double)(end - start) / 1e9
- );
- // put GPU frame buffer into CPU
- clEnqueueReadBuffer(
- context.opencl.queue,
- context.opencl.frame_buffer_mem_buffer,
- CL_TRUE,
- 0,
- context.window.width * context.window.height * sizeof(uint32_t),
- context.sdl.frame_buffer,
- 0, NULL, &clevent
- );
- clFinish(context.opencl.queue);
- clGetEventProfilingInfo(clevent, CL_PROFILING_COMMAND_START, sizeof(start), &start, NULL);
- clGetEventProfilingInfo(clevent, CL_PROFILING_COMMAND_END, sizeof(end), &end, NULL);
- debug("reading GPU frame buffer took %f seconds",
- RI_DEBUG_RENDER_FRAME_BUFFER_READ_TIME,
- (double)(end - start) / 1e9
- );
- context.opencl.number_of_faces_just_rendered += scene->face_count;
- end_time = clock();
- debug("rendering took %lf seconds",
- RI_DEBUG_RENDER_TIME,
- (double)(end_time - start_time) / CLOCKS_PER_SEC
- );
- }
- void RI_tick(){
- clock_t start_time, end_time;
-
- start_time = clock();
-
- SDL_Event event;
- while (SDL_PollEvent(&event)){
- switch (event.type){
- case SDL_QUIT: {
- context.is_running = ri_false;
- break;
- }
- default: {
- break;
- }
- }
- }
- SDL_LockTexture(
- context.sdl.frame_buffer_texture,
- NULL,
- (void*)&context.sdl.frame_buffer,
- &context.sdl.pitch
- );
- SDL_UnlockTexture(context.sdl.frame_buffer_texture);
- SDL_RenderCopy(context.sdl.renderer, context.sdl.frame_buffer_texture, NULL, NULL);
- SDL_RenderPresent(context.sdl.renderer);
- ++context.current_frame;
- end_time = clock();
- debug("Done! ticking took %lf seconds",
- RI_DEBUG_TICK_TIME,
- (double)(end_time - start_time) / CLOCKS_PER_SEC
- );
- debug("---FRAME END---(frame #%d, %d polygons)----------------\n",
- RI_DEBUG_FRAME_START_END_MARKERS,
- context.current_frame,
- context.opencl.number_of_faces_just_rendered
- );
- context.opencl.number_of_faces_just_rendered = 0;
- return;
- }
- RI_context *RI_get_context(){
- context.sdl = (RI_SDL){NULL, NULL, NULL, NULL, -1};
- context.opencl = (RI_CL){NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 1, 0, 0};
- context.window = (RI_window){800, 800, 400, 400, "RasterIver Window", RI_ASPECT_MODE_LETTERBOX};
-
- context.debug_flags = RI_DEBUG_ERRORS;
- context.current_frame = 0;
- context.is_running = ri_true;
- context.debug_prefix = "[RasterIver] ";
- return &context;
- }
- // Convert a CL file to a string
- char *load_kernel_source(const char *filename) {
- FILE *f = fopen(filename, "rb");
- if (f == NULL){
- debug("couldn't open kernel file \"%s\"",
- RI_DEBUG_KERNEL_LOADER_ERROR,
- filename
- );
- }
- fseek(f, 0, SEEK_END);
- size_t size = ftell(f);
- rewind(f);
- char *source = malloc(size + 1);
- fread(source, 1, size, f);
- source[size] = '\0';
- fclose(f);
- return source;
- }
- int RI_init(){
- context.window.half_width = context.window.width / 2;
- context.window.half_height = context.window.height / 2;
-
- // init SDL
- context.sdl.window = SDL_CreateWindow(
- context.window.title,
- SDL_WINDOWPOS_CENTERED,
- SDL_WINDOWPOS_CENTERED,
- context.window.width,
- context.window.height, 0
- );
- context.sdl.renderer = SDL_CreateRenderer(context.sdl.window, -1, SDL_RENDERER_ACCELERATED);
- context.sdl.frame_buffer_texture = SDL_CreateTexture(
- context.sdl.renderer,
- SDL_PIXELFORMAT_BGRA8888,
- SDL_TEXTUREACCESS_STREAMING,
- context.window.width,
- context.window.height
- );
- context.sdl.frame_buffer = malloc(
- sizeof(uint32_t) * context.window.width * context.window.height
- );
-
- if (!context.debug_flags)
- context.debug_flags = RI_DEBUG_ERRORS;
- context.defaults.default_actor = RI_new_actor();
-
- // init OpenCL
-
- context.opencl.faces_to_render = RI_malloc(
- sizeof(RI_renderable_face) * context.opencl.length_of_renderable_faces_array
- );
- context.opencl.faces = RI_malloc(sizeof(RI_face) * context.opencl.face_count);
- cl_uint num_platforms = 0;
- clerror = clGetPlatformIDs(0, NULL, &num_platforms);
- cl_platform_id *platforms = malloc(sizeof(cl_platform_id) * num_platforms);
- clerror = clGetPlatformIDs(num_platforms, platforms, NULL);
- cl_device_id *devices;
-
- cl_platform_id chosen_platform = NULL;
- char pname[256];
- for (cl_uint i = 0; i < num_platforms; i++) {
- clerror = clGetPlatformInfo(platforms[i], CL_PLATFORM_NAME, sizeof(pname), pname, NULL);
- debug("get platform info result: %d", RI_DEBUG_INIT_PLATFORMS, clerror);
- cl_uint num_devices = 0;
- clerror = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
- debug("num devices result: %d", RI_DEBUG_INIT_PLATFORMS, clerror);
- devices = malloc(sizeof(cl_device_id) * num_devices);
- clerror = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, num_devices, devices, NULL);
- if (i == 0){
- context.opencl.device = devices[0];
- }
- debug("get device ids result: %d", RI_DEBUG_INIT_PLATFORMS, clerror);
- debug("-platform #%d: NAME: %s | DEVICE COUNT: %d", RI_DEBUG_INIT_PLATFORMS, i, pname, num_devices);
- for (cl_uint j = 0; j < num_devices; ++j){
- debug("-\\ device #%d: ID: %u", RI_DEBUG_INIT_PLATFORMS, j, devices[j]);
- }
- free(devices);
- }
- context.opencl.platform = platforms[0];
- debug("chosen device id: %u", RI_DEBUG_INIT_PLATFORMS, context.opencl.device);
- context.opencl.context = clCreateContext(NULL, 1, &context.opencl.device, NULL, NULL, NULL);
- context.opencl.queue = clCreateCommandQueueWithProperties(
- context.opencl.context,
- context.opencl.device,
- (const cl_queue_properties[]){CL_QUEUE_PROPERTIES, CL_QUEUE_PROFILING_ENABLE, 0},
- &clerror
- );
- if (!context.opencl.context){
- debug("failed to create OpenCL context", RI_DEBUG_OPENCL_ERROR);
-
- exit(1);
- }
- // build programs
- char *program_source = load_kernel_source("src/kernels/kernels.cl");
- cl_program rasterization_program = clCreateProgramWithSource(
- context.opencl.context,
- 1,
- (const char**)&program_source,
- NULL, NULL
- );
-
- free(program_source);
- cl_int result = clBuildProgram(rasterization_program, 1, &context.opencl.device, "", NULL, NULL);
- if (result != CL_SUCCESS){
- char log[10001];
- clGetProgramBuildInfo(
- rasterization_program,
- context.opencl.device,
- CL_PROGRAM_BUILD_LOG,
- 10000, log, NULL);
- debug("rasterization program build failed (%d). Log: \n %s", RI_DEBUG_OPENCL_ERROR, result, log);
-
- return 1;
- }
- // kernels
- context.opencl.rasterization_kernel = clCreateKernel(rasterization_program, "rasterizer", &clerror);
- if (clerror != CL_SUCCESS){
- debug("couldn't create rasterizer kernel", RI_DEBUG_OPENCL_ERROR);
- return 1;
- }
- context.opencl.transformation_kernel = clCreateKernel(rasterization_program, "transformer", &clerror);
- if (clerror != CL_SUCCESS){
- debug("couldn't create transformer kernel", RI_DEBUG_OPENCL_ERROR);
- return 1;
- }
- // rasterizer
- context.opencl.renderable_faces_mem_buffer = clCreateBuffer(
- context.opencl.context,
- CL_MEM_READ_WRITE,
- sizeof(RI_renderable_face) * context.opencl.length_of_renderable_faces_array,
- NULL, &clerror);
-
- if (clerror != CL_SUCCESS){
- debug("couldn't create renderable faces memory buffer", RI_DEBUG_OPENCL_ERROR);
- return 1;
- }
-
- context.opencl.frame_buffer_mem_buffer = clCreateBuffer(
- context.opencl.context,
- CL_MEM_READ_WRITE,
- sizeof(uint32_t) * context.window.width * context.window.height,
- NULL, &clerror);
- if (clerror != CL_SUCCESS || !context.opencl.frame_buffer_mem_buffer){
- debug("couldn't create frame buffer memory buffer", RI_DEBUG_OPENCL_ERROR);
- return 1;
- }
- context.opencl.textures_mem_buffer = clCreateBuffer(
- context.opencl.context,
- CL_MEM_READ_WRITE,
- 1,
- NULL, &clerror);
- if (clerror != CL_SUCCESS || !context.opencl.textures_mem_buffer){
- debug("couldn't create textures memory buffer", RI_DEBUG_OPENCL_ERROR);
- return 1;
- }
- // rasterizer(__global RI_renderable_face *renderable_faces, __global uint *frame_buffer,
- // int width, int height, int half_width, int half_height, int number_of_renderable_faces,
- // int number_of_split_renderable_faces)
- clSetKernelArg(context.opencl.rasterization_kernel, 0, sizeof(cl_mem), &context.opencl.renderable_faces_mem_buffer);
- clSetKernelArg(context.opencl.rasterization_kernel, 1, sizeof(cl_mem), &context.opencl.textures_mem_buffer);
- clSetKernelArg(context.opencl.rasterization_kernel, 2, sizeof(cl_mem), &context.opencl.frame_buffer_mem_buffer);
- clSetKernelArg(context.opencl.rasterization_kernel, 3, sizeof(int), &context.window.width);
- clSetKernelArg(context.opencl.rasterization_kernel, 4, sizeof(int), &context.window.height);
- clSetKernelArg(context.opencl.rasterization_kernel, 5, sizeof(int), &context.window.half_width);
- clSetKernelArg(context.opencl.rasterization_kernel, 6, sizeof(int), &context.window.half_height);
- clSetKernelArg(context.opencl.rasterization_kernel, 7, sizeof(int), &context.current_renderable_face_index);
- clSetKernelArg(context.opencl.rasterization_kernel, 8, sizeof(int), &context.current_split_renderable_face_index);
- // transformer
- // transformer
- // __global RI_face *faces, __global RI_vector_3 *vertecies,
- // __global RI_vector_3 *normals, __global RI_vector_2 *uvs,
- // __global RI_renderable_face *renderable_faces,
- // double actor_x, double actor_y, double actor_z,
- // double actor_r_w, double actor_r_x, double actor_r_y, double actor_r_z,
- // double actor_s_x, double actor_s_y, double actor_s_z,
- // int has_normals, int has_uvs, int face_array_offset_index, int face_count,
- // int width, int height, double horizontal_fov_factor, double vertical_fov_factor,
- // double min_clip, double max_clip,
- // double camera_x, double camera_y, double camera_z,
- // double camera_r_w, double camera_r_x, double camera_r_y, double camera_r_z
- // // 0: __global RI_face *faces
- // clSetKernelArg(context.opencl.transformation_kernel, 0, sizeof(cl_mem), &context.opencl.faces_mem_buffer);
- // // 1: __global RI_renderable_face *renderable_faces
- // clSetKernelArg(context.opencl.transformation_kernel, 1, sizeof(cl_mem), &context.opencl.renderable_faces_mem_buffer);
- // // 2: double actor_x
- // clSetKernelArg(context.opencl.transformation_kernel, 2, sizeof(double), &actor_x);
- // // 3: double actor_y
- // clSetKernelArg(context.opencl.transformation_kernel, 3, sizeof(double), &actor_y);
- // // 4: double actor_z
- // clSetKernelArg(context.opencl.transformation_kernel, 4, sizeof(double), &actor_z);
- // // 5: double actor_r_w
- // clSetKernelArg(context.opencl.transformation_kernel, 5, sizeof(double), &actor_r_w);
- // // 6: double actor_r_x
- // clSetKernelArg(context.opencl.transformation_kernel, 6, sizeof(double), &actor_r_x);
- // // 7: double actor_r_y
- // clSetKernelArg(context.opencl.transformation_kernel, 7, sizeof(double), &actor_r_y);
- // // 8: double actor_r_z
- // clSetKernelArg(context.opencl.transformation_kernel, 8, sizeof(double), &actor_r_z);
- // // 9: double actor_s_x
- // clSetKernelArg(context.opencl.transformation_kernel, 9, sizeof(double), &actor_s_x);
- // // 10: double actor_s_y
- // clSetKernelArg(context.opencl.transformation_kernel, 10, sizeof(double), &actor_s_y);
- // // 11: double actor_s_z
- // clSetKernelArg(context.opencl.transformation_kernel, 11, sizeof(double), &actor_s_z);
- // // 12: int has_normals
- // clSetKernelArg(context.opencl.transformation_kernel, 12, sizeof(int), &has_normals);
- // // 13: int has_uvs
- // clSetKernelArg(context.opencl.transformation_kernel, 13, sizeof(int), &has_uvs);
- // // 14: int face_array_offset_index
- // clSetKernelArg(context.opencl.transformation_kernel, 14, sizeof(int), &face_array_offset_index);
- // // 15: int face_count
- // clSetKernelArg(context.opencl.transformation_kernel, 15, sizeof(int), &face_count);
- // // 16: int width
- clSetKernelArg(context.opencl.transformation_kernel, 16, sizeof(int), &context.window.width);
- // // 17: int height
- clSetKernelArg(context.opencl.transformation_kernel, 17, sizeof(int), &context.window.height);
- // // 18: double horizontal_fov_factor
- // clSetKernelArg(context.opencl.transformation_kernel, 18, sizeof(double), &horizontal_fov_factor);
- // // 19: double vertical_fov_factor
- // clSetKernelArg(context.opencl.transformation_kernel, 19, sizeof(double), &vertical_fov_factor);
- // // 20: float min_clip
- // clSetKernelArg(context.opencl.transformation_kernel, 20, sizeof(float), &min_clip_f);
- // // 21: float max_clip
- // clSetKernelArg(context.opencl.transformation_kernel, 21, sizeof(float), &max_clip_f);
- // // 22: double camera_x
- // clSetKernelArg(context.opencl.transformation_kernel, 22, sizeof(double), &camera_x);
- // // 23: double camera_y
- // clSetKernelArg(context.opencl.transformation_kernel, 23, sizeof(double), &camera_y);
- // // 24: double camera_z
- // clSetKernelArg(context.opencl.transformation_kernel, 24, sizeof(double), &camera_z);
- // // 25: double camera_r_w
- // clSetKernelArg(context.opencl.transformation_kernel, 25, sizeof(double), &camera_r_w);
- // // 26: double camera_r_x
- // clSetKernelArg(context.opencl.transformation_kernel, 26, sizeof(double), &camera_r_x);
- // // 27: double camera_r_y
- // clSetKernelArg(context.opencl.transformation_kernel, 27, sizeof(double), &camera_r_y);
- // // 28: double camera_r_z
- // clSetKernelArg(context.opencl.transformation_kernel, 28, sizeof(double), &camera_r_z);
- // // 29: int renderable_face_offset
- // clSetKernelArg(context.opencl.transformation_kernel, 29, sizeof(int), &renderable_face_offset);
- // // 30: int face_sqrt
- // clSetKernelArg(context.opencl.transformation_kernel, 30, sizeof(int), &face_sqrt);
- // // 31: uint16_t texture_width
- // clSetKernelArg(context.opencl.transformation_kernel, 31, sizeof(uint16_t), &texture_width);
- // // 32: uint16_t texture_height
- // clSetKernelArg(context.opencl.transformation_kernel, 32, sizeof(uint16_t), &texture_height);
- // // 33: uint32_t texture_index
- // clSetKernelArg(context.opencl.transformation_kernel, 33, sizeof(uint32_t), &texture_index);
- context.defaults.default_actor->mesh = RI_load_mesh("objects/error_object.obj");
- return 0;
- }
|