Why is my rotating cube doesn't looks like rotating cube?
Do I need to move camera?
I don't have any idea what is wrong.
I am using glium
in rust
.
24 Vertices
const P: f32 = 0.5;
let vertex_buffer = glium::VertexBuffer::new(&display, &vec![
// front 0-3
Vertex { position: (-P, -P, 0.0) },
Vertex { position: (P, P, 0.0) },
Vertex { position: (P, -P, 0.0) },
Vertex { position: (-P, P, 0.0) },
// back 4-7
Vertex { position: (-P, -P, 1.0) },
Vertex { position: (P, P, 1.0) },
Vertex { position: (P, -P, 1.0) },
Vertex { position: (-P, P, 1.0) },
// up 8-11
Vertex { position: (-P, P, 0.0) },
Vertex { position: (P, P, 0.0) },
Vertex { position: (P, P, 1.0) },
Vertex { position: (-P, P, 1.0) },
// down 12-15
Vertex { position: (-P, -P, 0.0) },
Vertex { position: (P, -P, 0.0) },
Vertex { position: (P, -P, 1.0) },
Vertex { position: (-P, -P, 1.0) },
// right 16-19
Vertex { position: (P, -P, 0.0) },
Vertex { position: (P, -P, 1.0) },
Vertex { position: (P, P, 1.0) },
Vertex { position: (P, P, 0.0) },
// left 20-23
Vertex { position: (-P, -P, 0.0) },
Vertex { position: (-P, -P, 1.0) },
Vertex { position: (-P, P, 1.0) },
Vertex { position: (-P, P, 0.0) },
]
).unwrap();
Indices for generating 6 faces of cube(4 Vertices per face, 2 triangles per face):
let indices = glium::IndexBuffer::new(&display, glium::index::PrimitiveType::TrianglesList,
&[
// front
0, 2, 1,
0, 3, 1,
// back
4, 6, 5,
4, 7, 5,
// up
8, 9, 10,
8, 11, 10,
// down
12, 13, 14,
12, 15, 14,
// right
16, 17, 18,
16, 19, 18,
// left
20, 21, 22,
20, 23, 22u16,
]
).unwrap();
I am using Gouraud shading(from glium
tutorial) for lighting.
I find normals
for cube on the stackoverflow.
Normals
:
let normals = glium::VertexBuffer::new(&display, &vec![
// front
Normal { normal: (1.0, 0.0, 0.0) },
// back
Normal { normal: (0.0, -1.0, 0.0) },
// up
Normal { normal: (1.0, 0.0, -1.0) },
// down
Normal { normal: (0.0, 0.0, 1.0) },
// right
Normal { normal: (1.0, 0.0, 0.0) },
// left
Normal { normal: (-1.0, 0.0, 0.0) },
]
).unwrap();
Vertex shader(glsl
):
#version 150
in vec3 position;
in vec3 normal;
out vec3 v_normal;
uniform mat4 m;
void main() {
v_normal = transpose(inverse(mat3(m))) * normal;
gl_Position = m * vec4(position, 1.0);
}
Fragment shader(glsl
):
#version 150
in vec3 v_normal;
out vec4 color;
uniform vec3 u_light;
void main() {
float brightness = dot(normalize(v_normal), normalize(u_light));
vec3 dark_color = vec3(0.6, 0.0, 0.0);
vec3 regular_color = vec3(1.0, 0.0, 0.0);
color = vec4(mix(dark_color, regular_color, brightness), 1.0);
}
Rotating is done by 4x4 matrix:
let mut t: f32 = 0.0;
let mut s: f32 = 0.002;
// ... loop.run
t += s;
if t > 180.0 || t < -180.0 {
s = -s;
}
let m = [
[1.0, 0.0, 0.0, 0.0],
[0.0, t.cos(), -t.sin(), 0.0],
[0.0, t.sin(), t.cos(), 0.0],
[0.0, 0.0, 0.0, 1.0f32]
];
let light = [-1.0, -0.4, 0.9f32];
// params
target.draw((&vertex_buffer, &normals), &indices, &program, &uniform! { m: m, u_light: light }, ¶ms).unwrap();
target.finish().unwrap();
Any ideas whats wrong? I am sorry for so long Q. which has so much of code, but I don't know what's else than this I can provide.
Your rotation matrix is a rotation about the X axis, and you are applying no perspective projection matrix, so you get the implied default orthographic projection. Your pictures are more or less typical examples of what you get in that case, though with what might be further errors, perhaps in the vertex data (I'm noticing the visible diagonal line).
The vertices are being moved in circles about the X axis, in the YZ plane, and you can't see Z directly, so you just see them moving up and down in Y.
In order to get a picture that looks like a rotating cube, you will want to set up a perspective projection, and probably a camera position/rotation (view matrix) that is looking at the cube.
Or you could try changing your matrix to a matrix for rotation about the Z axis:
let m = [
[t.cos(), -t.sin(), 0.0, 0.0],
[t.sin(), t.cos(), 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0f32]
];
That will be visibly a rotation.
But in general, I highly recommend getting perspective projection in your program. This will reveal motion in the Z axis (currently invisible) and make the images make more intuitive sense to human vision. It is also useful to add more objects and more complex ones, making a more complete “scene” — then if you have code bugs, you can see how they're affecting all the geometry being displayed, rather than seeing only a very abstract bunch of rectangles as you have now.