Files
lity3d/Demo/scene_test.c
T

122 lines
5.0 KiB
C

// 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;
}