19

是否可以仅使用单个 绘制整个立方体GL_TRIANGLE_STRIP

显然这只是我在这里关心的立方体组合,它还可以延伸到任何类型的盒子或类似的物体中。

4

6 回答 6

25

来自Evans、Skiena 和 Varshney的论文Optimizing Triangle Strips for Fast Rendering :

三角带图

于 2016-08-09T16:23:09.700 回答
16

对于那些懒惰的人(像我一样),这是 rob mayoff 答案的复制粘贴版本;)

static const GLfloat cube_strip[] = {
    -1.f, 1.f, 1.f,     // Front-top-left
    1.f, 1.f, 1.f,      // Front-top-right
    -1.f, -1.f, 1.f,    // Front-bottom-left
    1.f, -1.f, 1.f,     // Front-bottom-right
    1.f, -1.f, -1.f,    // Back-bottom-right
    1.f, 1.f, 1.f,      // Front-top-right
    1.f, 1.f, -1.f,     // Back-top-right
    -1.f, 1.f, 1.f,     // Front-top-left
    -1.f, 1.f, -1.f,    // Back-top-left
    -1.f, -1.f, 1.f,    // Front-bottom-left
    -1.f, -1.f, -1.f,   // Back-bottom-left
    1.f, -1.f, -1.f,    // Back-bottom-right
    -1.f, 1.f, -1.f,    // Back-top-left
    1.f, 1.f, -1.f      // Back-top-right
};
于 2017-09-02T17:37:55.977 回答
7

是的,经过一番试验,我自己找到了答案。想象一下你的立方体的角落是黑白交替的。沿着两个黑角之间的每个面画一条三角形边。这样,对角线在立方体内部形成一个四面体。对于 [0,1]³ 立方体,可能的坐标序列如下:

Vertex  Triangle    Face
------+-----------+-----
0 0 0
0 1 0
1 0 0  000 010 100  **0
1 1 0  100 010 110  **0
1 1 1  100 110 111  1**
0 1 0  111 110 010  *1*
0 1 1  111 010 011  *1*
0 0 1  011 010 001  0**
1 1 1  011 001 111  **1
1 0 1  111 001 101  **1
1 0 0  111 101 100  1**
0 0 1  100 101 001  *0*
0 0 0  100 001 000  *0*
0 1 0  000 001 010  0**
于 2015-02-06T21:46:12.593 回答
3

可能对某些人有用,这是一个几何着色器,它将接收一个点并输出一个单位立方体的三角形条

#version 410

layout(points) in;
layout(triangle_strip, max_vertices = 12) out;

uniform mat4 mvp;

void main() {
    vec4 center = gl_in[0].gl_Position;

    vec4 dx = mvp[0];
    vec4 dy = mvp[1];
    vec4 dz = mvp[2];

    vec4 p1 = center;
    vec4 p2 = center + dx;
    vec4 p3 = center + dy;
    vec4 p4 = p2 + dy;
    vec4 p5 = p1 + dz;
    vec4 p6 = p2 + dz;
    vec4 p7 = p3 + dz;
    vec4 p8 = p4 + dz;

    gl_Position = p7;
    EmitVertex();

    gl_Position = p8;
    EmitVertex();

    gl_Position = p5;
    EmitVertex();

    gl_Position = p6;
    EmitVertex();

    gl_Position = p2;
    EmitVertex();

    gl_Position = p8;
    EmitVertex();

    gl_Position = p4;
    EmitVertex();

    gl_Position = p7;
    EmitVertex();

    gl_Position = p3;
    EmitVertex();

    gl_Position = p5;
    EmitVertex();

    gl_Position = p1;
    EmitVertex();

    gl_Position = p2;
    EmitVertex();

    gl_Position = p3;
    EmitVertex();

    gl_Position = p4;
    EmitVertex();

}
于 2019-03-13T07:37:25.310 回答
2

上面提到的纸有三角形缠绕在错误的方向,但是有一个简单的修正,颠倒顶点的顺序,它会变成正面向外(而不是向内)。

1 2 5 6 7 2 4 1 3 5 8 7 3 4

这是一个单位立方体的一组顶点。您可以对此应用转换并渲染边界框(轴对齐或定向)。

    static const std::array<float> cube_strip = {
        +0.5, +0.5, -0.5, // Back-top-right
        -0.5, +0.5, -0.5, // Back-top-left
        +0.5, -0.5, -0.5, // Back-bottom-right
        -0.5, -0.5, -0.5, // Back-bottom-left
        -0.5, -0.5, +0.5, // Front-bottom-left
        -0.5, +0.5, -0.5, // Back-top-left
        -0.5, +0.5, +0.5, // Front-top-left
        +0.5, +0.5, -0.5, // Back-top-right
        +0.5, +0.5, +0.5, // Front-top-right
        +0.5, -0.5, -0.5, // Back-bottom-right
        +0.5, -0.5, +0.5, // Front-bottom-right
        -0.5, -0.5, +0.5, // Front-bottom-left
        +0.5, +0.5, +0.5, // Front-top-right
        -0.5, +0.5, +0.5, // Front-top-left
    };
于 2021-12-03T19:26:53.330 回答
1

此版本还具有纹理坐标和法线,以防万一您需要它们。

我用 WebGL 对此进行了测试,立方体的纹理映射正确,但由于每个角确实需要三个纹理坐标 - 每个面一个,因此具有特殊性。因此,您可以使用这些 UV 对立方体的 4 个侧面进行纹理贴图,但顶部和底部不会有适当的纹理。

const Cube = function () {
    const u0 = 0;
    const u1 = 1;

    const v0 = 0;
    const v1 = 1 / 3;
    const v2 = 2 / 3;
    const v3 = 1;

    const verticies = [
        +1, +1, -1,
        -1, +1, -1,
        +1, -1, -1,
        -1, -1, -1,
        +1, +1, +1,
        -1, +1, +1,
        -1, -1, +1,
        +1, -1, +1,
    ];

    const uvs = [
        u0, v3,
        u0, v0,
        u0, v2,
        u0, v1,
        u1, v3,
        u1, v0,
        u1, v1,
        u1, v2,
    ];

    const indexes = [3, 2, 6, 7, 4, 2, 0, 3, 1, 6, 5, 4, 1, 0];

    const v = [];
    const u = [];
    for (var i = 0; i < indexes.length; i++) {
        const corner = indexes[i];
        v.push(verticies[corner * 3 + 0]);
        v.push(verticies[corner * 3 + 1]);
        v.push(verticies[corner * 3 + 2]);

        u.push(uvs[corner * 2 + 0]);
        u.push(uvs[corner * 2 + 1]);
    }

    return {
        verticies: v, 
        uvs: u,
        normals: v
    };
};
于 2021-03-19T03:58:53.893 回答