summaryrefslogtreecommitdiff
path: root/examples/cube.c
blob: 8fd85de7488ae1c1dd13b7b6ca0c15c8d9979409 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <celeritas.h>
#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;
}