From 562aba4f9c71356c4242fdd031948640350aea47 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Thu, 8 Feb 2024 20:39:44 -0800 Subject: Rename glfw_view -> viewer. --- game/src/plugins/CMakeLists.txt | 8 +- game/src/plugins/gltf_view.c | 240 ---------------------------------------- game/src/plugins/viewer.c | 240 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 244 insertions(+), 244 deletions(-) delete mode 100644 game/src/plugins/gltf_view.c create mode 100644 game/src/plugins/viewer.c diff --git a/game/src/plugins/CMakeLists.txt b/game/src/plugins/CMakeLists.txt index e5abbb8..8661598 100644 --- a/game/src/plugins/CMakeLists.txt +++ b/game/src/plugins/CMakeLists.txt @@ -4,12 +4,12 @@ project(plugins) set(LINK_LIBRARIES cstring math gfx gfx-app) -# GLTF viewer +# Viewer -add_library(gltf_view SHARED - gltf_view.c) +add_library(viewer SHARED + viewer.c) -target_link_libraries(gltf_view PUBLIC +target_link_libraries(viewer PUBLIC ${LINK_LIBRARIES}) # Texture viewer diff --git a/game/src/plugins/gltf_view.c b/game/src/plugins/gltf_view.c deleted file mode 100644 index 83fc8ed..0000000 --- a/game/src/plugins/gltf_view.c +++ /dev/null @@ -1,240 +0,0 @@ -#include "plugin.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -// Paths to various scene files. -static const char* BOX = "/assets/models/box.gltf"; -static const char* SUZANNE = "/assets/models/suzanne.gltf"; -static const char* SPONZA = - "/assets/glTF-Sample-Models/2.0/Sponza/glTF/Sponza.gltf"; -static const char* FLIGHT_HELMET = - "/assets/glTF-Sample-Models/2.0/FlightHelmet/glTF/FlightHelmet.gltf"; -static const char* DAMAGED_HELMET = - "/assets/glTF-Sample-Models/2.0/DamagedHelmet/glTF/DamagedHelmet.gltf"; -static const char* GIRL = - "/home/jeanne/Nextcloud/assets/models/girl/girl-with-ground.gltf"; - -#define DEFAULT_SCENE_FILE GIRL - -struct State { - Scene* scene; - SceneCamera* camera; -}; - -/// Load the skyquad texture. -static Texture* load_environment_map(RenderBackend* render_backend) { - return gfx_load_texture( - render_backend, - &(LoadTextureCmd){ - .origin = TextureFromFile, - .type = LoadCubemap, - .colour_space = sRGB, - .filtering = NearestFiltering, - .mipmaps = false, - .data.cubemap.filepaths = { - mstring_make("/assets/skybox/clouds1/clouds1_east.bmp"), - mstring_make("/assets/skybox/clouds1/clouds1_west.bmp"), - mstring_make("/assets/skybox/clouds1/clouds1_up.bmp"), - mstring_make("/assets/skybox/clouds1/clouds1_down.bmp"), - mstring_make("/assets/skybox/clouds1/clouds1_south.bmp"), - mstring_make("/assets/skybox/clouds1/clouds1_north.bmp")} - }); -} - -/// Load the skyquad and return the environment light node. -static SceneNode* load_skyquad(RenderBackend* render_backend, SceneNode* root) { - assert(render_backend); - assert(root); - - Texture* environment_map = load_environment_map(render_backend); - if (!environment_map) { - return 0; - } - - return gfx_setup_skyquad(render_backend, root, environment_map); -} - -/// Load the 3D scene. -static SceneNode* load_scene( - Game* game, State* state, const char* scene_filepath) { - assert(game); - assert(game->gfx); - assert(state); - assert(state->scene); - - SceneNode* root = gfx_get_scene_root(state->scene); - RenderBackend* render_backend = gfx_get_render_backend(game->gfx); - - Camera* camera = gfx_get_camera_camera(state->camera); - spatial3_set_position(&camera->spatial, vec3_make(0, 0, 2)); - - SceneNode* sky_light_node = load_skyquad(render_backend, root); - if (!sky_light_node) { - return 0; - } - - SceneNode* scene_node = gfx_load_scene( - game->gfx, sky_light_node, - &(LoadSceneCmd){.origin = SceneFromFile, .filepath = scene_filepath}); - if (!scene_node) { - return 0; - } - - gfx_log_node_hierarchy(root); - - return scene_node; -} - -bool init(Game* game, State** pp_state) { - assert(game); - - State* state = calloc(1, sizeof(State)); - if (!state) { - goto cleanup; - } - - if (!(state->scene = gfx_make_scene())) { - goto cleanup; - } - if (!(state->camera = gfx_make_camera())) { - goto cleanup; - } - - const int argc = game->argc; - const char** argv = game->argv; - - // Usage: - const char* scene_filepath = argc > 1 ? argv[1] : DEFAULT_SCENE_FILE; - - SceneNode* node = load_scene(game, state, scene_filepath); - if (!node) { - goto cleanup; - } - Anima* anima = gfx_get_node_anima(node); - gfx_play_animation( - anima, &(AnimationPlaySettings){.name = "Walk", .loop = true}); - - *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 update(Game* game, State* state, double t, double dt) { - assert(game); - assert(state); - assert(state->scene); - assert(state->camera); - - gfx_animate_scene(state->scene, (R)t); - - const vec3 orbit_point = vec3_make(0, 2, 0); - Camera* camera = gfx_get_camera_camera(state->camera); - spatial3_orbit( - &camera->spatial, orbit_point, - /*radius=*/2.5, - /*azimuth=*/t * 0.5, /*zenith=*/0); - spatial3_lookat(&camera->spatial, orbit_point); -} - -/// Render the bounding boxes of all scene objects. -static void render_bounding_boxes_rec(ImmRenderer* imm, const SceneNode* node) { - assert(imm); - assert(node); - if (gfx_get_node_type(node) == ObjectNode) { - // TODO: Look at the scene log. The JointNodes are detached from the - // ObjectNodes. This is why the boxes are not being transformed as expected - // here. Anima needs to animate boxes? Use OOBB in addition to AABB? - const mat4 model = gfx_get_node_global_transform(node); - const SceneObject* obj = gfx_get_node_object(node); - const aabb3 box = gfx_calc_object_aabb(obj); - gfx_imm_set_model_matrix(imm, &model); - gfx_imm_draw_aabb3(imm, box); - } - - // Render children's boxes. - for (NodeIter it = gfx_get_node_child(node); it; - it = gfx_get_next_child(it)) { - render_bounding_boxes_rec(imm, gfx_get_iter_node(it)); - } -} - -/// Render the bounding boxes of all scene objects. -static void render_bounding_boxes(const Game* game, const State* state) { - assert(game); - assert(state); - - RenderBackend* render_backend = gfx_get_render_backend(game->gfx); - ImmRenderer* imm = gfx_get_imm_renderer(game->gfx); - assert(render_backend); - assert(imm); - - gfx_set_blending(render_backend, true); - gfx_set_depth_mask(render_backend, false); - gfx_set_polygon_offset(render_backend, 0.5f, 0.5f); - - gfx_imm_start(imm); - gfx_imm_set_camera(imm, gfx_get_camera_camera(state->camera)); - gfx_imm_set_colour(imm, vec4_make(0.2, 0.2, 1.0, 0.3)); - render_bounding_boxes_rec(imm, gfx_get_scene_root(state->scene)); - gfx_imm_end(imm); - - gfx_set_polygon_offset(render_backend, 0.0f, 0.0f); - gfx_set_depth_mask(render_backend, true); - gfx_set_blending(render_backend, false); -} - -void render(const Game* game, const State* state) { - assert(state); - assert(game); - assert(game->gfx); - assert(state->scene); - assert(state->camera); - - Renderer* renderer = gfx_get_renderer(game->gfx); - assert(renderer); - - gfx_render_scene( - renderer, &(RenderSceneParams){ - .mode = RenderDefault, - .scene = state->scene, - .camera = state->camera}); - - render_bounding_boxes(game, state); -} - -void resize(Game* game, State* state, int width, int height) { - assert(game); - assert(state); - - 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; -} diff --git a/game/src/plugins/viewer.c b/game/src/plugins/viewer.c new file mode 100644 index 0000000..83fc8ed --- /dev/null +++ b/game/src/plugins/viewer.c @@ -0,0 +1,240 @@ +#include "plugin.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +// Paths to various scene files. +static const char* BOX = "/assets/models/box.gltf"; +static const char* SUZANNE = "/assets/models/suzanne.gltf"; +static const char* SPONZA = + "/assets/glTF-Sample-Models/2.0/Sponza/glTF/Sponza.gltf"; +static const char* FLIGHT_HELMET = + "/assets/glTF-Sample-Models/2.0/FlightHelmet/glTF/FlightHelmet.gltf"; +static const char* DAMAGED_HELMET = + "/assets/glTF-Sample-Models/2.0/DamagedHelmet/glTF/DamagedHelmet.gltf"; +static const char* GIRL = + "/home/jeanne/Nextcloud/assets/models/girl/girl-with-ground.gltf"; + +#define DEFAULT_SCENE_FILE GIRL + +struct State { + Scene* scene; + SceneCamera* camera; +}; + +/// Load the skyquad texture. +static Texture* load_environment_map(RenderBackend* render_backend) { + return gfx_load_texture( + render_backend, + &(LoadTextureCmd){ + .origin = TextureFromFile, + .type = LoadCubemap, + .colour_space = sRGB, + .filtering = NearestFiltering, + .mipmaps = false, + .data.cubemap.filepaths = { + mstring_make("/assets/skybox/clouds1/clouds1_east.bmp"), + mstring_make("/assets/skybox/clouds1/clouds1_west.bmp"), + mstring_make("/assets/skybox/clouds1/clouds1_up.bmp"), + mstring_make("/assets/skybox/clouds1/clouds1_down.bmp"), + mstring_make("/assets/skybox/clouds1/clouds1_south.bmp"), + mstring_make("/assets/skybox/clouds1/clouds1_north.bmp")} + }); +} + +/// Load the skyquad and return the environment light node. +static SceneNode* load_skyquad(RenderBackend* render_backend, SceneNode* root) { + assert(render_backend); + assert(root); + + Texture* environment_map = load_environment_map(render_backend); + if (!environment_map) { + return 0; + } + + return gfx_setup_skyquad(render_backend, root, environment_map); +} + +/// Load the 3D scene. +static SceneNode* load_scene( + Game* game, State* state, const char* scene_filepath) { + assert(game); + assert(game->gfx); + assert(state); + assert(state->scene); + + SceneNode* root = gfx_get_scene_root(state->scene); + RenderBackend* render_backend = gfx_get_render_backend(game->gfx); + + Camera* camera = gfx_get_camera_camera(state->camera); + spatial3_set_position(&camera->spatial, vec3_make(0, 0, 2)); + + SceneNode* sky_light_node = load_skyquad(render_backend, root); + if (!sky_light_node) { + return 0; + } + + SceneNode* scene_node = gfx_load_scene( + game->gfx, sky_light_node, + &(LoadSceneCmd){.origin = SceneFromFile, .filepath = scene_filepath}); + if (!scene_node) { + return 0; + } + + gfx_log_node_hierarchy(root); + + return scene_node; +} + +bool init(Game* game, State** pp_state) { + assert(game); + + State* state = calloc(1, sizeof(State)); + if (!state) { + goto cleanup; + } + + if (!(state->scene = gfx_make_scene())) { + goto cleanup; + } + if (!(state->camera = gfx_make_camera())) { + goto cleanup; + } + + const int argc = game->argc; + const char** argv = game->argv; + + // Usage: + const char* scene_filepath = argc > 1 ? argv[1] : DEFAULT_SCENE_FILE; + + SceneNode* node = load_scene(game, state, scene_filepath); + if (!node) { + goto cleanup; + } + Anima* anima = gfx_get_node_anima(node); + gfx_play_animation( + anima, &(AnimationPlaySettings){.name = "Walk", .loop = true}); + + *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 update(Game* game, State* state, double t, double dt) { + assert(game); + assert(state); + assert(state->scene); + assert(state->camera); + + gfx_animate_scene(state->scene, (R)t); + + const vec3 orbit_point = vec3_make(0, 2, 0); + Camera* camera = gfx_get_camera_camera(state->camera); + spatial3_orbit( + &camera->spatial, orbit_point, + /*radius=*/2.5, + /*azimuth=*/t * 0.5, /*zenith=*/0); + spatial3_lookat(&camera->spatial, orbit_point); +} + +/// Render the bounding boxes of all scene objects. +static void render_bounding_boxes_rec(ImmRenderer* imm, const SceneNode* node) { + assert(imm); + assert(node); + if (gfx_get_node_type(node) == ObjectNode) { + // TODO: Look at the scene log. The JointNodes are detached from the + // ObjectNodes. This is why the boxes are not being transformed as expected + // here. Anima needs to animate boxes? Use OOBB in addition to AABB? + const mat4 model = gfx_get_node_global_transform(node); + const SceneObject* obj = gfx_get_node_object(node); + const aabb3 box = gfx_calc_object_aabb(obj); + gfx_imm_set_model_matrix(imm, &model); + gfx_imm_draw_aabb3(imm, box); + } + + // Render children's boxes. + for (NodeIter it = gfx_get_node_child(node); it; + it = gfx_get_next_child(it)) { + render_bounding_boxes_rec(imm, gfx_get_iter_node(it)); + } +} + +/// Render the bounding boxes of all scene objects. +static void render_bounding_boxes(const Game* game, const State* state) { + assert(game); + assert(state); + + RenderBackend* render_backend = gfx_get_render_backend(game->gfx); + ImmRenderer* imm = gfx_get_imm_renderer(game->gfx); + assert(render_backend); + assert(imm); + + gfx_set_blending(render_backend, true); + gfx_set_depth_mask(render_backend, false); + gfx_set_polygon_offset(render_backend, 0.5f, 0.5f); + + gfx_imm_start(imm); + gfx_imm_set_camera(imm, gfx_get_camera_camera(state->camera)); + gfx_imm_set_colour(imm, vec4_make(0.2, 0.2, 1.0, 0.3)); + render_bounding_boxes_rec(imm, gfx_get_scene_root(state->scene)); + gfx_imm_end(imm); + + gfx_set_polygon_offset(render_backend, 0.0f, 0.0f); + gfx_set_depth_mask(render_backend, true); + gfx_set_blending(render_backend, false); +} + +void render(const Game* game, const State* state) { + assert(state); + assert(game); + assert(game->gfx); + assert(state->scene); + assert(state->camera); + + Renderer* renderer = gfx_get_renderer(game->gfx); + assert(renderer); + + gfx_render_scene( + renderer, &(RenderSceneParams){ + .mode = RenderDefault, + .scene = state->scene, + .camera = state->camera}); + + render_bounding_boxes(game, state); +} + +void resize(Game* game, State* state, int width, int height) { + assert(game); + assert(state); + + 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