如何画旋转的立方体胶质?

问题描述 投票:0回答:1

为什么我的旋转立方体看起来不像旋转立方体? 我需要移动相机吗? 我不知道出了什么问题。 我在

glium
中使用
rust

24 个顶点

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();

生成立方体 6 个面的索引(每个面 4 个顶点,每个面 2 个三角形):

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();

我正在使用Gouraud shading(来自

glium
教程)进行照明。
我在 stackoverflow 上找到了
normals
的立方体。
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();

顶点着色器(

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);
}

片段着色器(

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);
}

旋转由4x4矩阵完成:

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 }, &params).unwrap();

target.finish().unwrap();

任何想法出了什么问题? 抱歉了这么久Q.代码太多了,但我不知道我还能提供什么。

我的“旋转立方体”有一些图片:

opengl rust graphics 3d glium
1个回答
2
投票

您的旋转矩阵是围绕 X 轴的旋转,并且您没有应用透视投影矩阵,因此您得到隐含的默认正交投影。你的照片或多或少是你在那种情况下得到的典型例子,尽管可能还有更多的错误,可能在顶点数据中(我注意到可见的对角线)。

顶点在 YZ 平面中绕 X 轴圆周移动,您无法直接看到 Z,所以您只能看到它们在 Y 中上下移动。

为了获得看起来像旋转立方体的图片,您需要设置透视投影,并且可能需要设置正在观察立方体的相机位置/旋转(视图矩阵)。

或者您可以尝试将矩阵更改为绕 Z 轴旋转的矩阵:

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]
];

这将是一个明显的轮换。

但总的来说,我强烈建议在你的程序中使用透视投影。这将揭示 Z 轴(目前不可见)的运动,并使图像对人类视觉更直观。添加更多对象和更复杂的对象,创建更完整的“场景”也很有用——然后如果您有代码错误,您可以看到它们如何影响 all 正在显示的几何体,而不是只看到一个非常你现在拥有的一堆抽象矩形。

© www.soinside.com 2019 - 2024. All rights reserved.