我只是从LWJGL Wiki上的this tutorial复制粘贴了代码,为了方便起见,现在将其粘贴到此处。
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.*;
import org.lwjgl.util.glu.GLU;
import java.nio.FloatBuffer;
public class TheQuadExampleDrawArrays {
// Entry point for the application
public static void main(String[] args) {
new TheQuadExampleDrawArrays();
}
// Setup variables
private final String WINDOW_TITLE = "The Quad: glDrawArrays";
private final int WIDTH = 320;
private final int HEIGHT = 240;
// Quad variables
private int vaoId = 0;
private int vboId = 0;
private int vertexCount = 0;
public TheQuadExampleDrawArrays() {
// Initialize OpenGL (Display)
this.setupOpenGL();
this.setupQuad();
while (!Display.isCloseRequested()) {
// Do a single loop (logic/render)
this.loopCycle();
// Force a maximum FPS of about 60
Display.sync(60);
// Let the CPU synchronize with the GPU if GPU is tagging behind
Display.update();
}
// Destroy OpenGL (Display)
this.destroyOpenGL();
}
public void setupOpenGL() {
// Setup an OpenGL context with API version 3.2
try {
PixelFormat pixelFormat = new PixelFormat();
ContextAttribs contextAtrributes = new ContextAttribs(3, 2)
.withForwardCompatible(true)
.withProfileCore(true);
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.setTitle(WINDOW_TITLE);
Display.create(pixelFormat, contextAtrributes);
GL11.glViewport(0, 0, WIDTH, HEIGHT);
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(-1);
}
// Setup an XNA like background color
GL11.glClearColor(0.4f, 0.6f, 0.9f, 0f);
// Map the internal OpenGL coordinate system to the entire screen
GL11.glViewport(0, 0, WIDTH, HEIGHT);
this.exitOnGLError("Error in setupOpenGL");
}
public void setupQuad() {
// OpenGL expects vertices to be defined counter clockwise by default
float[] vertices = {
// Left bottom triangle
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
// Right top triangle
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
-0.5f, 0.5f, 0f
};
// Sending data to OpenGL requires the usage of (flipped) byte buffers
FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesBuffer.put(vertices);
verticesBuffer.flip();
vertexCount = 6;
// Create a new Vertex Array Object in memory and select it (bind)
// A VAO can have up to 16 attributes (VBO's) assigned to it by default
vaoId = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoId);
// Create a new Vertex Buffer Object in memory and select it (bind)
// A VBO is a collection of Vectors which in this case resemble the location of each vertex.
vboId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
// Put the VBO in the attributes list at index 0
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
// Deselect (bind to 0) the VBO
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
// Deselect (bind to 0) the VAO
GL30.glBindVertexArray(0);
this.exitOnGLError("Error in setupQuad");
}
public void loopCycle() {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
// Bind to the VAO that has all the information about the quad vertices
GL30.glBindVertexArray(vaoId);
GL20.glEnableVertexAttribArray(0);
// Draw the vertices
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, vertexCount);
/**
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* I found that the GL_INVALID_OPERATION flag was being raised here,
* at the call to glDrawArrays().
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*/
// Put everything back to default (deselect)
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
this.exitOnGLError("Error in loopCycle");
}
public void destroyOpenGL() {
// Disable the VBO index from the VAO attributes list
GL20.glDisableVertexAttribArray(0);
// Delete the VBO
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL15.glDeleteBuffers(vboId);
// Delete the VAO
GL30.glBindVertexArray(0);
GL30.glDeleteVertexArrays(vaoId);
Display.destroy();
}
public void exitOnGLError(String errorMessage) {
int errorValue = GL11.glGetError();
if (errorValue != GL11.GL_NO_ERROR) {
String errorString = GLU.gluErrorString(errorValue);
System.err.println("ERROR - " + errorMessage + ": " + errorString);
if (Display.isCreated()) Display.destroy();
System.exit(-1);
}
}
}
当我运行它时,它抛出了一个读取的错误
ERROR - Error in loopCycle: Invalid operation
我将其范围缩小为
glDrawArrays()
方法中对loopCycle()
的调用,然后打开Google找出可能的含义,并发现了this SO question,其中列出了很多可能的原因(为方便起见在此处列出) 。如果将非零缓冲区对象名称绑定到已启用的数组或
GL_INVALID_OPERATION
绑定,并且当前已映射缓冲区对象的数据存储,则会生成GL_DRAW_INDIRECT_BUFFER
。如果在
GL_INVALID_OPERATION
的执行和相应的glDrawArrays
之间执行了glBegin
,则会生成glEnd
。如果当前程序对象中的任何两个活动采样器属于不同类型,但引用相同的纹理图像单元,则
GL_INVALID_OPERATION
或glDrawArrays
将生成glDrawElements
。如果几何着色器处于活动状态并且模式与当前安装的程序对象中的几何着色器的输入基本类型不兼容,则生成
GL_INVALID_OPERATION
。如果mode为
GL_INVALID_OPERATION
并且没有任何镶嵌控制着色器处于活动状态,则生成GL_PATCHES
。如果将图元的顶点记录到用于转换反馈目的的缓冲对象中,则将导致
GL_INVALID_OPERATION
生成,结果将导致超出任何缓冲对象的大小限制,或者导致超出最终位置偏移量+ size-1,由glBindBufferRange
。如果没有几何着色器,则
GL_INVALID_OPERATION
由glDrawArrays()
生成,转换反馈处于活动状态,并且模式不是允许的模式之一。如果存在几何着色器,则
GL_INVALID_OPERATION
由glDrawArrays()
生成,则转换反馈处于活动状态,并且几何着色器的输出基元类型与转换反馈originalMode不匹配。如果绑定的着色器程序无效,则生成
GL_INVALID_OPERATION
。如果使用转换反馈,则会生成
GL_INVALID_OPERATION
,并且绑定到转换反馈绑定点的缓冲区也将绑定到数组缓冲区绑定点。其中大多数对我来说都是没有意义的,经过相当长的时间阅读它们之后,我几乎无法发现此代码出了什么问题。谁能比我更了解此事,请指出提出
GL_INVALID_OPERATION
标志的原因吗? 最佳答案
项目9。您似乎没有绑定着色器程序。
您正在使用Core Profile创建上下文:
ContextAttribs contextAtrributes = new ContextAttribs(3, 2)
.withForwardCompatible(true)
.withProfileCore(true);
使用Core Profile,需要您提供着色器程序。通常,您通常会在GLSL中至少编写一个顶点和一个片段着色器,然后使用如下所示的调用来构建和绑定着色器程序:
glCreateShader
glShaderSource
glCompileShader
glCreateProgram
glAttachShader
glLinkProgram
glUseProgram
关于java - LWJGL Wiki上的示例代码因GL_INVALID_OPERATION而失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26986908/