Search code examples
javaopenglglslshaderlwjgl

GL_INVALID_OPERATION on Tesselation Shader


I'm using OpenGL with LWJGL and my own very small framework for trivial tasks. I'm following the book OpenGL SuperBible: Comprehensive Tutorial and Reference (6th Edition).

I will list the most important parts of my program:

public class GameController extends Controller {
    private Program test1Program;
    private int vaoId;

    @Override
    protected void init() {
        glViewport(0, 0, 800, 600);
        test1Program = new Program(
                new VertexShader("src/shaders/test.vert.glsl").create(),
                new ControlShader("src/shaders/test.cont.glsl").create(),
                new EvaluationShader("src/shaders/test.eval.glsl").create(),
                new FragmentShader("src/shaders/test.frag.glsl").create()
                ).create();
        vaoId = glGenVertexArrays();
        glBindVertexArray(vaoId);
    }

    @Override
    protected void draw(double msDelta) {
        glClearColor((float)Math.sin(currentTime / 1000f) * 0.5f + 0.5f, (float)Math.cos(currentTime / 1000f) * 0.5f + 0.5f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);        
        test1Program.use();
        glVertexAttrib4f(0, (float)Math.sin(currentTime / 1000f) * 0.5f, (float)Math.cos(currentTime / 1000f) * 0.5f, 0.0f, 0.0f);
        glVertexAttrib4f(1, (float)Math.sin(currentTime / 1000f * 2f) * 0.5f + 0.5f, (float)Math.cos(currentTime / 1000f * 2f) * 0.5f + 0.5f, 0.0f, 1.0f);
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }

    @Override
    protected void shutdown() {
        test1Program.delete();
        glDeleteVertexArrays(vaoId);
    }

    public static void main(String[] args) {
        Controller controller = new GameController();
        controller.start();
    }
}

My custom VertexShader, ControlShader, EvaluationShader and FragmentShader are working and if shader code does not compile properly or does not get linked correctly, then an exception will be thrown and I would notice it. So I have verified that those and Program are working correctly.

The error (Exception in thread "main" org.lwjgl.opengl.OpenGLException: Invalid operation (1282)) gets thrown at the glDrawArrays call.

test.vert.glsl:

#version 440 core

layout(location = 0) in vec4 offset;
layout(location = 1) in vec4 color;

out VS_OUT {
    vec4 color;
} vs_out;

void main() {
    const vec4 vertices[3] = vec4[3](
        vec4(0.25, -0.25, 0.5, 1.0),
        vec4(-0.25, -0.25, 0.5, 1.0),
        vec4(0.25, 0.25, 0.5, 1.0)
    );
    gl_Position = vertices[gl_VertexID] + offset;
    vs_out.color = color;
}

test.cont.glsl:

#version 440 core

layout(vertices = 3) out;

void main() {
    if (gl_InvocationID == 0) {
        gl_TessLevelInner[0] = 5.0;
        gl_TessLevelOuter[0] = 5.0;
        gl_TessLevelOuter[1] = 5.0;
        gl_TessLevelOuter[2] = 5.0;
    }
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
}

test.eval.glsl:

#version 440 core

layout(triangles, equal_spacing, cw) in;

void main() {
    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position);
}

#version 440 core

in VS_OUT {
    vec4 color;
} fs_in;

out vec4 color;

void main() {
    color = fs_in.color;
}

I have triple checked all my code and crosschecked with the book, but have no clue why it is not working. I would appreciate any help and am around to provide additional information if neccessary.


Solution

  • I found the answer just now:

        glDrawArrays(GL_TRIANGLES, 0, 3);
    

    needs to be:

        glDrawArrays(GL_PATCHES, 0, 3);
    

    Some more effort from OpenGL to show what was wrong would have been appreciated.

    Also nowhere in the book it has been (explicitely) mentioned that I need to use GL_PATCHES, I just figured it out by looking at the source code of the compilable examples from the book.