From 4b5695ce26a8f821dfac987e8e11a6ba5eeff610 Mon Sep 17 00:00:00 2001 From: omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Mon, 17 Jun 2024 22:17:48 +1000 Subject: start working on a immediate mode drawing API --- examples/pbr_textured/ex_pbr_textured.c | 135 ++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 examples/pbr_textured/ex_pbr_textured.c (limited to 'examples') diff --git a/examples/pbr_textured/ex_pbr_textured.c b/examples/pbr_textured/ex_pbr_textured.c new file mode 100644 index 0000000..a28d3fb --- /dev/null +++ b/examples/pbr_textured/ex_pbr_textured.c @@ -0,0 +1,135 @@ +#include +#include + +#include "builtin_materials.h" +#include "camera.h" +#include "colours.h" +#include "core.h" +#include "loaders.h" +#include "log.h" +#include "maths.h" +#include "maths_types.h" +#include "primitives.h" +#include "ral.h" +#include "render.h" +#include "render_types.h" +#include "str.h" + +extern core g_core; + +#define MODEL_GET(h) (model_pool_get(&g_core.models, h)) + +const vec3 pointlight_positions[4] = { + { 10.0 / 1., 10.0 / 1., 10.0 }, + { -10.0 / 1., 10.0 / 1., 10.0 }, + { 10.0 / 1., -10.0 / 1., 10.0 }, + { -10.0 / 1., -10.0 / 1., 10.0 }, +}; +pbr_point_light point_lights[4]; + +int main() { + core_bringup(); + + arena scratch = arena_create(malloc(1024 * 1024), 1024 * 1024); + + for (int i = 0; i < 4; i++) { + point_lights[i].pos = pointlight_positions[i]; + point_lights[i].color = vec3(300.0, 300.0, 300.0); + } + + vec3 camera_pos = vec3(5., 0., 0.); + vec3 camera_front = vec3_normalise(vec3_negate(camera_pos)); + camera cam = camera_create(camera_pos, camera_front, VEC3_NEG_Z, deg_to_rad(45.0)); + + shader_data pbr_uniforms = { .data = NULL, .shader_data_get_layout = &pbr_textured_shader_layout }; + + // Make the pipeline + gpu_renderpass_desc pass_description = {}; + gpu_renderpass* renderpass = gpu_renderpass_create(&pass_description); + str8 vert_path = str8lit("assets/shaders/pbr_textured.vert"); + str8 frag_path = str8lit("assets/shaders/pbr_textured.frag"); + str8_opt vertex_shader = str8_from_file(&scratch, vert_path); + str8_opt fragment_shader = str8_from_file(&scratch, frag_path); + if (!vertex_shader.has_value || !fragment_shader.has_value) { + ERROR_EXIT("Failed to load shaders from disk") + } + + struct graphics_pipeline_desc pipeline_description = { + .debug_name = "Basic Pipeline", + .vertex_desc = static_3d_vertex_description(), + .data_layouts = { pbr_uniforms }, + .data_layouts_count = 1, + .vs = { .debug_name = "PBR (textured) Vertex Shader", + .filepath = vert_path, + .code = vertex_shader.contents, + .is_spirv = false }, + .fs = { .debug_name = "PBR (textured) Fragment Shader", + .filepath = frag_path, + .code = fragment_shader.contents, + .is_spirv = false }, + .renderpass = renderpass, + .wireframe = false, + .depth_test = false + }; + gpu_pipeline* pbr_pipeline = gpu_graphics_pipeline_create(pipeline_description); + + // Model + model_handle helmet_handle = + model_load_gltf("assets/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf", false); + INFO("GLTF loaded successfully!"); + model* helmet = MODEL_GET(helmet_handle); + + pbr_textured_bindgroup pbr_bind_data; + + while (!should_exit()) { + input_update(&g_core.input); + + if (!gpu_backend_begin_frame()) { + continue; + } + gpu_cmd_encoder* enc = gpu_get_default_cmd_encoder(); + // Begin recording + gpu_cmd_encoder_begin(*enc); + gpu_cmd_encoder_begin_render(enc, renderpass); + encode_bind_pipeline(enc, PIPELINE_GRAPHICS, pbr_pipeline); + encode_set_default_settings(enc); + + mat4 model_affine = mat4_ident(); + mat4 view, proj; + camera_view_projection(&cam, 1000, 1000, &view, &proj); + + // Feed shader data + pbr_bind_data.mvp_matrices = + (mvp_matrix_uniforms){ .model = model_affine, .view = view, .projection = proj }; + pbr_bind_data.lights = (pbr_params_light_uniforms){ + .viewPos = vec4(cam.position.x, cam.position.y, cam.position.z, 1.0), + .pointLights = { point_lights[0], point_lights[1], point_lights[2], point_lights[3] } + }; + pbr_bind_data.textures = (pbr_textures){ + .albedo_tex = helmet->materials->data[0].mat_data.pbr.albedo_map, + .metal_roughness_tex = helmet->materials->data[0].mat_data.pbr.metallic_map, + .ao_tex = helmet->materials->data[0].mat_data.pbr.ao_map, + .normal_tex = helmet->materials->data[0].mat_data.pbr.normal_map, + }; + pbr_uniforms.data = &pbr_bind_data; + encode_bind_shader_data(enc, 0, &pbr_uniforms); + + // Record draw calls + mesh m = helmet->meshes->data[0]; + encode_set_vertex_buffer(enc, m.vertex_buffer); + encode_set_index_buffer(enc, m.index_buffer); + encode_draw_indexed(enc, m.geometry->indices->len); + + // End recording + gpu_cmd_encoder_end_render(enc); + + gpu_cmd_buffer buf = gpu_cmd_encoder_finish(enc); + gpu_queue_submit(&buf); + // Submit + gpu_backend_end_frame(); + } + + renderer_shutdown(&g_core.renderer); + + return 0; +} \ No newline at end of file -- cgit v1.2.3-70-g09d2