#include #include "glfw3.h" camera cam; pipeline_handle draw_pipeline; buf_handle cube_vbuf; buf_handle transform_buf; tex_handle texture; // transformation data typedef struct MVPData { mat4 model; mat4 view; mat4 projection; } MVPData; // draw calls for a single frame void draw() { // prepare model data f32 angle_degrees = glfwGetTime() * 45.0; f32 angle = angle_degrees * PI / 180.0; // Move origin to cube center vec3 center_offset = vec3(0.5, 0.5, 0.5); mat4 to_center = mat4_translation(vec3_negate(center_offset)); mat4 from_center = mat4_translation(center_offset); // Create rotation around Y axis mat4 rotation = mat4_rotation(quat_from_axis_angle(VEC3_Y, angle, true)); // Print debug info for one frame static bool printed = false; if (!printed) { printf("\nTo Center:\n"); for (int i = 0; i < 16; i += 4) { printf("%f %f %f %f\n", to_center.data[i], to_center.data[i + 1], to_center.data[i + 2], to_center.data[i + 3]); } printed = true; } // Order: first move to center, then rotate, then move back mat4 cube_transform = mat4_mult(from_center, mat4_mult(rotation, to_center)); mat4 move = mat4_translation(vec3(-0.5, -0.5, 0)); cube_transform = mat4_mult(move, cube_transform); // prepare camera data mat4 view, proj; camera_view_proj(cam, 800, 600, &view, &proj); render_pass_desc d = {}; gpu_encoder* enc = ral_render_encoder(d); ral_encode_bind_pipeline(enc, draw_pipeline); ral_set_default_settings(enc); MVPData mvp = { .model = cube_transform, .view = view, .projection = proj }; ral_buffer_upload_data(transform_buf, sizeof(MVPData), &mvp); ral_bind_buffer(enc, transform_buf, 1); // bind the transform data buffer to binding 1 ral_encode_set_vertex_buf(enc, cube_vbuf); ral_encode_set_texture(enc, texture, 0); ral_encode_draw_tris(enc, 0, 36); ral_encoder_finish_and_submit(enc); } void test_matrix_mult() { // Create a simple translation matrix (1 unit in x) mat4 trans1 = mat4_translation(vec3(1, 0, 0)); // Create another translation matrix (1 unit in y) mat4 trans2 = mat4_translation(vec3(0, 1, 0)); printf("Matrix 1 (translate x+1):\n"); for (int i = 0; i < 16; i += 4) { printf("%f %f %f %f\n", trans1.data[i], trans1.data[i + 1], trans1.data[i + 2], trans1.data[i + 3]); } printf("\nMatrix 2 (translate y+1):\n"); for (int i = 0; i < 16; i += 4) { printf("%f %f %f %f\n", trans2.data[i], trans2.data[i + 1], trans2.data[i + 2], trans2.data[i + 3]); } mat4 result = mat4_mult(trans1, trans2); printf("\nResult matrix:\n"); for (int i = 0; i < 16; i += 4) { printf("%f %f %f %f\n", result.data[i], result.data[i + 1], result.data[i + 2], result.data[i + 3]); } } int main() { test_matrix_mult(); // exit(1); core_bringup("Celeritas Example: Triangle", NULL); // create rendering pipeline gfx_pipeline_desc pipeline_desc = { .label = "Textured cube pipeline", .vertex_desc = static_3d_vertex_format(), .vertex = { .source = NULL, .is_spirv = false, .entry_point = "cubeVertexShader", .stage = STAGE_VERTEX, }, .fragment = { .source = NULL, .is_spirv = false, .entry_point = "fragmentShader", .stage = STAGE_FRAGMENT, }, }; draw_pipeline = ral_gfx_pipeline_create(pipeline_desc); // load texture from file texture = ral_texture_load_from_file("assets/textures/mc_grass.jpeg"); cam = (camera){ .position = vec3(0, 3, 5), .forwards = vec3(0, -3, -5), .fov = 45.0, .up = VEC3_Y }; // create the cube geometry geometry cube = geo_cuboid(1.0, 1.0, 1.0); // (debug) print out each vertex size_t vertex_stride = cube.data_length / cube.n_vertices; printf("Vertex stride %ld\n", vertex_stride); for (int i = 0; i < cube.n_vertices; i++) { static_3d_vert* vertex = (static_3d_vert*)(cube.vertex_data + vertex_stride * i); print_static_3d_vert(vertex); } // upload vertex data to the gpu cube_vbuf = ral_buffer_create(64 * 36, cube.vertex_data); // create a buffer to hold the MVP transforms MVPData d = {}; transform_buf = ral_buffer_create(sizeof(MVPData), &d); while (!app_should_exit()) { glfwPollEvents(); ral_frame_start(); ral_frame_draw(&draw); ral_frame_end(); } return 0; }