Is it possible to draw a whole cube using just a single GL_TRIANGLE_STRIP
?
Obviously it\'s just the cube combinatorics I\'m concerned about here, it might a
From the paper Optimizing Triangle Strips for Fast Rendering by Evans, Skiena, and Varshney:
Yes, after a bit of experimenting I found the answer myself. Imagine the corners of your cube are colored alternatingly black and white. Draw a triangle edge along each face between the two black corners. That way, the diagonals form a tetrahedron inside the cube. For the [0,1]³ cube, a possible sequence of coordinates would be the following:
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**
May be useful to some, here's a geometry shader that will take in a point and output a triangle strip of a unit cube
#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();
}
For those of you who are lazy (like me), here's a copy-paste version of rob mayoff's answer ;)
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
};