With OpenGL3+ and shader tricks, one can procedurally generate fullscreen quads or implicit surfaces. Here's another little trick I found to draw a unit sized cube with a single draw call (a triangle strip with 14 vertices) without any vertex or index buffers.
The idea is to use the gl_VertexID variable to extract the positions of the vertices.
Here are the shaders (which I now use to render my skyboxes)
Here are the shaders (which I now use to render my skyboxes)
Vertex Shader:
#version 330
uniform mat4 uModelViewProjection;
out vec3 vsTexCoord;
#define oTexCoord vsTexCoord
void main() {
// extract vertices
int r = int(gl_VertexID > 6);
int i = r==1 ? 13-gl_VertexID : gl_VertexID;
int x = int(i<3 || i==4);
int y = r ^ int(i>0 && i<4);
int z = r ^ int(i<2 || i>5);
// compute world pos and project
const float SKY_SIZE = 100.0;
oTexCoord = vec3(x,y,z)*2.0-1.0;
gl_Position = uModelViewProjection *
vec4(oTexCoord*SKY_SIZE,1);
}
Fragment shader (which is pretty standard):
#version 330
uniform samplerCube sSky;
in vec3 vsTexCoord;
#define iTexCoord vsTexCoord
layout(location=0) out vec4 oColour;
void main() {
oColour = texture(sSky, normalize(iTexCoord));
}
And the client code:
// init glBindVertexArray(emptyVertexArray); glBindVertexArray(0); // render glBindVertexArray(emptyVertexArray); glUseProgram(skyboxProgram); glDrawArrays(GL_TRIANGLE_STRIP, 0, 14);