From 3cd5b0bcca694630fcb4b977ddf7be7cd1bce153 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 20 Jan 2024 15:54:54 -0800 Subject: Rename gltfview -> game. --- game/src/plugins/texture_view.c | 147 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 game/src/plugins/texture_view.c (limited to 'game/src/plugins/texture_view.c') diff --git a/game/src/plugins/texture_view.c b/game/src/plugins/texture_view.c new file mode 100644 index 0000000..b424158 --- /dev/null +++ b/game/src/plugins/texture_view.c @@ -0,0 +1,147 @@ +#include "plugin.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +// Default texture to load if no texture is provided. +static const char* DEFAULT_TEXTURE = "/assets/skybox/clouds1/clouds1_west.bmp"; +// static const char* DEFAULT_TEXTURE = "/assets/checkerboard.jpg"; + +struct State { + Scene* scene; + SceneCamera* camera; +}; + +bool init(Game* game, State** pp_state) { + assert(game); + assert(pp_state); + + State* state = calloc(1, sizeof(State)); + if (!state) { + goto cleanup; + } + + // Usage: [texture file] + const char* texture_file = game->argc > 1 ? game->argv[1] : DEFAULT_TEXTURE; + + RenderBackend* render_backend = gfx_get_render_backend(game->gfx); + + Texture* texture = gfx_load_texture( + render_backend, &(LoadTextureCmd){ + .origin = TextureFromFile, + .type = LoadTexture, + .filtering = LinearFiltering, + .mipmaps = false, + .data.texture.filepath = mstring_make(texture_file)}); + if (!texture) { + goto cleanup; + } + + ShaderProgram* shader = gfx_make_view_texture_shader(render_backend); + if (!shader) { + goto cleanup; + } + + Geometry* geometry = gfx_make_quad_11(render_backend); + if (!geometry) { + goto cleanup; + } + + MaterialDesc material_desc = (MaterialDesc){.num_uniforms = 1}; + material_desc.uniforms[0] = (ShaderUniform){ + .type = UniformTexture, + .value.texture = texture, + .name = sstring_make("Texture")}; + Material* material = gfx_make_material(&material_desc); + if (!material) { + goto cleanup; + } + + const MeshDesc mesh_desc = + (MeshDesc){.geometry = geometry, .material = material, .shader = shader}; + Mesh* mesh = gfx_make_mesh(&mesh_desc); + if (!mesh) { + goto cleanup; + } + + SceneObject* object = gfx_make_object(); + if (!object) { + goto cleanup; + } + gfx_add_object_mesh(object, mesh); + + if (!(state->scene = gfx_make_scene())) { + goto cleanup; + } + + SceneNode* node = gfx_make_object_node(object); + if (!node) { + goto cleanup; + } + SceneNode* root = gfx_get_scene_root(state->scene); + if (!root) { + goto cleanup; + } + gfx_set_node_parent(node, root); + + if (!(state->camera = gfx_make_camera())) { + goto cleanup; + } + + *pp_state = state; + return true; + +cleanup: + shutdown(game, state); + if (state) { + free(state); + } + return false; +} + +void shutdown(Game* game, State* state) { + assert(game); + if (state) { + gfx_destroy_camera(&state->camera); + gfx_destroy_scene(&state->scene); + // State freed by plugin engine. + } +} + +void render(const Game* game, const State* state) { + assert(game); + assert(state); + + Renderer* renderer = gfx_get_renderer(game->gfx); + gfx_render_scene( + renderer, &(RenderSceneParams){ + .mode = RenderDefault, + .scene = state->scene, + .camera = state->camera}); +} + +void resize(Game* game, State* state, int width, int height) { + assert(game); + assert(state); + + RenderBackend* render_backend = gfx_get_render_backend(game->gfx); + gfx_set_viewport(render_backend, width, height); + + const R fovy = 90 * TO_RAD; + const R aspect = (R)width / (R)height; + const R near = 0.1; + const R far = 1000; + const mat4 projection = mat4_perspective(fovy, aspect, near, far); + + Camera* camera = gfx_get_camera_camera(state->camera); + camera->projection = projection; +} -- cgit v1.2.3