diff options
author | omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-10-05 12:48:05 +1000 |
---|---|---|
committer | omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-10-05 12:48:05 +1000 |
commit | dfb6adbcbcc7d50b770b6d5ea82efdd8f8c32e25 (patch) | |
tree | a470b91a90716d7ea46fde53ed395449c24583a2 /archive/src/systems/terrain.c | |
parent | 54354e32c6498cc7f8839ab4deb1208d37216cc5 (diff) |
delete documentation workflow
Diffstat (limited to 'archive/src/systems/terrain.c')
-rw-r--r-- | archive/src/systems/terrain.c | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/archive/src/systems/terrain.c b/archive/src/systems/terrain.c new file mode 100644 index 0000000..069000e --- /dev/null +++ b/archive/src/systems/terrain.c @@ -0,0 +1,204 @@ +/** + * @brief + */ +#include "terrain.h" +#include <assert.h> +#include "file.h" +#include "glad/glad.h" +#include "log.h" +#include "maths.h" +#include "mem.h" +#include "ral_common.h" +#include "ral_impl.h" +#include "ral_types.h" +#include "render.h" +#include "shader_layouts.h" +#include "str.h" + +#define TERRAIN_GRID_U 505 +#define TERRAIN_GRID_V 505 + +bool Terrain_Init(Terrain_Storage* storage) { + storage->grid_dimensions = u32x2(TERRAIN_GRID_U, TERRAIN_GRID_V); + storage->hmap_loaded = false; + + GPU_RenderpassDesc rpass_desc = { + .default_framebuffer = true, + }; + storage->hmap_renderpass = GPU_Renderpass_Create(rpass_desc); + + arena scratch = arena_create(malloc(1024 * 1024), 1024 * 1024); + + Str8 vert_path = str8("assets/shaders/terrain.vert"); + Str8 frag_path = str8("assets/shaders/terrain.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") + } + + ShaderDataLayout camera_data = Binding_Camera_GetLayout(NULL); + ShaderDataLayout terrain_data = TerrainUniforms_GetLayout(NULL); + + GraphicsPipelineDesc pipeline_desc = { + .debug_name = "terrain rendering pipeline", + .vertex_desc = static_3d_vertex_description(), + .data_layouts = { camera_data, terrain_data }, + .data_layouts_count = 2, + .vs = { + .debug_name = "terrain vertex shader", + .filepath = vert_path, + .code = vertex_shader.contents, + }, + .fs = { + .debug_name = "terrain fragment shader", + .filepath = frag_path, + .code = fragment_shader.contents, + }, + .wireframe = false, + }; + storage->hmap_pipeline = GPU_GraphicsPipeline_Create(pipeline_desc, storage->hmap_renderpass); + + storage->texture = TextureLoadFromFile("assets/demo/textures/grass2.png"); + + return true; +} + +void Terrain_Shutdown(Terrain_Storage* storage) {} + +void Terrain_LoadHeightmap(Terrain_Storage* storage, Heightmap hmap, f32 grid_scale, + bool free_on_upload) { + // If there's a current one we will delete it and reallocate buffers + if (storage->hmap_loaded) { + GPU_BufferDestroy(storage->vertex_buffer); + GPU_BufferDestroy(storage->index_buffer); + } + + u32 width = hmap.pixel_dimensions.x; + u32 height = hmap.pixel_dimensions.y; + storage->grid_scale = grid_scale; + + size_t num_vertices = storage->grid_dimensions.x * storage->grid_dimensions.y; + storage->num_vertices = num_vertices; + + Vertex_darray* vertices = Vertex_darray_new(num_vertices); + u32 index = 0; + for (u32 i = 0; i < storage->grid_dimensions.x; i++) { + for (u32 j = 0; j < storage->grid_dimensions.y; j++) { + size_t position = j * storage->grid_dimensions.x + i; + u8* bytes = hmap.image_data; + u8 channel = bytes[position]; + float value = (float)channel / 255.0; + // printf("(%d, %d) %d : %f \n", i, j, channel, value); + + assert(index < num_vertices); + f32 height = Heightmap_HeightXZ(&hmap, i, j); + Vec3 v_pos = vec3_create(i * grid_scale, height, j * grid_scale); + Vec3 v_normal = VEC3_Y; + float tiling_factor = 505.0f; + Vec2 v_uv = vec2((f32)i / width * tiling_factor, (f32)j / height * tiling_factor); + Vertex v = { .static_3d = { .position = v_pos, .normal = v_normal, .tex_coords = v_uv } }; + Vertex_darray_push(vertices, v); + index++; + } + } + BufferHandle vertices_handle = GPU_BufferCreate(num_vertices * sizeof(Vertex), BUFFER_VERTEX, + BUFFER_FLAG_GPU, vertices->data); + storage->vertex_buffer = vertices_handle; + + u32 quad_count = (width - 1) * (height - 1); + u32 indices_count = quad_count * 6; + storage->indices_count = indices_count; + u32_darray* indices = u32_darray_new(indices_count); + for (u32 i = 0; i < (width - 1); i++) { // row + for (u32 j = 0; j < (height - 1); j++) { // col + u32 bot_left = i * width + j; + u32 top_left = (i + 1) * width + j; + u32 top_right = (i + 1) * width + (j + 1); + u32 bot_right = i * width + j + 1; + + // top left tri + u32_darray_push(indices, top_right); + u32_darray_push(indices, top_left); + u32_darray_push(indices, bot_left); + + // bottom right tri + u32_darray_push(indices, bot_right); + u32_darray_push(indices, top_right); + u32_darray_push(indices, bot_left); + } + } + + BufferHandle indices_handle = + GPU_BufferCreate(indices_count * sizeof(u32), BUFFER_INDEX, BUFFER_FLAG_GPU, indices->data); + storage->index_buffer = indices_handle; +} + +Heightmap Heightmap_FromImage(Str8 filepath) { + size_t max_size = MB(16); + arena arena = arena_create(malloc(max_size), max_size); + // str8_opt maybe_file = str8_from_file(&arena, filepath); + // assert(maybe_file.has_value); + + TextureData hmap_tex = TextureDataLoad(Str8_to_cstr(&arena, filepath), false); + + // arena_free_storage(&arena); + + return (Heightmap){ + .pixel_dimensions = hmap_tex.description.extents, + .filepath = filepath, + .image_data = hmap_tex.image_data, + .num_channels = hmap_tex.description.num_channels, + .is_uploaded = false, + }; +} + +void Terrain_Draw(Terrain_Storage* storage) { + GPU_CmdEncoder* enc = GPU_GetDefaultEncoder(); + GPU_EncodeBindPipeline(enc, storage->hmap_pipeline); + RenderScene* scene = Render_GetScene(); + + Mat4 view, proj; + u32x2 dimensions = GPU_Swapchain_GetDimensions(); + Camera_ViewProj(&scene->camera, (f32)dimensions.x, (f32)dimensions.y, &view, &proj); + Binding_Camera camera_data = { .view = view, + .projection = proj, + .viewPos = vec4(scene->camera.position.x, scene->camera.position.y, + scene->camera.position.z, 1.0) }; + GPU_EncodeBindShaderData(enc, 0, Binding_Camera_GetLayout(&camera_data)); + + TerrainUniforms uniforms = { .tex_slot_1 = storage->texture }; + ShaderDataLayout terrain_data = TerrainUniforms_GetLayout(&uniforms); + GPU_EncodeBindShaderData(enc, 1, terrain_data); + + GPU_EncodeSetVertexBuffer(enc, storage->vertex_buffer); + GPU_EncodeSetIndexBuffer(enc, storage->index_buffer); + + GPU_EncodeDrawIndexedTris(enc, storage->indices_count); + // glDrawArrays(GL_POINTS, 0, storage->num_vertices); +} + +f32 Heightmap_HeightXZ(const Heightmap* hmap, u32 x, u32 z) { + // its single channel so only one byte per pixel + size_t position = x * hmap->pixel_dimensions.x + z; + u8* bytes = hmap->image_data; + u8 channel = bytes[position]; + float value = (float)channel / 2.0; /// 255.0; + return value; +} + +ShaderDataLayout TerrainUniforms_GetLayout(void* data) { + TerrainUniforms* d = data; + bool has_data = data != NULL; + + ShaderBinding b1 = { + .label = "TextureSlot1", + .kind = BINDING_TEXTURE, + .vis = VISIBILITY_FRAGMENT, + }; + + if (has_data) { + b1.data.texture.handle = d->tex_slot_1; + } + return (ShaderDataLayout){ .bindings = { b1 }, .binding_count = 1 }; +} |