From c3c36d8517cb8fe764c0e45df669b7de2de586c1 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Tue, 10 Jun 2025 18:31:36 +0200 Subject: [PATCH] demos: Introduce a helper function to create a projection matrix. --- demos/demo.h | 38 ++++++++++++++++++++++++++++++++++++++ demos/gears.c | 46 +++++++++++++--------------------------------- 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/demos/demo.h b/demos/demo.h index 2d5aae33a..765a3c0e3 100644 --- a/demos/demo.h +++ b/demos/demo.h @@ -98,6 +98,11 @@ struct demo_vec4 float x, y, z, w; }; +struct demo_matrix +{ + float m[4][4]; +}; + struct demo_swapchain_desc { unsigned int width; @@ -123,6 +128,39 @@ static inline void demo_vec4_set(struct demo_vec4 *v, float x, float y, float z, v->w = w; } +static inline void demo_matrix_multiply(struct demo_matrix *out, + const struct demo_matrix *a, const struct demo_matrix *b) +{ + unsigned int i, j; + + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + out->m[i][j] = a->m[i][0] * b->m[0][j] + + a->m[i][1] * b->m[1][j] + + a->m[i][2] * b->m[2][j] + + a->m[i][3] * b->m[3][j]; + } + } +} + +static inline void demo_matrix_perspective_rh(struct demo_matrix *m, float w, float h, float z_near, float z_far) +{ + float sx = 2.0 * z_near / w; + float sy = 2.0 * z_near / h; + float sz = z_far / (z_near - z_far); + float d = z_near * sz; + + *m = (struct demo_matrix) + {{ + { sx, 0.0f, 0.0f, 0.0f}, + {0.0f, sy, 0.0f, 0.0f}, + {0.0f, 0.0f, sz, -1.0f}, + {0.0f, 0.0f, d, 0.0f}, + }}; +} + static inline void demo_rasterizer_desc_init_default(D3D12_RASTERIZER_DESC *desc) { desc->FillMode = D3D12_FILL_MODE_SOLID; diff --git a/demos/gears.c b/demos/gears.c index a372be3da..f7f82f4c9 100644 --- a/demos/gears.c +++ b/demos/gears.c @@ -59,7 +59,7 @@ struct cxg_fence struct cxg_cb_data { - float mvp_matrix[16]; + struct demo_matrix mvp_matrix; float normal_matrix[12]; }; @@ -230,44 +230,24 @@ static void cxg_wait_for_previous_frame(struct cx_gears *cxg) static void cxg_update_mvp(struct cx_gears *cxg) { + struct demo_matrix projection, world; float s1 = sinf(cxg->theta); float c1 = cosf(cxg->theta); float s2 = sinf(cxg->phi); float c2 = cosf(cxg->phi); float z_offset = -40.0f; - float z_max = 60.0f; - float z_min = 5.0f; - float sx = z_min; - float sy = z_min * cxg->aspect_ratio; - float sz = -((z_max + z_min) / (z_max - z_min)); - float d = (-2.0f * z_max * z_min) / (z_max - z_min); - unsigned int i, j; - float world[] = - { - c1, s2 * s1, c2 * -s1, 0.0f, - 0.0f, c2, s2, 0.0f, - s1, -s2 * c1, c2 * c1, 0.0f, - 0.0f, 0.0f, z_offset, 1.0f, - }; - float projection[] = - { - sx, 0.0f, 0.0f, 0.0f, - 0.0f, sy, 0.0f, 0.0f, - 0.0f, 0.0f, sz, -1.0f, - 0.0f, 0.0f, d, 0.0f, - }; - for (i = 0; i < 4; ++i) - { - for (j = 0; j < 4; ++j) - { - cxg->cb_data->mvp_matrix[i * 4 + j] = projection[j] * world[i * 4] - + projection[j + 4] * world[i * 4 + 1] - + projection[j + 8] * world[i * 4 + 2] - + projection[j + 12] * world[i * 4 + 3]; - } - } - memcpy(cxg->cb_data->normal_matrix, world, sizeof(cxg->cb_data->normal_matrix)); + world = (struct demo_matrix) + {{ + { c1, s2 * s1, c2 * -s1, 0.0f}, + {0.0f, c2, s2, 0.0f}, + { s1, -s2 * c1, c2 * c1, 0.0f}, + {0.0f, 0.0f, z_offset, 1.0f}, + }}; + demo_matrix_perspective_rh(&projection, 2.0f, 2.0f / cxg->aspect_ratio, 5.0f, 60.0f); + + demo_matrix_multiply(&cxg->cb_data->mvp_matrix, &world, &projection); + memcpy(cxg->cb_data->normal_matrix, &world, sizeof(cxg->cb_data->normal_matrix)); } static void cxg_render_frame(struct cx_gears *cxg)