0
votes

I've just started out learning modern OpenGL and i have trouble getting a triangle rendered. When i start the program it gives a Invalid Operation exception when i try to call glDrawArrays. By the looks of the console log the shader is setup without errors and the program is validated. A lot of the code is copied from this tutorial. I've searched for some hours now and couldn't figrure out what's causing the problem. I'm really sorry if i'm missing out something basic here.

The java program:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.ContextAttribs;
import org.lwjgl.opengl.Display;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
import org.lwjgl.opengl.PixelFormat;

public class MAIN {

    public static void main(String[] args) {
        try {
            try {
                ContextAttribs attr = new ContextAttribs(3, 2)
                        .withForwardCompatible(true).withProfileCore(true);
                Display.create(new PixelFormat(), attr);
            } catch (Exception ex) {
                ex.printStackTrace();
                return;
            }

            int vert = loadShader(ClassLoader.getSystemResource("shader.vert"),
                    GL_VERTEX_SHADER);
            int frag = loadShader(ClassLoader.getSystemResource("shader.frag"),
                    GL_FRAGMENT_SHADER);
            if (frag == -1 || vert == -1) {
                Display.destroy();
                System.exit(2);
            }
            int prog = glCreateProgram();
            glAttachShader(prog, vert);
            glAttachShader(prog, frag);
            glLinkProgram(prog);
            if (glGetProgrami(prog, GL_LINK_STATUS) == GL_FALSE) {
                int length = glGetProgrami(prog, GL_INFO_LOG_LENGTH);
                System.out.println(glGetProgramInfoLog(prog, length));
                System.out.println("Linking failed");
                Display.destroy();
                System.exit(2);
            }
            System.out.println("Shader setup sucesfull");
            glViewport(0, 0, Display.getWidth(), Display.getHeight());

            glUseProgram(prog);

            int buff = glGenVertexArrays();
            glBindVertexArray(buff);

            glValidateProgram(prog);
            System.out.println(glGetProgrami(prog, GL_VALIDATE_STATUS) == GL_TRUE);

            FloatBuffer buf = BufferUtils.createFloatBuffer(12);
            buf.put(new float[] { -50, 50, 0, 1, 50, -50, 0, 1, 0, -50, 0, 1 });
            buf.flip();
            buff = glGenBuffers();
            glBindBuffer(GL_ARRAY_BUFFER, buff);
            glBufferData(GL_ARRAY_BUFFER, buf, GL_STATIC_DRAW);
            glBindBuffer(GL_ARRAY_BUFFER, 0);

            while (!Display.isCloseRequested()
                    && !Thread.currentThread().isInterrupted()) {

                glClear(GL_COLOR_BUFFER_BIT);

                glBindBuffer(GL_ARRAY_BUFFER, buff);
                glEnableVertexAttribArray(1);
                glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);
                glDrawArrays(GL_TRIANGLES, 0, 3); // The Error
                glBindBuffer(GL_ARRAY_BUFFER, 0);

                Display.update();
                Display.sync(60);
            }
            Display.destroy();
        } catch (Exception ex) {
            ex.printStackTrace();
            if (Display.isCreated()) {
                Display.destroy();
            }
        }
    }

    public static int loadShader(URL path, int shaderType) {
        try (BufferedReader in = new BufferedReader(new InputStreamReader(
                path.openStream()))) {
            String text = "";
            String line;
            while ((line = in.readLine()) != null) {
                text = text + "\n" + line;
            }
            text.replaceFirst("\n", "");

            int shader = glCreateShader(shaderType);
            System.out.println("Setup shader: " + path + " for id: " + shader);
            glShaderSource(shader, text);

            glCompileShader(shader);
            if (glGetShaderi(shader, GL_COMPILE_STATUS) == GL_FALSE) {
                int length = glGetShaderi(shader, GL_INFO_LOG_LENGTH);
                String log = glGetShaderInfoLog(shader, length);
                System.out.println("Shader " + shader + " log: " + log);
                return -1;
            }
            return shader;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return -1;
    }
}

The vertex shader:

#version 330

layout(location = 0) in vec4 position;
void main() {
    gl_Position = position;
}

And the fragment shader:

#version 330

out vec4 outputColor;
void main() {
    outputColor = vec4(1, 1, 1, 1);
}
1

1 Answers

1
votes

You're enabling the wrong vertex attribute:

glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 4, GL_FLOAT, false, 0, 0);

The first argument to glEnableVertexAttribArray() is the location of the vertex attribute to be enabled. It corresponds to the first argument of glVertexAttribPointer(), and the location you specified for the attribute in the shader code:

layout(location = 0) in vec4 position;

Since you use 0 for the location of the position, the argument to glEnableVertexAttribArray() should be 0 as well:

glEnableVertexAttribArray(0);