diff options
| author | Connor Thomson <blumatrikz@gmail.com> | 2026-09-10 19:16:42 -0700 |
|---|---|---|
| committer | Connor Thomson <blumatrikz@gmail.com> | 2026-09-10 19:16:42 -0700 |
| commit | a618f7c8d4e8df65d9d2542d9032c32973e42981 (patch) | |
| tree | 79e1a9eccd4d1ad61daf4c14f2e3c76638f37597 /src/obj_model.c | |
| parent | e9d4cbaa3c44337115d672d2038a7b73745181c8 (diff) | |
Switch away from Wavefront & more
Diffstat (limited to 'src/obj_model.c')
| -rw-r--r-- | src/obj_model.c | 188 |
1 files changed, 0 insertions, 188 deletions
diff --git a/src/obj_model.c b/src/obj_model.c deleted file mode 100644 index 39c25b6..0000000 --- a/src/obj_model.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Tuxánci 2 - A first person shooter - * Copyright (C) 2007-2011 Tuxánci Development Team - * Copyright (C) 2025-2026 Connor Thomson - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -#include <math.h> -#include <string.h> -#include "obj_model.h" -#include "camera.h" -#include "ta_sdl.h" -#include "files.h" - -typedef struct ta_obj_uniforms { - float mvp[16]; - float model[16]; - float camera_position[3]; - float padding; -} ta_obj_uniforms; - -static SDL_GPUShader *ta_obj_shader(SDL_GPUDevice *device, const void *code, size_t size, SDL_GPUShaderStage stage) { - SDL_GPUShaderCreateInfo info = { - .code = code, - .code_size = size, - .entrypoint = "main", - .format = SDL_GPU_SHADERFORMAT_SPIRV, - .stage = stage, - .num_uniform_buffers = stage == SDL_GPU_SHADERSTAGE_VERTEX ? 1 : 0, - }; - return ta_sdl_create_gpu_shader(device, &info); -} - -static void ta_obj_identity(float *matrix) { - for (int index = 0; index < 16; index++) matrix[index] = index % 5 == 0 ? 1.0f : 0.0f; -} - -static void ta_obj_multiply(float *result, const float *left, const float *right) { - float product[16]; - for (int column = 0; column < 4; column++) for (int row = 0; row < 4; row++) { - product[column * 4 + row] = 0.0f; - for (int inner = 0; inner < 4; inner++) product[column * 4 + row] += left[inner * 4 + row] * right[column * 4 + inner]; - } - memcpy(result, product, sizeof(product)); -} - -bool ta_obj_model_init(ta_obj_model *model, SDL_GPUDevice *device, const unsigned char *data, size_t size, SDL_GPUTextureFormat color_format, SDL_GPUTextureFormat depth_format, SDL_GPUSampleCount sample_count) { - memset(model, 0, sizeof(*model)); - if (!ta_obj_parse(data, size, &model->mesh) || model->mesh.vertex_count == 0) return false; - float minimum[3]; - float maximum[3]; - memcpy(minimum, model->mesh.vertices[0].position, sizeof(minimum)); - memcpy(maximum, minimum, sizeof(maximum)); - for (size_t index = 1; index < model->mesh.vertex_count; index++) for (int axis = 0; axis < 3; axis++) { - if (model->mesh.vertices[index].position[axis] < minimum[axis]) minimum[axis] = model->mesh.vertices[index].position[axis]; - if (model->mesh.vertices[index].position[axis] > maximum[axis]) maximum[axis] = model->mesh.vertices[index].position[axis]; - } - float center[3] = {(minimum[0] + maximum[0]) * 0.5f, (minimum[1] + maximum[1]) * 0.5f, (minimum[2] + maximum[2]) * 0.5f}; - float extent = maximum[0] - minimum[0]; - for (int axis = 1; axis < 3; axis++) if (maximum[axis] - minimum[axis] > extent) extent = maximum[axis] - minimum[axis]; - for (size_t index = 0; index < model->mesh.vertex_count; index++) for (int axis = 0; axis < 3; axis++) model->mesh.vertices[index].position[axis] = (model->mesh.vertices[index].position[axis] - center[axis]) * (2.2f / extent); - - SDL_GPUBufferCreateInfo buffer_info = {.usage = SDL_GPU_BUFFERUSAGE_VERTEX, .size = (Uint32)(model->mesh.vertex_count * sizeof(*model->mesh.vertices))}; - model->vertex_buffer = SDL_CreateGPUBuffer(device, &buffer_info); - if (!model->vertex_buffer) { - ta_obj_free(&model->mesh); - return false; - } - model->vertex_count = (Uint32)model->mesh.vertex_count; - SDL_GPUShader *vertex_shader = ta_obj_shader(device, file_obj_vert_slang_spv_start, file_obj_vert_slang_spv_size, SDL_GPU_SHADERSTAGE_VERTEX); - SDL_GPUShader *fragment_shader = ta_obj_shader(device, file_obj_frag_slang_spv_start, file_obj_frag_slang_spv_size, SDL_GPU_SHADERSTAGE_FRAGMENT); - SDL_GPUVertexBufferDescription vertex_buffer = {.slot = 0, .pitch = sizeof(ta_obj_vertex), .input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX}; - SDL_GPUVertexAttribute attributes[2] = { - {.location = 0, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3, .offset = 0}, - {.location = 1, .buffer_slot = 0, .format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3, .offset = sizeof(float) * 3}, - }; - SDL_GPUColorTargetDescription color_target = {.format = color_format}; - SDL_GPUGraphicsPipelineCreateInfo pipeline_info = { - .vertex_shader = vertex_shader, - .fragment_shader = fragment_shader, - .vertex_input_state = {.vertex_buffer_descriptions = &vertex_buffer, .num_vertex_buffers = 1, .vertex_attributes = attributes, .num_vertex_attributes = 2}, - .primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, - .rasterizer_state = {.cull_mode = SDL_GPU_CULLMODE_NONE}, - .depth_stencil_state = {.compare_op = SDL_GPU_COMPAREOP_LESS, .enable_depth_test = true, .enable_depth_write = true}, - .multisample_state = {.sample_count = sample_count}, - .target_info = {.num_color_targets = 1, .color_target_descriptions = &color_target, .depth_stencil_format = depth_format, .has_depth_stencil_target = true}, - }; - model->pipeline = ta_sdl_create_gpu_graphics_pipeline(device, &pipeline_info); - SDL_ReleaseGPUShader(device, vertex_shader); - SDL_ReleaseGPUShader(device, fragment_shader); - return model->pipeline != NULL; -} - -void ta_obj_model_upload(ta_obj_model *model, SDL_GPUCommandBuffer *command_buffer, SDL_GPUDevice *device) { - if (model->uploaded || !model->vertex_buffer) return; - Uint32 size = (Uint32)(model->mesh.vertex_count * sizeof(*model->mesh.vertices)); - SDL_GPUTransferBufferCreateInfo transfer_info = {.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD, .size = size}; - SDL_GPUTransferBuffer *transfer_buffer = ta_sdl_create_gpu_transfer_buffer(device, &transfer_info); - void *mapped = ta_sdl_map_gpu_transfer_buffer(device, transfer_buffer, false); - memcpy(mapped, model->mesh.vertices, size); - SDL_UnmapGPUTransferBuffer(device, transfer_buffer); - SDL_GPUCopyPass *copy_pass = ta_sdl_begin_gpu_copy_pass(command_buffer); - SDL_GPUTransferBufferLocation source = {.transfer_buffer = transfer_buffer}; - SDL_GPUBufferRegion destination = {.buffer = model->vertex_buffer, .size = size}; - SDL_UploadToGPUBuffer(copy_pass, &source, &destination, false); - SDL_EndGPUCopyPass(copy_pass); - SDL_ReleaseGPUTransferBuffer(device, transfer_buffer); - ta_obj_free(&model->mesh); - model->uploaded = true; -} - -void ta_obj_model_render(const ta_obj_model *model, SDL_GPUCommandBuffer *command_buffer, SDL_GPURenderPass *render_pass, int window_width, int window_height) { - if (!model->pipeline || !model->vertex_buffer || !model->uploaded) return; - ta_obj_uniforms uniforms; - float view[16]; - float projection[16] = {0}; - float view_model[16]; - float rotation_x[16]; - float rotation_y[16]; - float rotation_z[16]; - float rotation_xy[16]; - float cosine = cosf(model->rotation[0]); - float sine = sinf(model->rotation[0]); - ta_obj_identity(rotation_x); - rotation_x[5] = cosine; - rotation_x[6] = sine; - rotation_x[9] = -sine; - rotation_x[10] = cosine; - cosine = cosf(model->rotation[1]); - sine = sinf(model->rotation[1]); - ta_obj_identity(rotation_y); - rotation_y[0] = cosine; - rotation_y[2] = -sine; - rotation_y[8] = sine; - rotation_y[10] = cosine; - cosine = cosf(model->rotation[2]); - sine = sinf(model->rotation[2]); - ta_obj_identity(rotation_z); - rotation_z[0] = cosine; - rotation_z[1] = sine; - rotation_z[4] = -sine; - rotation_z[5] = cosine; - ta_obj_multiply(rotation_xy, rotation_y, rotation_x); - ta_obj_multiply(uniforms.model, rotation_z, rotation_xy); - uniforms.model[12] = model->position[0]; - uniforms.model[13] = model->position[1]; - uniforms.model[14] = model->position[2]; - float aspect = (float)window_width / (float)window_height; - float focal_length = 1.0f / tanf(22.5f * 0.01745329252f); - float near_plane = 0.1f; - float far_plane = 100.0f; - ta_camera_get_view_matrix(view); - projection[0] = focal_length / aspect; - projection[5] = focal_length; - projection[10] = far_plane / (near_plane - far_plane); - projection[11] = -1.0f; - projection[14] = near_plane * far_plane / (near_plane - far_plane); - ta_obj_multiply(view_model, view, uniforms.model); - ta_obj_multiply(uniforms.mvp, projection, view_model); - uniforms.camera_position[0] = ta_camera_current.x; - uniforms.camera_position[1] = ta_camera_current.y; - uniforms.camera_position[2] = ta_camera_current.z; - uniforms.padding = 0.0f; - SDL_PushGPUVertexUniformData(command_buffer, 0, &uniforms, sizeof(uniforms)); - SDL_BindGPUGraphicsPipeline(render_pass, model->pipeline); - SDL_GPUBufferBinding binding = {.buffer = model->vertex_buffer}; - SDL_BindGPUVertexBuffers(render_pass, 0, &binding, 1); - SDL_DrawGPUPrimitives(render_pass, model->vertex_count, 1, 0, 0); -} - -void ta_obj_model_destroy(ta_obj_model *model, SDL_GPUDevice *device) { - SDL_ReleaseGPUGraphicsPipeline(device, model->pipeline); - SDL_ReleaseGPUBuffer(device, model->vertex_buffer); - ta_obj_free(&model->mesh); - memset(model, 0, sizeof(*model)); -}
\ No newline at end of file |