Draw a cube

Description

We're building a world out of cubes, so let's try to render a cube. Our triangle had 3 vertices, and we can make a square from two triangles. Six squares make a cube, so we'll need:

3 vertices/triangles * 2 triangles/square * 6 squares/cube = 36 vertices/cube

Again, we'll hard-code the vertices right into the shader source. The cube's bottom left corner on the near side will start at the origin (0, 0, 0) and the far side top-right corner will end at (1, 1, 1). It doesn't matter yet, but we'll assume that the Z values increase further into the screen.

When defining the vertices for the two triangles on each face of the cube, we'll move in counter-clockwise order. This is called the winding order and will be important if we use [face culling] at a later stage. Choosing clockwise or counter-clockwise doesn't really matter as long as it's consistent, but counter-clockwise is the default of glFrontFace so we'll stick with that.

Even though we're rendering all six sides of the cube, we can only see the front side from the current view.

Screenshot

Commands

git clone git@github.com:atsheehan/iridium
cd iridium
git checkout a770d811367553d973759ac3b4f679d785763877
cargo run --release

Code Changes

Modified shaders/cube.vertGitHub

@@ -1,10 +1,69 @@
11 #version 150
22
33 void main() {
4- vec2 vertices[3];
5- vertices[0] = vec2(-0.5, -0.5);
6- vertices[1] = vec2(0.5, -0.5);
7- vertices[2] = vec2(0.0, 0.5);
4+ vec3 near_bottom_left = vec3(0.0, 0.0, 0.0);
5+ vec3 near_bottom_right = vec3(1.0, 0.0, 0.0);
6+ vec3 near_top_left = vec3(0.0, 1.0, 0.0);
7+ vec3 near_top_right = vec3(1.0, 1.0, 0.0);
8+ vec3 far_bottom_left = vec3(0.0, 0.0, 1.0);
9+ vec3 far_bottom_right = vec3(1.0, 0.0, 1.0);
10+ vec3 far_top_left = vec3(0.0, 1.0, 1.0);
11+ vec3 far_top_right = vec3(1.0, 1.0, 1.0);
812
9- gl_Position = vec4(vertices[gl_VertexID], 0.0, 1.0);
13+ vec3 vertices[36];
14+ // Front side
15+ vertices[0] = near_bottom_left;
16+ vertices[1] = near_bottom_right;
17+ vertices[2] = near_top_right;
18+
19+ vertices[3] = near_top_right;
20+ vertices[4] = near_top_left;
21+ vertices[5] = near_bottom_left;
22+
23+ // Right side
24+ vertices[6] = near_bottom_right;
25+ vertices[7] = far_bottom_right;
26+ vertices[8] = far_top_right;
27+
28+ vertices[9] = far_top_right;
29+ vertices[10] = near_top_right;
30+ vertices[11] = near_bottom_right;
31+
32+ // Far side
33+ vertices[12] = far_bottom_right;
34+ vertices[13] = far_bottom_left;
35+ vertices[14] = far_top_left;
36+
37+ vertices[15] = far_top_left;
38+ vertices[16] = far_top_right;
39+ vertices[17] = far_bottom_right;
40+
41+ // Left side
42+ vertices[18] = far_bottom_left;
43+ vertices[19] = near_bottom_left;
44+ vertices[20] = near_top_left;
45+
46+ vertices[21] = near_top_left;
47+ vertices[22] = far_top_left;
48+ vertices[23] = far_bottom_left;
49+
50+ // Top side
51+ vertices[24] = near_top_left;
52+ vertices[25] = near_top_right;
53+ vertices[26] = far_top_right;
54+
55+ vertices[27] = far_top_right;
56+ vertices[28] = far_top_left;
57+ vertices[29] = near_top_left;
58+
59+ // Bottom side
60+ vertices[30] = far_bottom_left;
61+ vertices[31] = far_bottom_right;
62+ vertices[32] = near_bottom_right;
63+
64+ vertices[33] = near_bottom_right;
65+ vertices[34] = near_bottom_left;
66+ vertices[35] = far_bottom_left;
67+
68+ gl_Position = vec4(vertices[gl_VertexID], 1.0);
1069 }
@@ -1,10 +1,69 @@
1 #version 150
2
3 void main() {
4- vec2 vertices[3];
5- vertices[0] = vec2(-0.5, -0.5);
6- vertices[1] = vec2(0.5, -0.5);
7- vertices[2] = vec2(0.0, 0.5);
 
 
 
 
8
9- gl_Position = vec4(vertices[gl_VertexID], 0.0, 1.0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10 }
@@ -1,10 +1,69 @@
1 #version 150
2
3 void main() {
4+ vec3 near_bottom_left = vec3(0.0, 0.0, 0.0);
5+ vec3 near_bottom_right = vec3(1.0, 0.0, 0.0);
6+ vec3 near_top_left = vec3(0.0, 1.0, 0.0);
7+ vec3 near_top_right = vec3(1.0, 1.0, 0.0);
8+ vec3 far_bottom_left = vec3(0.0, 0.0, 1.0);
9+ vec3 far_bottom_right = vec3(1.0, 0.0, 1.0);
10+ vec3 far_top_left = vec3(0.0, 1.0, 1.0);
11+ vec3 far_top_right = vec3(1.0, 1.0, 1.0);
12
13+ vec3 vertices[36];
14+ // Front side
15+ vertices[0] = near_bottom_left;
16+ vertices[1] = near_bottom_right;
17+ vertices[2] = near_top_right;
18+
19+ vertices[3] = near_top_right;
20+ vertices[4] = near_top_left;
21+ vertices[5] = near_bottom_left;
22+
23+ // Right side
24+ vertices[6] = near_bottom_right;
25+ vertices[7] = far_bottom_right;
26+ vertices[8] = far_top_right;
27+
28+ vertices[9] = far_top_right;
29+ vertices[10] = near_top_right;
30+ vertices[11] = near_bottom_right;
31+
32+ // Far side
33+ vertices[12] = far_bottom_right;
34+ vertices[13] = far_bottom_left;
35+ vertices[14] = far_top_left;
36+
37+ vertices[15] = far_top_left;
38+ vertices[16] = far_top_right;
39+ vertices[17] = far_bottom_right;
40+
41+ // Left side
42+ vertices[18] = far_bottom_left;
43+ vertices[19] = near_bottom_left;
44+ vertices[20] = near_top_left;
45+
46+ vertices[21] = near_top_left;
47+ vertices[22] = far_top_left;
48+ vertices[23] = far_bottom_left;
49+
50+ // Top side
51+ vertices[24] = near_top_left;
52+ vertices[25] = near_top_right;
53+ vertices[26] = far_top_right;
54+
55+ vertices[27] = far_top_right;
56+ vertices[28] = far_top_left;
57+ vertices[29] = near_top_left;
58+
59+ // Bottom side
60+ vertices[30] = far_bottom_left;
61+ vertices[31] = far_bottom_right;
62+ vertices[32] = near_bottom_right;
63+
64+ vertices[33] = near_bottom_right;
65+ vertices[34] = near_bottom_left;
66+ vertices[35] = far_bottom_left;
67+
68+ gl_Position = vec4(vertices[gl_VertexID], 1.0);
69 }

Modified src/main.rsGitHub

@@ -23,7 +23,7 @@
2323 window_id,
2424 } if window_id == renderer.window_id() => {
2525 renderer.clear();
26- renderer.draw_triangle();
26+ renderer.draw_cube();
2727 renderer.present();
2828 }
2929 _ => (),
@@ -23,7 +23,7 @@
23 window_id,
24 } if window_id == renderer.window_id() => {
25 renderer.clear();
26- renderer.draw_triangle();
27 renderer.present();
28 }
29 _ => (),
@@ -23,7 +23,7 @@
23 window_id,
24 } if window_id == renderer.window_id() => {
25 renderer.clear();
26+ renderer.draw_cube();
27 renderer.present();
28 }
29 _ => (),

Modified src/render.rsGitHub

@@ -99,11 +99,11 @@
9999 }
100100 }
101101
102- pub(crate) fn draw_triangle(&mut self) {
102+ pub(crate) fn draw_cube(&mut self) {
103103 unsafe {
104104 gl::UseProgram(self.cube_program.gl_id());
105105 gl::BindVertexArray(self.cube_vertex_array_id);
106- gl::DrawArrays(gl::TRIANGLES, 0, 3);
106+ gl::DrawArrays(gl::TRIANGLES, 0, 36);
107107 }
108108 }
109109
@@ -99,11 +99,11 @@
99 }
100 }
101
102- pub(crate) fn draw_triangle(&mut self) {
103 unsafe {
104 gl::UseProgram(self.cube_program.gl_id());
105 gl::BindVertexArray(self.cube_vertex_array_id);
106- gl::DrawArrays(gl::TRIANGLES, 0, 3);
107 }
108 }
109
@@ -99,11 +99,11 @@
99 }
100 }
101
102+ pub(crate) fn draw_cube(&mut self) {
103 unsafe {
104 gl::UseProgram(self.cube_program.gl_id());
105 gl::BindVertexArray(self.cube_vertex_array_id);
106+ gl::DrawArrays(gl::TRIANGLES, 0, 36);
107 }
108 }
109