我刚开始学习现代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);
}
答案 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);