summaryrefslogtreecommitdiff
path: root/pbr/2.1.1.ibl_irradiance_conversion/ibl_irradiance_conversion.c
diff options
context:
space:
mode:
authorpryazha <pryadeiniv@mail.ru>2025-07-23 20:55:29 +0500
committerpryazha <pryadeiniv@mail.ru>2025-07-23 20:55:29 +0500
commit33d5f67044d104d69cb2d11e78e6a79bc20d4c4e (patch)
tree61a61becc4a2ccf2638403ecd85518d26bbf1a23 /pbr/2.1.1.ibl_irradiance_conversion/ibl_irradiance_conversion.c
parent76df5cc4186ca3449e9b957e7de753cb6df4047b (diff)
some prb examples
Diffstat (limited to 'pbr/2.1.1.ibl_irradiance_conversion/ibl_irradiance_conversion.c')
-rw-r--r--pbr/2.1.1.ibl_irradiance_conversion/ibl_irradiance_conversion.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/pbr/2.1.1.ibl_irradiance_conversion/ibl_irradiance_conversion.c b/pbr/2.1.1.ibl_irradiance_conversion/ibl_irradiance_conversion.c
new file mode 100644
index 0000000..0ffbe7c
--- /dev/null
+++ b/pbr/2.1.1.ibl_irradiance_conversion/ibl_irradiance_conversion.c
@@ -0,0 +1,193 @@
+#include "GL/glew.h"
+#include "GLFW/glfw3.h"
+#include "common.h"
+
+int main(void)
+{
+ state_t state = init_state(1600, 800);
+
+ init_glfw(&state);
+ init_gl();
+ glDepthFunc(GL_LEQUAL);
+
+ /* meshes */
+ Mesh *cube = mesh_load_obj(state.arena, "../../data/models/cube.obj");
+ Mesh *quad = mesh_gen_quad(state.arena);
+
+ /* shaders */
+ add_shader("pbr.vert", "pbr.frag", 0);
+ add_shader("hdr.vert", "hdr.frag", 0);
+ add_shader("cubemap.vert", "cubemap.frag", 0);
+ add_shader("background.vert", "background.frag", 0);
+
+ light_t lights[4] = {
+ {{-10.0f, 0.0f, 20.0f}, {300.0f, 300.0f, 300.0f}},
+ {{-5.0f, 0.0f, 20.0f}, {300.0f, 300.0f, 300.0f}},
+ {{ 5.0f, 0.0f, 20.0f}, {300.0f, 300.0f, 300.0f}},
+ {{ 10.0f, 0.0f, 20.0f}, {300.0f, 300.0f, 300.0f}},
+ };
+
+ /* textures */
+ U32 hdr_texture = load_hdr_texture("../../data/textures/loigerwiesen.hdr");
+
+ /* framebuffers */
+ U32 hdr_fbo, hdr_colorbuffer, hdr_rbo;
+ glGenFramebuffers(1, &hdr_fbo);
+ glGenTextures(1, &hdr_colorbuffer);
+ glBindTexture(GL_TEXTURE_2D, hdr_colorbuffer);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, state.width, state.height, 0, GL_RGBA, GL_FLOAT, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glGenRenderbuffers(1, &hdr_rbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, hdr_rbo);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, state.width, state.height);
+ glBindFramebuffer(GL_FRAMEBUFFER, hdr_fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, hdr_colorbuffer, 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, hdr_rbo);
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+ die("failed to create framebuffer");
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ U32 capture_fbo, capture_rbo;
+ glGenFramebuffers(1, &capture_fbo);
+ glGenRenderbuffers(1, &capture_rbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, capture_fbo);
+ glBindRenderbuffer(GL_RENDERBUFFER, capture_rbo);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 512, 512);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, capture_rbo);
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+ die("failed to create framebuffer");
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ U32 cubemap;
+ glGenTextures(1, &cubemap);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap);
+ for (U32 i = 0; i < 6; i++)
+ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 512, 512, 0, GL_RGB, GL_FLOAT, 0);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ MAT4 capture_projection = perspective(90.0f, 1.0f, 0.1f, 10.0f);
+ V3F capture_origin = {0};
+ MAT4 capture_views[6] = {
+ look_at(capture_origin, v3f( 1.0f, 0.0f, 0.0f), v3f(0.0f, -1.0f, 0.0f)),
+ look_at(capture_origin, v3f(-1.0f, 0.0f, 0.0f), v3f(0.0f, -1.0f, 0.0f)),
+ look_at(capture_origin, v3f( 0.0f, 1.0f, 0.0f), v3f(0.0f, 0.0f, 1.0f)),
+ look_at(capture_origin, v3f( 0.0f, -1.0f, 0.0f), v3f(0.0f, 0.0f, -1.0f)),
+ look_at(capture_origin, v3f( 0.0f, 0.0f, 1.0f), v3f(0.0f, -1.0f, 0.0f)),
+ look_at(capture_origin, v3f( 0.0f, 0.0f, -1.0f), v3f(0.0f, -1.0f, 0.0f)),
+ };
+
+ glBindFramebuffer(GL_FRAMEBUFFER, capture_fbo);
+ U32 shader = find_shader("cubemap");
+ if (!shader) die("waht");
+ glUseProgram(shader);
+ shader_set_mat4fv(shader, "projection", capture_projection);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, hdr_texture);
+
+ glViewport(0, 0, 512, 512);
+ for (U32 i = 0; i < 6; i++) {
+ shader_set_mat4fv(shader, "view", capture_views[i]);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cubemap, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ mesh_draw(cube);
+ }
+ glUseProgram(0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ glViewport(0, 0, state.width, state.height);
+
+ F32 time = 0;
+
+ while (!glfwWindowShouldClose(state.window)) {
+ handle_glfw_events(state.window, &state.input);
+ F32 dt = lock_framerate(60);
+ fps_info(dt, 10);
+
+ /* update */
+ update_camera_first_person(&state.camera, &state.input, dt, 2.0f);
+ F32 limit = 4.0f;
+ for (U32 i = 0; i < (sizeof(lights) / sizeof(lights[0])); i++)
+ lights[i].position.y = sinf(time + i) * limit;
+ time += dt;
+
+ /* render */
+ F32 ar = (F32)state.width / (F32)state.height;
+ MAT4 projection = camera_persp(state.camera, ar);
+ MAT4 view = get_view_matrix(&state.camera);
+
+ glClearColor(0.16f, 0.16f, 0.16f, 1.0f);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, hdr_fbo);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ shader = find_shader("pbr");
+ if (!shader) die("wha");
+ glUseProgram(shader);
+ shader_set_mat4fv(shader, "projection", projection);
+ shader_set_mat4fv(shader, "view", view);
+ shader_set_3fv(shader, "camera", state.camera.pos);
+ shader_set_3fv(shader, "color", v3f(0.04, 0.04, 0.04));
+ shader_set_1f(shader, "ao", 1.0f);
+ for (U32 i = 0; i < (sizeof(lights) / sizeof(lights[0])); i++) {
+ char str[512];
+ snprintf(str, 512, "lights[%d].position", i);
+ shader_set_3fv(shader, str, lights[i].position);
+ snprintf(str, 512, "lights[%d].color", i);
+ shader_set_3fv(shader, str, lights[i].color);
+ }
+ S32 rows = 7;
+ S32 cols = 7;
+ F32 offset = 3.0f;
+ for (S32 row = 0; row < rows; row++) {
+ shader_set_1f(shader, "metallic", (F32)row / (F32)rows);
+ for (S32 col = 0; col < cols; col++) {
+ shader_set_1f(shader, "roughness", clamp(0.05f, (F32)col / (F32)cols, 1.0f));
+ V3F pos = {(col - cols / 2.0f) * offset, (row - rows / 2.0f) * offset, 0.0f};
+ MAT4 model = mat4_make_translate(pos);
+ shader_set_mat4fv(shader, "model", model);
+ mesh_draw(cube);
+ }
+ }
+
+ for (U32 i = 0; i < (sizeof(lights) / sizeof(lights[0])); i++) {
+ MAT4 model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f));
+ model = mat4_translate(model, lights[i].position);
+ shader_set_mat4fv(shader, "model", model);
+ mesh_draw(cube);
+ }
+
+ glUseProgram(0);
+
+ shader = find_shader("background");
+ glUseProgram(shader);
+ shader_set_mat4fv(shader, "projection", projection);
+ shader_set_mat4fv(shader, "view", view);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, cubemap);
+ mesh_draw(cube);
+ glUseProgram(0);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ shader = find_shader("hdr");
+ if (!shader) die("failed to find hdr shader!");
+ glUseProgram(shader);
+ glBindTexture(GL_TEXTURE_2D, hdr_colorbuffer);
+ shader_set_mat4fv(shader, "model", mat4_identity());
+ mesh_draw(quad);
+ glUseProgram(0);
+
+ glfwSwapBuffers(state.window);
+ }
+
+ return 0;
+}