// scene_test.c - 场景图 + 网格渲染 #include "../Engine/Core/engine.h" #include "../Engine/Core/logger.h" #include "../Engine/Window/window.h" #include "../Engine/Rendering/graphics_device.h" #include "../Engine/Rendering/shader.h" #include "../Engine/Rendering/mesh.h" #include "../Engine/Scene/scene_graph.h" #include "../Engine/include/engine_api.h" #include "../Engine/ASM/math_c_fallback.h" static GraphicsDevice* g_dev = NULL; static Shader* g_shader = NULL; static Mesh* g_cube = NULL; static Mesh* g_plane = NULL; static Scene g_scene; static SceneNode* g_camera = NULL; static float g_time = 0; static void on_render(Engine* engine) { if (!g_dev) return; ID3D11DeviceContext* ctx = g_dev->context; scene_update(&g_scene); g_time += (float)engine->delta_time; float sw = (float)g_dev->width, sh = (float)g_dev->height; float fov = 1.0f / tanf(0.5f * 0.785f), aspect = sw / sh; Vec3 cam_pos; scene_get_world_position(g_camera, &cam_pos); // VP 矩阵 float proj[16] = {0}; proj[0] = fov / aspect; proj[5] = -fov; proj[10] = 1.0f; proj[11] = -1.0f; proj[14] = 0.1f; proj[15] = 1.0f; Vec3 eye = cam_pos, target = {0,0,0}, up = {0,1,0}; Vec3 f, r, u; vec3_sub(&target, &eye, &f); vec3_normalize(&f, &f); vec3_cross(&up, &f, &r); vec3_normalize(&r, &r); vec3_cross(&f, &r, &u); float view[16] = {0}; view[0]=r.x; view[1]=u.x; view[2]=-f.x; view[4]=r.y; view[5]=u.y; view[6]=-f.y; view[8]=r.z; view[9]=u.z; view[10]=-f.z; view[12]=-vec3_dot(&r,&eye); view[13]=-vec3_dot(&u,&eye); view[14]=vec3_dot(&f,&eye); view[15]=1.0f; float vp_raw[16] = {0}; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) vp_raw[i*4+j] = view[i*4+0]*proj[0*4+j]+view[i*4+1]*proj[1*4+j]+view[i*4+2]*proj[2*4+j]+view[i*4+3]*proj[3*4+j]; Mat4 vp_m, vp_t; memcpy(&vp_m, vp_raw, sizeof(Mat4)); mat4_transpose(&vp_m, &vp_t); graphics_device_clear(g_dev, 0.15f, 0.18f, 0.25f, 1.0f); D3D11_VIEWPORT vport = {0}; vport.Width = sw; vport.Height = sh; vport.MaxDepth = 1.0f; ctx->lpVtbl->RSSetViewports(ctx, 1, &vport); D3D11_RASTERIZER_DESC rdesc = {0}; rdesc.FillMode = D3D11_FILL_SOLID; rdesc.CullMode = D3D11_CULL_NONE; ID3D11RasterizerState* rstate = NULL; g_dev->device->lpVtbl->CreateRasterizerState(g_dev->device, &rdesc, &rstate); ctx->lpVtbl->RSSetState(ctx, rstate); ctx->lpVtbl->IASetPrimitiveTopology(ctx, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); shader_bind(g_shader, ctx); shader_set_matrix(g_shader, ctx, (float*)&vp_t); if (g_plane) mesh_draw(g_plane, ctx); for (int i = 0; i < g_scene.node_count; i++) { SceneNode* node = &g_scene.nodes[i]; if (!node->visible || node->id == 0 || node->user_type != 1 || !g_cube) continue; float wvp_raw[16] = {0}; for (int r2 = 0; r2 < 4; r2++) for (int c = 0; c < 4; c++) wvp_raw[r2*4+c] = view[r2*4+0]*node->world_matrix.m[0][c]+view[r2*4+1]*node->world_matrix.m[1][c]+view[r2*4+2]*node->world_matrix.m[2][c]+view[r2*4+3]*node->world_matrix.m[3][c]; Mat4 wvp_m, wvp_t; memcpy(&wvp_m, wvp_raw, sizeof(Mat4)); mat4_transpose(&wvp_m, &wvp_t); shader_set_matrix(g_shader, ctx, (float*)&wvp_t); mesh_draw(g_cube, ctx); } if (rstate) rstate->lpVtbl->Release(rstate); graphics_device_present(g_dev); } static void on_key(Engine* engine, int key) { if (key == VK_ESCAPE) engine_request_quit(engine); } int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR cmd, int nS) { (void)hI;(void)hP;(void)cmd;(void)nS; EngineConfig cfg = engine_default_config(); cfg.app_name = "lity3d Scene Test"; Engine* engine = engine_create(); if (!engine_init(engine, &cfg)) return -1; g_dev = graphics_device_create(); if (!graphics_device_init(g_dev, window_get_handle(engine->window), cfg.window_width, cfg.window_height, 1)) return -1; g_shader = shader_create(); shader_compile(g_shader, g_dev->device, NULL, NULL, 0, 0); g_cube = mesh_create_cube(g_dev->device); g_plane = mesh_create_plane(g_dev->device, 10.0f); scene_init(&g_scene); g_camera = scene_create_node(&g_scene, "Camera"); scene_set_position(g_camera, 5, 4, 8); SceneNode* c1 = scene_create_node(&g_scene, "Cube1"); scene_set_position(c1, 0, 0.5f, 0); c1->user_type = 1; SceneNode* c2 = scene_create_node(&g_scene, "Cube2"); scene_set_position(c2, -3, 0.5f, 2); c2->user_type = 1; SceneNode* c3 = scene_create_node(&g_scene, "Cube3"); scene_set_position(c3, 3, 0.5f, -2); c3->user_type = 1; scene_set_scale(c3, 0.5f, 0.5f, 0.5f); SceneNode* child = scene_create_node(&g_scene, "Child"); scene_set_position(child, 2, 0, 0); child->user_type = 1; scene_set_parent(child, c1); engine_set_render_callback(engine, on_render); engine_set_key_callback(engine, on_key); engine_run(engine); mesh_destroy(g_cube); mesh_destroy(g_plane); shader_destroy(g_shader); graphics_device_destroy(g_dev); engine_shutdown(engine); return 0; }