#include "../Engine/Core/engine.h" #include "../Engine/Core/logger.h" #include "../Engine/Core/timer.h" #include "../Engine/Core/asset_manager.h" #include "../Engine/Rendering/graphics_device.h" #include "../Engine/Rendering/renderer.h" #include "../Engine/Rendering/shader.h" #include "../Engine/Rendering/mesh.h" #include "../Engine/Rendering/material.h" #include "../Engine/Rendering/texture.h" #include "../Engine/Rendering/camera.h" #include "../Engine/Scene/scene_graph.h" #include "../Engine/Scene/scene_render.h" #include "../Engine/Scene/scene_serialize.h" #include "../Engine/include/engine_api.h" #include "../Engine/ASM/math_c_fallback.h" #include #include #include #include static Scene* g_scene = NULL; static AssetManager* g_assets = NULL; static Asset* g_shader_asset = NULL; static Camera g_camera; static int g_mouse_down[3] = {0}; static int g_last_mouse_x = 0, g_last_mouse_y = 0; static int g_mouse_first = 1; static SceneNode* create_primitive_node(Scene* scene, SceneNode* parent, AssetManager* am, ID3D11Device* dev, const char* name, MeshType type, Vec3 pos, Vec3 rot, Vec3 scale, Material* material) { SceneNode* node = scene_create_node(scene, name); if (!node) return NULL; if (parent) scene_set_parent(node, parent); node->position = pos; node->scale = scale; quat_from_euler(rot.x, rot.y, rot.z, &node->rotation); Asset* mesh_asset = asset_manager_load_mesh(am, dev, name); if (!mesh_asset) { const char* builtin = NULL; if (type == MESH_CUBE) builtin = "cube"; else if (type == MESH_SPHERE) builtin = "sphere"; else if (type == MESH_PLANE) builtin = "plane"; if (builtin) mesh_asset = asset_manager_load_mesh(am, dev, builtin); } if (mesh_asset && material) { MeshRenderer* mr = mesh_renderer_create(type, (Mesh*)asset_data(mesh_asset), material); scene_node_set_mesh_renderer(node, mr); } return node; } static Scene* create_default_scene(AssetManager* am, ID3D11Device* dev) { Scene* scene = (Scene*)malloc(sizeof(Scene)); if (!scene) return NULL; scene_init(scene); SceneNode* root = scene->root; root->name[0] = '\0'; strncpy(root->name, "root", sizeof(root->name) - 1); Shader* shader = (Shader*)asset_data(g_shader_asset); Material* mat_red = material_create(shader, NULL); mat_red->color = (Vec4){1.0f, 0.3f, 0.2f, 1.0f}; Material* mat_blue = material_create(shader, NULL); mat_blue->color = (Vec4){0.2f, 0.5f, 1.0f, 1.0f}; Material* mat_ground = material_create(shader, NULL); mat_ground->color = (Vec4){0.3f, 0.3f, 0.35f, 1.0f}; // 中心红色立方体 create_primitive_node(scene, root, am, dev, "cube", MESH_CUBE, (Vec3){0, 0, 0}, (Vec3){0, 0, 0}, (Vec3){1, 1, 1}, mat_red); // 右侧蓝色球体 create_primitive_node(scene, root, am, dev, "sphere", MESH_SPHERE, (Vec3){2.0f, 0, 0}, (Vec3){0, 0, 0}, (Vec3){0.8f, 0.8f, 0.8f}, mat_blue); // 下方地面 create_primitive_node(scene, root, am, dev, "ground", MESH_PLANE, (Vec3){0, -1.0f, 0}, (Vec3){0, 0, 0}, (Vec3){1, 1, 1}, mat_ground); scene_update(scene); return scene; } static void on_render(Engine* engine) { Renderer* r = engine_get_renderer(engine); GraphicsDevice* dev = engine_get_graphics_device(engine); if (!r || !dev || !g_scene) return; renderer_set_view(r, camera_get_view(&g_camera)); renderer_set_projection(r, camera_get_projection(&g_camera)); renderer_begin_frame(r); scene_update(g_scene); scene_render(g_scene, r); renderer_end_frame(r); if (engine->frame_count == 60) { graphics_device_save_screenshot(dev, "screenshot1.bmp"); } if (engine->frame_count == 180) { graphics_device_save_screenshot(dev, "screenshot2.bmp"); } } static void on_update(Engine* engine, double dt) { (void)engine; (void)dt; } static void on_key(Engine* engine, int key) { if (key == VK_ESCAPE) engine_request_quit(engine); if (key == 'W' || key == 'w') camera_move_forward(&g_camera, 0.5f); if (key == 'S' || key == 's') camera_move_forward(&g_camera, -0.5f); if (key == 'A' || key == 'a') camera_move_right(&g_camera, -0.5f); if (key == 'D' || key == 'd') camera_move_right(&g_camera, 0.5f); if (key == VK_LEFT) camera_rotate_yaw(&g_camera, -0.1f); if (key == VK_RIGHT) camera_rotate_yaw(&g_camera, 0.1f); if (key == VK_UP) camera_rotate_pitch(&g_camera, -0.1f); if (key == VK_DOWN) camera_rotate_pitch(&g_camera, 0.1f); } static void on_mouse_move(Engine* engine, int x, int y) { (void)engine; if (g_mouse_down[0]) { if (g_mouse_first) { g_last_mouse_x = x; g_last_mouse_y = y; g_mouse_first = 0; } else { float dx = (float)(x - g_last_mouse_x); float dy = (float)(y - g_last_mouse_y); camera_rotate_yaw(&g_camera, dx * 0.005f); camera_rotate_pitch(&g_camera, dy * 0.005f); g_last_mouse_x = x; g_last_mouse_y = y; } } else { g_mouse_first = 1; } } static void on_mouse_button(Engine* engine, int button, int pressed) { (void)engine; if (button >= 0 && button < 3) g_mouse_down[button] = pressed; } static void on_resize(Engine* engine, int width, int height) { Renderer* r = engine_get_renderer(engine); if (r && width > 0 && height > 0) { renderer_resize(r, width, height); g_camera.aspect = (float)width / (float)height; g_camera.dirty = 1; } } int main(int argc, char* argv[]) { (void)argc; (void)argv; EngineConfig config = engine_default_config(); config.app_name = "Lity3D - Scene Demo"; config.vsync = 0; config.window_width = 1280; config.window_height = 720; Engine* engine = engine_create(); if (!engine_init(engine, &config)) { LOG_FATAL("Engine init failed"); return -1; } GraphicsDevice* dev = engine_get_graphics_device(engine); Renderer* r = engine_get_renderer(engine); g_assets = asset_manager_create(); g_shader_asset = asset_manager_load_shader(g_assets, dev->device, NULL, NULL); if (!g_shader_asset) { LOG_FATAL("Shader load failed"); return -1; } LOG_INFO("Shader loaded via AssetManager"); Shader* default_shader = (Shader*)asset_data(g_shader_asset); g_scene = scene_load("scene.txt", dev->device, default_shader); if (!g_scene) { LOG_INFO("No scene.txt found, creating default scene"); g_scene = create_default_scene(g_assets, dev->device); if (!scene_save(g_scene, "scene.txt")) { LOG_WARN("Failed to save scene.txt"); } } float aspect = (float)config.window_width / config.window_height; g_camera = camera_perspective(1.0472f, aspect, 0.1f, 100.0f); g_camera.position = (Vec3){0, 0.5f, -5.0f}; g_camera.target = (Vec3){0, 0, 0}; g_camera.dirty = 1; renderer_set_view(r, camera_get_view(&g_camera)); renderer_set_projection(r, camera_get_projection(&g_camera)); engine_set_update_callback(engine, on_update); engine_set_render_callback(engine, on_render); engine_set_key_callback(engine, on_key); engine_set_mouse_move_callback(engine, on_mouse_move); engine_set_mouse_button_callback(engine, on_mouse_button); engine_set_resize_callback(engine, on_resize); LOG_INFO("Running scene demo..."); engine_run(engine); scene_destroy_renderers(g_scene); scene_destroy(g_scene); free(g_scene); asset_manager_destroy(g_assets); engine_shutdown(engine); return 0; }