openglglslgeometry-shadergl-triangle-strip

EmitVertex gives "error C1067: too little data in type constructor"


I am using geometry shaders to generate cubes from GL_POINTS

#version 150 core

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

in vec3 g_col[];

out vec3 f_col;

uniform mat4 transform;

void main()
{
    f_col = g_col[0];

    float s = gl_in[0].gl_PointSize * 0.5;

    vec4 c = gl_in[0].gl_Position;

    // Bottom

    gl_Position = transform * (c + vec4 (-s, -s, -s, 0));
    EmitVertex();

    gl_Position = transform * (c + vec4 (+s, -s, -s, 0));
    EmitVertex();

    gl_Position = transform * (c + vec4 (-s, +s, -s, 0));
    EmitVertex();

    gl_Position = transform * (c + vec4 (+s, +s, -s, 0));
    EmitVertex();

    // Far

    gl_Position = transform * (c + vec4 (-s, +s, +s, 0));
    EmitVertex();

    gl_Position = transform * (c + vec4 (+s, +s, +s, 0));
    EmitVertex();

    // Top

    gl_Position = transform * (c + vec4 (-s, -s, +s, 0));
    EmitVertex();

    gl_Position = transform * (c + vec4 (+s, -s, +s, 0));
    EmitVertex();

    // Near

    gl_Position = transform * (c + vec4 (-s, -s, -s, 0));
    EmitVertex();

    gl_Position = transform * (c + vec4 (+s, -s, -s, 0));
    EmitVertex();

    EndPrimitive();

    // Left

    gl_Position = transform * (c + vec4 (-s, -s, -s));
    EmitVertex ();

    gl_Position = transform * (c + vec4 (-s, +s, -s));
    EmitVertex ();

    gl_Position = transform * (c + vec4 (-s, -s, +s));
    EmitVertex ();

    gl_Position = transform * (c + vec4 (-s, +s, +s));
    EmitVertex ();

    EndPrimitive ();
}

If I delete the code after the first EndPrimitive (before the // Left comment), this correctly draws a strip around a cube, leaving the sides uncapped.

If I try to draw a new triangle strip to cap the side, I get this error for each of the four subsequent EmitVertex calls:

error C1067: too little data in type constructor

According to this documentation

The GS defines what kind of primitive these vertex outputs represent. The GS can also end a primitive and start a new one, by calling the EndPrimitive() function. This does not emit a vertex.

In order to write two independent triangles from a GS, you must write three separate vertices with EmitVertex() for the first three vertices, then call EndPrimitive() to end the strip and start a new one. Then you write three more vertices with EmitVertex().

What am I doing wrong?


Solution

  • In the working part:

    gl_Position = transform * (c + vec4 (+s, -s, -s, 0));
    

    In the non-working part:

    gl_Position = transform * (c + vec4 (-s, -s, -s));
    

    A vec4 constructor needs four components, just as the error message tells you.