Update project files and enhance rendering system
Added: - Updated `.gitignore` to ignore the `[Bb]uild/` directory. - Additional tasks added to the roadmap in `README.md` for light unit standardization and GPU backend support. Changed: - Removed line in `settings.json` that disabled error squiggles for C/C++ code. - Modified `Triangle.h` to include `material_id` in `triangle_t` and reorganized properties. - Reordered parameters in `triangle_collection_init` for clarity. - Updated `shading_context_t` in `Material.h` and added size parameter to `material_create`. - Streamlined initialization in `scene_init` and updated `scene_free` for proper resource management. - Updated `window_create` in `Window.h` to accept a `render_job_t` parameter. - Introduced `renderer_start` in `Renderer.c` to handle rendering jobs and optimized pixel rendering logic.
This commit is contained in:
331
source/main.c
331
source/main.c
@@ -3,8 +3,6 @@
|
||||
#include <svpng.inc>
|
||||
|
||||
#include "Algorithm/Sobol.h"
|
||||
#include "Debug.h"
|
||||
// #include "Geometry/GeometryUtilities.h"
|
||||
#include "Geometry/Mesh.h"
|
||||
#include "Lighting/SkyLight.h"
|
||||
#include "Material/SimpleLit.h"
|
||||
@@ -12,26 +10,169 @@
|
||||
#include "Rendering/Scene.h"
|
||||
#include "Window.h"
|
||||
|
||||
static void save_img(render_target_t* source, uint32_t width, uint32_t height, const char* filename)
|
||||
#define TITLE "Path Tracing"
|
||||
#define SPONZA_PATH "./assets/sponza.obj"
|
||||
|
||||
static bool scene_setup(scene_t* scene)
|
||||
{
|
||||
FILE* file_stream;
|
||||
fopen_s(&file_stream, filename, "wb");
|
||||
if (file_stream == NULL)
|
||||
if (!scene_init(scene, 67000, 8, 1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
scene->camera.position = (vec3s){-7.5f, 2.0f, 0.0f};
|
||||
scene->camera.rotation = euler_to_quat(10.0f, -90.0f, 0.0f);
|
||||
|
||||
// TODO: Standardize light unit
|
||||
light_entity_t sun = light_create_directional_light(&scene->lights);
|
||||
directional_light_t* sun_light = &scene->lights.directional_lights[sun.id];
|
||||
sun_light->direction = glms_vec3_normalize((vec3s){-0.5f, 1.0f, 0.15f});
|
||||
sun_light->color = (vec3s){1.0f, 0.93f, 0.87f};
|
||||
sun_light->intensity = 2.0f;
|
||||
sun_light->angular_diameter = 0.53f;
|
||||
|
||||
scene->lights.sky_light = sky_create_constant_sky(&(constant_sky_data_t)
|
||||
{
|
||||
.color = (vec3s){0.73f, 0.82f, 1.0f},
|
||||
.intensity = 1.0f,
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool load_assets(scene_t* scene)
|
||||
{
|
||||
simple_lit_data_t floor_lit_data =
|
||||
{
|
||||
.albedo = (vec3s){1.0f, 1.0f, 1.0f},
|
||||
.roughness = 0.95f,
|
||||
.metallic = 0.0f,
|
||||
};
|
||||
|
||||
material_entity_t floor_material = material_create_simple_lit(&floor_lit_data, &scene->materials);
|
||||
|
||||
mesh_load(SPONZA_PATH, floor_material.id, &scene->triangles, &scene->materials);
|
||||
|
||||
return scene_build_bvh(scene);
|
||||
}
|
||||
|
||||
static bool initialize_renderer(const rendering_config_t* config, render_job_t** outJob, render_target_t* outImg, scene_t* outScene)
|
||||
{
|
||||
if (!scene_setup(outScene))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!load_assets(outScene))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!scene_build_bvh(outScene))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!render_target_init(config->width, config->height, outImg))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
render_job_t* job = malloc(sizeof(render_job_t));
|
||||
if (job == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*job = (render_job_t){
|
||||
.scene = outScene,
|
||||
.render_target = outImg,
|
||||
.config = config,
|
||||
|
||||
.rendering_type = TILE_BASED,
|
||||
.rendering_flag = DEBUG_NONE,
|
||||
.is_done = false,
|
||||
};
|
||||
|
||||
sobol_init();
|
||||
|
||||
*outJob = job;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void shutdown_renderer(render_job_t* job, render_target_t* img, scene_t* scene)
|
||||
{
|
||||
if (job != NULL)
|
||||
{
|
||||
free(job);
|
||||
}
|
||||
|
||||
render_target_free(img);
|
||||
scene_free(scene);
|
||||
}
|
||||
|
||||
static void update_pixel_buffer(render_target_t* render_target)
|
||||
{
|
||||
if (render_target == NULL || render_target->buffer == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to open file for writing: %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char* img_buffer = render_target_to_char(source);
|
||||
svpng(file_stream, width, height, img_buffer, 1);
|
||||
for (uint32_t y = 0; y < render_target->height; y++)
|
||||
{
|
||||
for (uint32_t x = 0; x < render_target->width; x++)
|
||||
{
|
||||
vec4s pixel = render_target_get_pixel(render_target, x, y);
|
||||
pixel = gamma_correct(pixel, 2.2f);
|
||||
pixel = aces_tone_map(pixel);
|
||||
window_update_pixel(pixel, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file_stream);
|
||||
free(img_buffer);
|
||||
window_refresh_region(0, 0, render_target->width, render_target->height);
|
||||
}
|
||||
|
||||
static int run_main_loop(render_job_t* job, render_target_t* img)
|
||||
{
|
||||
MSG msg;
|
||||
bool running = true;
|
||||
|
||||
while (running)
|
||||
{
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
switch (msg.message)
|
||||
{
|
||||
case WM_QUIT:
|
||||
case WM_CLOSE:
|
||||
{
|
||||
running = false;
|
||||
job->is_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
if (!job->is_done && running)
|
||||
{
|
||||
update_pixel_buffer(img);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// int main()
|
||||
int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ PWSTR pCmdLine, _In_ int nCmdShow)
|
||||
{
|
||||
omp_set_num_threads(16);
|
||||
|
||||
scene_t scene;
|
||||
render_target_t img;
|
||||
render_job_t* job = NULL;
|
||||
|
||||
rendering_config_t config = {
|
||||
.width = 1920 / 4,
|
||||
.height = 1080 / 4,
|
||||
@@ -40,166 +181,22 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
|
||||
.bucket_size = 64,
|
||||
};
|
||||
|
||||
int result = window_create("Path Tracing", hInstance, config.width, config.height);
|
||||
if (result != 0)
|
||||
if (!initialize_renderer(&config, &job, &img, &scene))
|
||||
{
|
||||
fprintf(stderr, "Failed to create window\n");
|
||||
shutdown_renderer(job, &img, &scene);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!window_create(TITLE, hInstance, config.width, config.height, job))
|
||||
{
|
||||
shutdown_renderer(job, &img, &scene);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#pragma region SceneSetup
|
||||
omp_set_num_threads(16);
|
||||
sobol_init();
|
||||
int result = run_main_loop(job, &img);
|
||||
|
||||
scene_t scene;
|
||||
if (!scene_init(67000, 8, 1, &scene))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
window_close();
|
||||
shutdown_renderer(job, &img, &scene);
|
||||
|
||||
scene.camera.position = (vec3s){-7.5f, 2.0f, 0.0f};
|
||||
scene.camera.rotation = euler_to_quat(10.0f, -90.0f, 0.0f);
|
||||
|
||||
light_entity_t sun = light_create_directional_light(&scene.lights);
|
||||
directional_light_t* sun_light = &scene.lights.directional_lights[sun.id];
|
||||
sun_light->direction = glms_vec3_normalize((vec3s){-0.5f, 1.0f, 0.15f});
|
||||
sun_light->color = (vec3s){1.0f, 0.93f, 0.87f};
|
||||
sun_light->intensity = 2.0f;
|
||||
sun_light->angular_diameter = 0.53f;
|
||||
|
||||
scene.lights.sky_light = sky_create_constant_sky(&(constant_sky_data_t){
|
||||
.color = (vec3s){0.73f, 0.82f, 1.0f},
|
||||
.intensity = 1.0f,
|
||||
});
|
||||
|
||||
// simple_lit_data_t gray_lit_data =
|
||||
// {
|
||||
// .albedo = (vec3s){0.73f, 0.73f, 0.73f},
|
||||
// .roughness = 0.5f,
|
||||
// .metallic = 0.0f,
|
||||
// };
|
||||
// simple_lit_data_t blue_lit_data =
|
||||
// {
|
||||
// .albedo = (vec3s){0.0f, 0.0f, 1.0f},
|
||||
// .roughness = 0.5f,
|
||||
// .metallic = 0.0f,
|
||||
// };
|
||||
// simple_lit_data_t red_lit_data =
|
||||
// {
|
||||
// .albedo = (vec3s){1.0f, 0.0f, 0.0f},
|
||||
// .roughness = 0.5f,
|
||||
// .metallic = 0.0f,
|
||||
// };
|
||||
// simple_lit_data_t green_lit_data =
|
||||
// {
|
||||
// .albedo = (vec3s){0.0f, 1.0f, 0.0f},
|
||||
// .roughness = 0.5f,
|
||||
// .metallic = 0.0f,
|
||||
// };
|
||||
simple_lit_data_t floor_lit_data = {
|
||||
.albedo = (vec3s){1.0f, 1.0f, 1.0f},
|
||||
.roughness = 0.95f,
|
||||
.metallic = 0.0f,
|
||||
};
|
||||
// material_entity_t gray_material = material_create_simple_lit(&gray_lit_data, &scene.materials);
|
||||
// material_entity_t gray_light_material = material_create_simple_lit(&gray_lit_data, &scene.materials);
|
||||
// material_entity_t blue_material = material_create_simple_lit(&blue_lit_data, &scene.materials);
|
||||
// material_entity_t red_material = material_create_simple_lit(&red_lit_data, &scene.materials);
|
||||
// material_entity_t green_material = material_create_simple_lit(&green_lit_data, &scene.materials);
|
||||
material_entity_t floor_material = material_create_simple_lit(&floor_lit_data, &scene.materials);
|
||||
|
||||
// scene.materials.buffer[gray_light_material.id].emission = (vec3s){10.0f, 10.0f, 10.0f};
|
||||
|
||||
mesh_load("./assets/sponza.obj", floor_material.id, &scene.triangles, &scene.materials);
|
||||
|
||||
// quad_create(
|
||||
// (vec3s){0.0f, 3.95f, 0.0f},
|
||||
// (vec3s){0.0f, -1.0f, 0.0f},
|
||||
// (vec3s){0.0f, 0.0f, 1.0f},
|
||||
// 1.0f, gray_light_material.id, &scene.triangles
|
||||
// );
|
||||
// quad_create(
|
||||
// (vec3s){0.0f, 0.0f, 0.0f},
|
||||
// (vec3s){0.0f, 1.0f, 0.0f},
|
||||
// (vec3s){0.0f, 0.0f, 1.0f},
|
||||
// 4.0f, floor_material.id, &scene.triangles
|
||||
// );
|
||||
// quad_create(
|
||||
// (vec3s){0.0f, 4.0f, 0.0f},
|
||||
// (vec3s){0.0f, -1.0f, 0.0f},
|
||||
// (vec3s){0.0f, 0.0f, 1.0f},
|
||||
// 4.0f, gray_material.id, &scene.triangles
|
||||
// );
|
||||
// quad_create(
|
||||
// (vec3s){0.0f, 2.0f, -2.0f},
|
||||
// (vec3s){0.0f, 0.0f, 1.0f},
|
||||
// (vec3s){0.0f, 1.0f, 0.0f},
|
||||
// 4.0f, green_material.id, &scene.triangles
|
||||
// );
|
||||
// quad_create(
|
||||
// (vec3s){-2.0f, 2.0f, 0.0f},
|
||||
// (vec3s){1.0f, 0.0f, 0.0f},
|
||||
// (vec3s){0.0f, 1.0f, 0.0f},
|
||||
// 4.0f, blue_material.id, &scene.triangles
|
||||
// );
|
||||
// quad_create(
|
||||
// (vec3s){2.0f, 2.0f, 0.0f},
|
||||
// (vec3s){-1.0f, 0.0f, 0.0f},
|
||||
// (vec3s){0.0f, 1.0f, 0.0f},
|
||||
// 4.0f, red_material.id, &scene.triangles
|
||||
// );
|
||||
|
||||
#pragma endregion
|
||||
|
||||
render_target_t img;
|
||||
render_target_init(config.width, config.height, &img);
|
||||
|
||||
if (!scene_build_bvh(&scene))
|
||||
{
|
||||
fprintf(stderr, "Failed to build BVH\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
MSG msg;
|
||||
uint16_t tile_index = 0;
|
||||
tile_t current_tile = {0};
|
||||
rendering_context_t ctx = {0};
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (msg.message == WM_QUIT)
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
// TODO: This hurt performance a lot, need to be optimized
|
||||
if (scene_render_tile(&scene, &ctx, config, tile_index, DEBUG_NONE, &img, ¤t_tile))
|
||||
{
|
||||
for (uint32_t y = current_tile.y; y < current_tile.y + current_tile.height; y++)
|
||||
{
|
||||
for (uint32_t x = current_tile.x; x < current_tile.x + current_tile.width; x++)
|
||||
{
|
||||
vec4s pixel = render_target_get_pixel(&img, x, y);
|
||||
pixel = gamma_correct(pixel, 2.2f);
|
||||
pixel = aces_tone_map(pixel);
|
||||
window_update_pixels(pixel, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
window_refresh_region(current_tile.x, current_tile.y, current_tile.width, current_tile.height);
|
||||
tile_index++;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
render_target_free(&img);
|
||||
scene_free(&scene);
|
||||
|
||||
return 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user