Changed function signatures to remove const qualifiers
Changed several function signatures across multiple files to remove the `const` qualifier from parameters of type `vec3s` for improved flexibility. Changed `material_collection_create` to `material_collection_init` for better initialization handling. Changed `scene_create` to `scene_init` to return a boolean indicating success or failure. Changed `render_target_create` to `render_target_init` for consistent initialization practices. Changed `window_create` to remove `const` from its parameters for consistency. Changed `evaluate_bsdf_directional` and `evaluate_bsdf_const_sky` to remove `const` from their parameters. Changed `sample_bsdf_simple_lit` and `sample_bsdf_pdf_simple_lit` to remove `const` from the `normal` parameter. Changed `scene_render` to take a pointer to `render_target_t` instead of returning it directly. Updated `main.c` to reflect new initialization functions for better memory management.
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
|
||||
// TODO: Implement a faster methods like BVH, KD-Tree or uniform grid acceleration
|
||||
// TODO: Split the diffuse and specular into different Monte Carlo, so we can decide the sample count for each one
|
||||
vec3s path_trace(const scene_t* scene, const ray_t ray, const uint32_t sample_index, const int max_depth)
|
||||
vec3s path_trace(const scene_t* scene, ray_t ray, uint32_t sample_index, int max_depth)
|
||||
{
|
||||
const triangle_collection_t* triangles = &scene->triangles;
|
||||
const material_collection_t* materials = &scene->materials;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "algorithm/RayIntersection.h"
|
||||
|
||||
hit_result_t ray_intersect(const triangle_t triangle, const ray_t ray)
|
||||
hit_result_t ray_intersect( triangle_t triangle, ray_t ray)
|
||||
{
|
||||
hit_result_t result = {0};
|
||||
|
||||
@@ -80,7 +80,7 @@ hit_result_t ray_intersect(const triangle_t triangle, const ray_t ray)
|
||||
return result;
|
||||
}
|
||||
|
||||
hit_result_t ray_intersect_closest(const triangle_collection_t* triangles, const ray_t ray)
|
||||
hit_result_t ray_intersect_closest(const triangle_collection_t* triangles, ray_t ray)
|
||||
{
|
||||
hit_result_t closest_hit = {0};
|
||||
closest_hit.distance = FLT_MAX;
|
||||
@@ -98,7 +98,7 @@ hit_result_t ray_intersect_closest(const triangle_collection_t* triangles, const
|
||||
return closest_hit;
|
||||
}
|
||||
|
||||
hit_result_t ray_intersect_any(const triangle_collection_t* triangles, const ray_t ray)
|
||||
hit_result_t ray_intersect_any(const triangle_collection_t* triangles, ray_t ray)
|
||||
{
|
||||
for (uint64_t i = 0; i < triangles->count; i++)
|
||||
{
|
||||
|
||||
@@ -8,8 +8,7 @@ mesh_entity_t mesh_load(const char* filename, uint8_t material_id, triangle_coll
|
||||
{
|
||||
mesh_entity_t entity = {0};
|
||||
|
||||
const C_STRUCT aiScene* scene = NULL;
|
||||
scene = aiImportFile(filename,aiProcessPreset_TargetRealtime_MaxQuality);
|
||||
const C_STRUCT aiScene* scene = aiImportFile(filename,aiProcessPreset_TargetRealtime_MaxQuality);
|
||||
if (scene == NULL)
|
||||
{
|
||||
// fprintf(stderr, "Error loading mesh: %s\n", aiGetErrorString());
|
||||
@@ -18,7 +17,7 @@ mesh_entity_t mesh_load(const char* filename, uint8_t material_id, triangle_coll
|
||||
|
||||
for (uint32_t i = 0; i < scene->mNumMeshes; i++)
|
||||
{
|
||||
const struct aiMesh* mesh = scene->mMeshes[i];
|
||||
struct aiMesh* mesh = scene->mMeshes[i];
|
||||
|
||||
//TODO: Handle all mesh types, not just triangles
|
||||
if (mesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE)
|
||||
@@ -29,7 +28,7 @@ mesh_entity_t mesh_load(const char* filename, uint8_t material_id, triangle_coll
|
||||
|
||||
for (uint32_t j = 0; j < mesh->mNumFaces; j++)
|
||||
{
|
||||
const struct aiFace* face = &mesh->mFaces[j];
|
||||
struct aiFace* face = &mesh->mFaces[j];
|
||||
if (face->mNumIndices != 3)
|
||||
{
|
||||
// fprintf(stderr, "Face %llu in mesh %llu does not have 3 indices\n", j, i);
|
||||
|
||||
@@ -1,41 +1,5 @@
|
||||
#include "Geometry/Triangle.h"
|
||||
|
||||
triangle_collection_t triangle_collection_create(size_t size)
|
||||
{
|
||||
if (size > UINT64_MAX)
|
||||
{
|
||||
size = UINT64_MAX;
|
||||
}
|
||||
|
||||
triangle_collection_t collection = {0};
|
||||
collection.buffer = (triangle_t*)malloc(size * sizeof(triangle_t));
|
||||
collection.size = (uint64_t)size;
|
||||
return collection;
|
||||
}
|
||||
|
||||
void triangle_collection_resize(triangle_collection_t* collection, size_t size)
|
||||
{
|
||||
if (size > UINT64_MAX)
|
||||
{
|
||||
size = UINT64_MAX;
|
||||
}
|
||||
|
||||
triangle_t* temp = realloc(collection->buffer, size * sizeof(triangle_t));
|
||||
if (temp != NULL)
|
||||
{
|
||||
collection->buffer = temp;
|
||||
collection->size = (uint64_t)size;
|
||||
}
|
||||
}
|
||||
|
||||
void triangle_collection_free(triangle_collection_t* collection)
|
||||
{
|
||||
if (collection->buffer != NULL)
|
||||
{
|
||||
free(collection->buffer);
|
||||
collection->buffer = NULL;
|
||||
}
|
||||
}
|
||||
void triangle_create_with_normals(vec3s point1, vec3s point2, vec3s point3,
|
||||
vec3s normal1, vec3s normal2, vec3s normal3,
|
||||
uint8_t material_id, triangle_collection_t* collection)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "Algorithm/RayIntersection.h"
|
||||
#include "Algorithm/Sobol.h"
|
||||
|
||||
vec3s evaluate_bsdf_directional(const directional_light_t light, const light_shading_context_t* context, sobol_state_t* sobol_state)
|
||||
vec3s evaluate_bsdf_directional( directional_light_t light, const light_shading_context_t* context, sobol_state_t* sobol_state)
|
||||
{
|
||||
float angular_radius = glm_rad(light.angular_diameter / 2.0f);
|
||||
vec3s wi = random_cosine_direction_angular(light.direction, angular_radius, sobol_state);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
vec3s evaluate_bsdf_const_sky(const void* data, const light_shading_context_t* context, sobol_state_t* sobol_state)
|
||||
{
|
||||
const constant_sky_data_t sky_data = *(const constant_sky_data_t*)data;
|
||||
constant_sky_data_t sky_data = *(const constant_sky_data_t*)data;
|
||||
|
||||
if (context == NULL)
|
||||
{
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
#include "Algorithm/BSDF.h"
|
||||
#include <float.h>
|
||||
|
||||
static const float DIELECTRIC_REFLECTIVE_F0 = 0.04f; // Standard dielectric reflectivity coef at incident angle (= 4%)
|
||||
static const vec3s DIELECTRIC_REFLECTIVE = {0.04f, 0.04f, 0.04f}; // Standard dielectric reflectivity coef at incident angle (= 4%)
|
||||
static float DIELECTRIC_REFLECTIVE_F0 = 0.04f; // Standard dielectric reflectivity coef at incident angle (= 4%)
|
||||
static vec3s DIELECTRIC_REFLECTIVE = {0.04f, 0.04f, 0.04f}; // Standard dielectric reflectivity coef at incident angle (= 4%)
|
||||
|
||||
// Simple lit, but keep it unbiased as much as possible
|
||||
vec3s sample_bsdf_simple_lit(const void* data, const vec3s normal, const vec3s wo, sobol_state_t* sobol_state, float* pdf_out)
|
||||
vec3s sample_bsdf_simple_lit(const void* data, vec3s normal, vec3s wo, sobol_state_t* sobol_state, float* pdf_out)
|
||||
{
|
||||
const simple_lit_data_t shading_data = *(const simple_lit_data_t*)data;
|
||||
simple_lit_data_t shading_data = *(const simple_lit_data_t*)data;
|
||||
|
||||
//TODO: having a bsdf data struct to avoid recomputing the same thing in both sample and evaluate
|
||||
vec3s f0 = glms_vec3_lerp(DIELECTRIC_REFLECTIVE, shading_data.albedo, shading_data.metallic);
|
||||
@@ -83,7 +83,7 @@ vec3s sample_bsdf_simple_lit(const void* data, const vec3s normal, const vec3s w
|
||||
}
|
||||
|
||||
//TODO: Most of the calculation here is same as in sample_bsdf_simple_lit, we can optimize this by using a bsdf data struct to avoid recomputing the same thing in both sample and evaluate
|
||||
float sample_bsdf_pdf_simple_lit(const void* data, const vec3s normal, const vec3s wo, const vec3s wi)
|
||||
float sample_bsdf_pdf_simple_lit(const void* data, vec3s normal, vec3s wo, vec3s wi)
|
||||
{
|
||||
// If wi is below the horizon relative to the normal, PDF must be 0
|
||||
if (glms_vec3_dot(normal, wi) <= 0.0f) // Use <= to be safe
|
||||
@@ -91,7 +91,7 @@ float sample_bsdf_pdf_simple_lit(const void* data, const vec3s normal, const vec
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
const simple_lit_data_t shading_data = *(const simple_lit_data_t*)data;
|
||||
simple_lit_data_t shading_data = *(const simple_lit_data_t*)data;
|
||||
|
||||
// Again, we need bsdf data;
|
||||
vec3s f0 = glms_vec3_lerp(DIELECTRIC_REFLECTIVE, shading_data.albedo, shading_data.metallic);
|
||||
@@ -120,8 +120,8 @@ float sample_bsdf_pdf_simple_lit(const void* data, const vec3s normal, const vec
|
||||
|
||||
vec3s evaluate_bsdf_simple_lit(const shading_context_t* context, const void* data)
|
||||
{
|
||||
const simple_lit_data_t shading_data = *(const simple_lit_data_t*)data;
|
||||
const shading_context_t shading_context = *context;
|
||||
simple_lit_data_t shading_data = *(const simple_lit_data_t*)data;
|
||||
shading_context_t shading_context = *context;
|
||||
|
||||
vec3s h = glms_vec3_normalize(glms_vec3_add(shading_context.wi, shading_context.wo));
|
||||
float n_dot_l = fmaxf(FLT_EPSILON, glms_vec3_dot(shading_context.normal, shading_context.wi));
|
||||
|
||||
@@ -3,27 +3,33 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
render_target_t render_target_create(uint32_t width, uint32_t height)
|
||||
bool render_target_init(uint32_t width, uint32_t height, render_target_t* render_target)
|
||||
|
||||
{
|
||||
render_target_t target;
|
||||
target.width = width;
|
||||
target.height = height;
|
||||
*render_target = (render_target_t){0};
|
||||
render_target->width = width;
|
||||
render_target->height = height;
|
||||
|
||||
size_t size_of_pixel = sizeof(vec4s);
|
||||
size_t buffer_size = (size_t)width * height * size_of_pixel;
|
||||
target.buffer = (vec4s*)malloc(buffer_size);
|
||||
vec4s* buffer = (vec4s*)malloc(buffer_size);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(target.buffer, 0, buffer_size);
|
||||
memset(buffer, 0, buffer_size);
|
||||
|
||||
for (size_t i = 0; i < buffer_size / size_of_pixel; i++)
|
||||
{
|
||||
target.buffer[i].w = 1.0;
|
||||
buffer[i].w = 1.0;
|
||||
}
|
||||
|
||||
return target;
|
||||
render_target->buffer = buffer;
|
||||
return true;
|
||||
}
|
||||
|
||||
vec4s render_target_get_pixel(render_target_t* render_target, uint32_t x, uint32_t y)
|
||||
vec4s render_target_get_pixel(const render_target_t* render_target, uint32_t x, uint32_t y)
|
||||
{
|
||||
if (x < render_target->width && y < render_target->height)
|
||||
{
|
||||
@@ -47,6 +53,10 @@ unsigned char* render_target_to_char(render_target_t* render_target)
|
||||
{
|
||||
size_t buffer_size = (size_t)render_target->width * render_target->height * 4; // 4 bytes for RGBA
|
||||
unsigned char* char_buffer = (unsigned char*)malloc(buffer_size);
|
||||
if (char_buffer == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (uint32_t y = 0; y < render_target->height; y++)
|
||||
{
|
||||
|
||||
@@ -3,26 +3,7 @@
|
||||
#include "Rendering/Scene.h"
|
||||
#include "Algorithm/PathTracing.h"
|
||||
|
||||
scene_t scene_create(const uint64_t triangle_count, const uint8_t material_count, const uint32_t punctual_light_count)
|
||||
{
|
||||
scene_t scene = {0};
|
||||
|
||||
scene.triangles = triangle_collection_create(triangle_count);
|
||||
scene.materials = material_collection_create(material_count);
|
||||
scene.lights = light_collection_create(punctual_light_count, 16); // NOTE: We just fixed the max directional light count to 16.
|
||||
scene.camera = camera_create(
|
||||
(vec3s){0.0f, 0.0f, 5.0f},
|
||||
(vec3s){0.0f, 0.0f, -1.0f},
|
||||
(vec3s){0.0f, 1.0f, 0.0f},
|
||||
0.025f,
|
||||
0.036f,
|
||||
16.0f / 9.0f
|
||||
);
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
static inline void ensure_camera_aspect_ratio(camera_t* camera, const rendering_config_t config)
|
||||
static inline void ensure_camera_aspect_ratio(camera_t* camera, rendering_config_t config)
|
||||
{
|
||||
if (fabsf((float)config.width / config.height - camera->aspect_ratio) > FLT_EPSILON)
|
||||
{
|
||||
@@ -49,7 +30,7 @@ static inline vec2s compute_ndc(float x, float y, uint32_t width, uint32_t heigh
|
||||
};
|
||||
}
|
||||
|
||||
static void screne_render_pixel(scene_t* scene, const rendering_config_t config, const vec3s coord, const uint32_t x, const uint32_t y, vec4s* pixel_color)
|
||||
static void screne_render_pixel(scene_t* scene, rendering_config_t config, vec3s coord, uint32_t x, uint32_t y, vec4s* pixel_color)
|
||||
{
|
||||
vec4s accumulated_color = glms_vec4_zero();
|
||||
*pixel_color = accumulated_color;
|
||||
@@ -84,8 +65,8 @@ static void screne_render_pixel(scene_t* scene, const rendering_config_t config,
|
||||
*pixel_color = glms_vec4_scale(accumulated_color, 1.0f / (float)config.sample_count);
|
||||
}
|
||||
|
||||
bool scene_render_tile(scene_t* scene, rendering_context_t* ctx, render_target_t* render_target,
|
||||
const rendering_config_t config, const uint32_t tile_index, tile_t* tile_out)
|
||||
bool scene_render_tile(scene_t* scene, rendering_context_t* ctx, render_target_t* render_target,
|
||||
rendering_config_t config, uint32_t tile_index, tile_t* tile_out)
|
||||
{
|
||||
if (ctx->is_done)
|
||||
{
|
||||
@@ -140,12 +121,19 @@ bool scene_render_tile(scene_t* scene, rendering_context_t* ctx, render_target_t
|
||||
return true;
|
||||
}
|
||||
|
||||
render_target_t scene_render(scene_t* scene, const rendering_config_t config)
|
||||
bool scene_render(scene_t* scene, rendering_config_t config, render_target_t* render_target)
|
||||
{
|
||||
ensure_camera_aspect_ratio(&scene->camera, config);
|
||||
|
||||
// The actual float buffer inside the render target is on the heap, copy return shoudl be fine.
|
||||
render_target_t render_target = render_target_create(config.width, config.height);
|
||||
if (render_target->buffer != NULL)
|
||||
{
|
||||
render_target_free(render_target);
|
||||
}
|
||||
|
||||
if (render_target_init(config.width, config.height, render_target))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t tile_count_x = (config.width + config.bucket_size - 1) / config.bucket_size;
|
||||
uint32_t tile_count_y = (config.height + config.bucket_size - 1) / config.bucket_size;
|
||||
@@ -173,17 +161,10 @@ render_target_t scene_render(scene_t* scene, const rendering_config_t config)
|
||||
{
|
||||
vec4s pixel_color;
|
||||
screne_render_pixel(scene, config_copy, coord, (uint32_t)x, (uint32_t)y, &pixel_color);
|
||||
render_target_set_pixel(&render_target, (uint32_t)x, (uint32_t)y, pixel_color);
|
||||
render_target_set_pixel(render_target, (uint32_t)x, (uint32_t)y, pixel_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return render_target;
|
||||
}
|
||||
|
||||
void scene_free(scene_t* scene)
|
||||
{
|
||||
triangle_collection_free(&scene->triangles);
|
||||
material_collection_free(&scene->materials);
|
||||
light_collection_free(&scene->lights);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -14,8 +14,7 @@ static LRESULT CALLBACK wndow_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
|
||||
bitmap_info.bmiHeader.biBitCount = 32; // 32 bits per pixel (RGBA)
|
||||
bitmap_info.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
bitmap = CreateDIBSection(hdc, &bitmap_info, DIB_RGB_COLORS,
|
||||
(void**)&pixel_buffer, NULL, 0);
|
||||
bitmap = CreateDIBSection(hdc, &bitmap_info, DIB_RGB_COLORS, (void**)&pixel_buffer, NULL, 0);
|
||||
hdc_mem = CreateCompatibleDC(hdc);
|
||||
SelectObject(hdc_mem, bitmap);
|
||||
|
||||
@@ -49,7 +48,7 @@ static LRESULT CALLBACK wndow_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
|
||||
}
|
||||
}
|
||||
|
||||
int window_create(const char* title, HINSTANCE hInst, const int width, const int height)
|
||||
int window_create(const char* title, HINSTANCE hInst, int width, int height)
|
||||
{
|
||||
RECT rect = {0, 0, width, height};
|
||||
AdjustWindowRect(&rect, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, FALSE);
|
||||
@@ -71,9 +70,8 @@ int window_create(const char* title, HINSTANCE hInst, const int width, const int
|
||||
int pos_x = (screen_width - window_width) / 2;
|
||||
int pos_y = (screen_height - window_height) / 2;
|
||||
|
||||
hwnd = CreateWindowEx(0, title, title, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE,
|
||||
pos_x, pos_y, window_width, window_height,
|
||||
NULL, NULL, wc.hInstance, NULL);
|
||||
hwnd = CreateWindowEx(0, title, title, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, pos_x, pos_y,
|
||||
window_width, window_height, NULL, NULL, wc.hInstance, NULL);
|
||||
|
||||
if (!hwnd)
|
||||
{
|
||||
@@ -85,7 +83,7 @@ int window_create(const char* title, HINSTANCE hInst, const int width, const int
|
||||
return 0;
|
||||
}
|
||||
|
||||
void window_update_pixels(const vec4s color, const int pixel_x, const int pixel_y)
|
||||
void window_update_pixels(vec4s color, int pixel_x, int pixel_y)
|
||||
{
|
||||
int pixel_index = (pixel_y * window_width + pixel_x) * 4;
|
||||
|
||||
@@ -96,7 +94,7 @@ void window_update_pixels(const vec4s color, const int pixel_x, const int pixel_
|
||||
pixel_buffer[pixel_index + 3] = COLOR_CLAMP(color.w * 255.0f);
|
||||
}
|
||||
|
||||
void window_refresh_region(const int pixel_x, const int pixel_y, const int region_width, const int region_height)
|
||||
void window_refresh_region(int pixel_x, int pixel_y, int region_width, int region_height)
|
||||
{
|
||||
HDC hdc = GetDC(hwnd);
|
||||
BitBlt(hdc, pixel_x, pixel_y, region_width, region_height, hdc_mem, pixel_x, pixel_y, SRCCOPY);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "Geometry/GeometryUtilities.h"
|
||||
#include "Window.h"
|
||||
|
||||
static void save_img(render_target_t* source, const uint32_t width, const uint32_t height, const char* filename)
|
||||
static void save_img(render_target_t* source, uint32_t width, uint32_t height, const char* filename)
|
||||
{
|
||||
FILE* file_stream;
|
||||
fopen_s(&file_stream, filename, "wb");
|
||||
@@ -48,7 +48,11 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
|
||||
omp_set_num_threads(16);
|
||||
sobol_init();
|
||||
|
||||
scene_t scene = scene_create(64, 8, 4);
|
||||
scene_t scene;
|
||||
if (!scene_init(64, 8, 4, &scene))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
scene.camera.position = (vec3s){0.0f, 0.0f, 5.0f};
|
||||
|
||||
@@ -142,7 +146,8 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
|
||||
|
||||
#pragma endregion
|
||||
|
||||
render_target_t img = render_target_create(config.width, config.height);
|
||||
render_target_t img;
|
||||
render_target_init(config.width, config.height, &img);
|
||||
// render_target_t img = scene_render(&scene, config);
|
||||
// save_img(&img, config.width, config.height, "output.png");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user