Files
lity3d/Demo/main.c
T
shuiyu1123 0669d102ce feat: major engine overhaul - scene demo with lighting, sphere, ground
- Scene Demo: cube + sphere + ground plane with proper lighting
- Audio: XAudio2 dynamic loading + WAV playback
- Physics: expanded collision system
- Renderer: improved pipeline with materials
- UI: extended widget system
- VisualScript: enhanced serializer + block interactions
- ASM: optimized math/memory/profiling routines
- Window: mouse input + scroll support
2026-07-12 08:21:07 +08:00

225 lines
7.7 KiB
C

#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 <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
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 = "MiMo Engine - 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;
}