LWJGL glDrawArrays抛出无效操作

时间:2014-07-28 12:42:50

标签: opengl lwjgl

我刚开始学习现代OpenGL,但我无法渲染三角形。当我启动程序时,当我尝试调用glDrawArrays时,它会给出无效操作异常。通过控制台日志的外观,着色器设置没有错误,并且程序已经过验证。很多代码都是从tutorial复制而来的。 我现在已经搜索了几个小时,无法确定导致问题的原因。如果我错过了一些基本的东西,我真的很抱歉。

java程序:

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;
    }
}

顶点着色器:

#version 330

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

片段着色器:

#version 330

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

1 个答案:

答案 0 :(得分:1)

您正在启用错误的顶点属性:

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

glEnableVertexAttribArray()的第一个参数是要启用的顶点属性的位置。它对应于glVertexAttribPointer()的第一个参数,以及您在着色器代码中为该属性指定的位置:

layout(location = 0) in vec4 position;

由于您使用0作为位置的位置,因此glEnableVertexAttribArray()的参数也应为0:

glEnableVertexAttribArray(0);