调用 GL11.glDrawElements 时出现 LWJGL 错误,原因未知
LWJGL error when calling GL11.glDrawElements, cause unknown
我正在尝试使用 LWJGL 渲染某些内容,并且我正在学习教程 (this one) and I had finished what has been written, however I wanted lighting so I followed a tutorial I had found (this one)。现在我的应用程序在启动时崩溃了,崩溃日志非常无用。
渲染函数:
public void renderMesh(GameObject object, Camera camera) {
GL30.glBindVertexArray(object.getMesh().getVAO());
GL30.glEnableVertexAttribArray(0);
GL30.glEnableVertexAttribArray(1);
GL30.glEnableVertexAttribArray(2);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, object.getMesh().getIBO());
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL13.glBindTexture(GL11.GL_TEXTURE_2D, object.getMesh().getMaterial().getTextureID());
shader.bind();
shader.setUniform("model", Matrix4f.transform(object.getPosition(), object.getRotation(), object.getScale()));
shader.setUniform("view", Matrix4f.view(camera.getPosition(), camera.getRotation()));
shader.setUniform("projection", window.getProjectionMatrix());
shader.setUniform("lightPos", new Vector3f(0, 10, 0));
GL11.glDrawElements(GL11.GL_TRIANGLES, object.getMesh().getIndices().length, GL11.GL_UNSIGNED_INT, 0);
shader.unbind();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL30.glDisableVertexAttribArray(0);
GL30.glDisableVertexAttribArray(1);
GL30.glDisableVertexAttribArray(2);
GL30.glBindVertexArray(0);
}
顶点着色器:
#version 460
in vec3 position;
in vec3 normal;
in vec3 color;
in vec2 textureCoord;
out vec2 passTextureCoord;
out vec3 passNormal;
out vec3 passPosition;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main() {
gl_Position = projection * view * model * vec4(position, 1.0);
passNormal = normal;
passTextureCoord = textureCoord;
passPosition = vec3(model * vec4(position, 1.0));
}
片段着色器:
#version 460
in vec2 passTextureCoord;
in vec3 passNormal;
in vec3 passPosition;
out vec4 color;
uniform sampler2D tex;
uniform vec3 lightPos;
void main() {
vec3 lightColor = vec3(1.0);
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
vec3 norm = normalize(passNormal);
vec3 lightDir = normalize(lightPos - passPosition);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
vec3 result = (ambient + diffuse) * 0.85;
color = vec4(result, 1.0) * texture(tex, passTextureCoord);
}
堆栈跟踪:
j org.lwjgl.opengl.GL11C.nglDrawElements(IIIJ)V+0
j org.lwjgl.opengl.GL11C.glDrawElements(IIIJ)V+4
j org.lwjgl.opengl.GL11.glDrawElements(IIIJ)V+4
j rendering.Renderer.renderMesh(Lobject/GameObject;Lobject/Camera;)V+155
...
有人能看出问题吗?
编辑:
Mesh.java
public class Mesh {
private Vertex[] vertices;
private int[] indices;
private Material material;
private int vao, pbo, ibo, cbo, tbo;
public Mesh(Vertex[] vertices, int[] indices, Material material) {
this.vertices = vertices;
this.indices = indices;
this.material = material;
}
public void create() {
material.create();
vao = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);
FloatBuffer positionBuffer = BufferUtils.createFloatBuffer(vertices.length * 3);
float[] positionData = new float[vertices.length * 3];
for (int i = 0; i < vertices.length; i++) {
positionData[i * 3] = vertices[i].getPosition().getX();
positionData[i * 3 + 1] = vertices[i].getPosition().getY();
positionData[i * 3 + 2] = vertices[i].getPosition().getZ();
}
positionBuffer.put(positionData).flip();
pbo = storeData(positionBuffer, 0, 3);
FloatBuffer textureBuffer = BufferUtils.createFloatBuffer(vertices.length * 2);
float[] textureData = new float[vertices.length * 2];
for (int i = 0; i < vertices.length; i++) {
textureData[i * 2] = vertices[i].getTextureCoord().getX();
textureData[i * 2 + 1] = vertices[i].getTextureCoord().getY();
}
textureBuffer.put(textureData).flip();
tbo = storeData(textureBuffer, 2, 2);
IntBuffer indicesBuffer = BufferUtils.createIntBuffer(indices.length);
indicesBuffer.put(indices).flip();
ibo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ibo);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
}
private int storeData(FloatBuffer buffer, int index, int size) {
int bufferID = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferID);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(index, size, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
return bufferID;
}
public void destroy() {
GL15.glDeleteBuffers(pbo);
GL15.glDeleteBuffers(cbo);
GL15.glDeleteBuffers(ibo);
GL15.glDeleteBuffers(tbo);
GL30.glDeleteVertexArrays(vao);
material.destroy();
}
public Vertex[] getVertices() {
return vertices;
}
public int[] getIndices() {
return indices;
}
public int getVAO() {
return vao;
}
public int getPBO() {
return pbo;
}
public int getCBO() {
return cbo;
}
public int getTBO() {
return tbo;
}
public int getIBO() {
return ibo;
}
public Material getMaterial() {
return material;
}
}
Shader.java
public class Shader {
private String vertexFile, fragmentFile;
private int vertexID, fragmentID, programID;
public Shader(String vertexPath, String fragmentPath) {
vertexFile = FileUtil.loadAsString(vertexPath);
fragmentFile = FileUtil.loadAsString(fragmentPath);
}
public void create() {
programID = GL20.glCreateProgram();
vertexID = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
GL20.glShaderSource(vertexID, vertexFile);
GL20.glCompileShader(vertexID);
if (GL20.glGetShaderi(vertexID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.err.println("Vertex Shader: " + GL20.glGetShaderInfoLog(vertexID));
return;
}
fragmentID = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
GL20.glShaderSource(fragmentID, fragmentFile);
GL20.glCompileShader(fragmentID);
if (GL20.glGetShaderi(fragmentID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.err.println("Fragment Shader: " + GL20.glGetShaderInfoLog(fragmentID));
return;
}
GL20.glAttachShader(programID, vertexID);
GL20.glAttachShader(programID, fragmentID);
GL20.glLinkProgram(programID);
if (GL20.glGetProgrami(programID, GL20.GL_LINK_STATUS) == GL11.GL_FALSE) {
System.err.println("Program Linking: " + GL20.glGetProgramInfoLog(programID));
return;
}
GL20.glValidateProgram(programID);
if (GL20.glGetProgrami(programID, GL20.GL_VALIDATE_STATUS) == GL11.GL_FALSE) {
System.err.println("Program Validation: " + GL20.glGetProgramInfoLog(programID));
return;
}
}
public int getUniformLocation(String name) {
return GL20.glGetUniformLocation(programID, name);
}
public void setUniform(String name, float value) {
GL20.glUniform1f(getUniformLocation(name), value);
}
public void setUniform(String name, int value) {
GL20.glUniform1i(getUniformLocation(name), value);
}
public void setUniform(String name, boolean value) {
GL20.glUniform1i(getUniformLocation(name), value ? 1 : 0);
}
public void setUniform(String name, Vector2f value) {
GL20.glUniform2f(getUniformLocation(name), value.getX(), value.getY());
}
public void setUniform(String name, Vector3f value) {
GL20.glUniform3f(getUniformLocation(name), value.getX(), value.getY(), value.getZ());
}
public void setUniform(String name, Matrix4f value) {
FloatBuffer matrix = MemoryUtil.memAllocFloat(Matrix4f.SIZE * Matrix4f.SIZE);
matrix.put(value.getAll()).flip();
GL20.glUniformMatrix4fv(getUniformLocation(name), true, matrix);
}
public void bind() {
GL20.glUseProgram(programID);
}
public void unbind() {
GL20.glUseProgram(0);
}
public void destroy() {
GL20.glDetachShader(programID, vertexID);
GL20.glDetachShader(programID, fragmentID);
GL20.glDeleteShader(vertexID);
GL20.glDeleteShader(fragmentID);
GL20.glDeleteProgram(programID);
}
}
Window 设置:
GLFWVidMode videoMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
windowPosX[0] = (videoMode.width());
windowPosY[0] = (videoMode.height() - height) / 2;
GLFW.glfwSetWindowPos(window, windowPosX[0], windowPosY[0]);
GLFW.glfwMakeContextCurrent(window);
GL.createCapabilities();
GL11.glShadeModel(GL_SMOOTH);
GL11.glEnable(GL_DEPTH_TEST);
GL11.glEnable(GL_LIGHTING);
GL11.glEnable(GL_LIGHT0);
GL11.glLightModelfv(GL_LIGHT_MODEL_AMBIENT, new float[]{0.1f, 0.05f, 0.05f, 1f});
GL11.glLightfv(GL_LIGHT0, GL_POSITION, new float[]{0, 0, 0, 1});
GL11.glEnable(GL_CULL_FACE);
GL11.glCullFace(GL_BACK);
GL11.glEnable(GL_COLOR_MATERIAL);
GL11.glColorMaterial(GL_FRONT, GL_DIFFUSE);
另一个注意事项:我是从程序加载的另一个 .jar 文件中添加渲染函数。这不太可能是问题所在,因为没有点亮程序就可以正常工作。
问题是您从未为索引为 1
的通用顶点属性设置顶点源(VBO - 通过 glVertexAttribPointer
),而是通过 glEnableVertexAttribArray(1)
启用该属性。您不能拥有未初始化的已启用通用顶点属性。
您只调用 storeData(positionBuffer, 0, 3)
和 storeData(positionBuffer, 2, 3)
但永远不会调用通用顶点属性索引 1
.
这会导致崩溃。
我正在尝试使用 LWJGL 渲染某些内容,并且我正在学习教程 (this one) and I had finished what has been written, however I wanted lighting so I followed a tutorial I had found (this one)。现在我的应用程序在启动时崩溃了,崩溃日志非常无用。
渲染函数:
public void renderMesh(GameObject object, Camera camera) {
GL30.glBindVertexArray(object.getMesh().getVAO());
GL30.glEnableVertexAttribArray(0);
GL30.glEnableVertexAttribArray(1);
GL30.glEnableVertexAttribArray(2);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, object.getMesh().getIBO());
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL13.glBindTexture(GL11.GL_TEXTURE_2D, object.getMesh().getMaterial().getTextureID());
shader.bind();
shader.setUniform("model", Matrix4f.transform(object.getPosition(), object.getRotation(), object.getScale()));
shader.setUniform("view", Matrix4f.view(camera.getPosition(), camera.getRotation()));
shader.setUniform("projection", window.getProjectionMatrix());
shader.setUniform("lightPos", new Vector3f(0, 10, 0));
GL11.glDrawElements(GL11.GL_TRIANGLES, object.getMesh().getIndices().length, GL11.GL_UNSIGNED_INT, 0);
shader.unbind();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL30.glDisableVertexAttribArray(0);
GL30.glDisableVertexAttribArray(1);
GL30.glDisableVertexAttribArray(2);
GL30.glBindVertexArray(0);
}
顶点着色器:
#version 460
in vec3 position;
in vec3 normal;
in vec3 color;
in vec2 textureCoord;
out vec2 passTextureCoord;
out vec3 passNormal;
out vec3 passPosition;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main() {
gl_Position = projection * view * model * vec4(position, 1.0);
passNormal = normal;
passTextureCoord = textureCoord;
passPosition = vec3(model * vec4(position, 1.0));
}
片段着色器:
#version 460
in vec2 passTextureCoord;
in vec3 passNormal;
in vec3 passPosition;
out vec4 color;
uniform sampler2D tex;
uniform vec3 lightPos;
void main() {
vec3 lightColor = vec3(1.0);
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
vec3 norm = normalize(passNormal);
vec3 lightDir = normalize(lightPos - passPosition);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
vec3 result = (ambient + diffuse) * 0.85;
color = vec4(result, 1.0) * texture(tex, passTextureCoord);
}
堆栈跟踪:
j org.lwjgl.opengl.GL11C.nglDrawElements(IIIJ)V+0
j org.lwjgl.opengl.GL11C.glDrawElements(IIIJ)V+4
j org.lwjgl.opengl.GL11.glDrawElements(IIIJ)V+4
j rendering.Renderer.renderMesh(Lobject/GameObject;Lobject/Camera;)V+155
...
有人能看出问题吗?
编辑: Mesh.java
public class Mesh {
private Vertex[] vertices;
private int[] indices;
private Material material;
private int vao, pbo, ibo, cbo, tbo;
public Mesh(Vertex[] vertices, int[] indices, Material material) {
this.vertices = vertices;
this.indices = indices;
this.material = material;
}
public void create() {
material.create();
vao = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);
FloatBuffer positionBuffer = BufferUtils.createFloatBuffer(vertices.length * 3);
float[] positionData = new float[vertices.length * 3];
for (int i = 0; i < vertices.length; i++) {
positionData[i * 3] = vertices[i].getPosition().getX();
positionData[i * 3 + 1] = vertices[i].getPosition().getY();
positionData[i * 3 + 2] = vertices[i].getPosition().getZ();
}
positionBuffer.put(positionData).flip();
pbo = storeData(positionBuffer, 0, 3);
FloatBuffer textureBuffer = BufferUtils.createFloatBuffer(vertices.length * 2);
float[] textureData = new float[vertices.length * 2];
for (int i = 0; i < vertices.length; i++) {
textureData[i * 2] = vertices[i].getTextureCoord().getX();
textureData[i * 2 + 1] = vertices[i].getTextureCoord().getY();
}
textureBuffer.put(textureData).flip();
tbo = storeData(textureBuffer, 2, 2);
IntBuffer indicesBuffer = BufferUtils.createIntBuffer(indices.length);
indicesBuffer.put(indices).flip();
ibo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ibo);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
}
private int storeData(FloatBuffer buffer, int index, int size) {
int bufferID = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferID);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(index, size, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
return bufferID;
}
public void destroy() {
GL15.glDeleteBuffers(pbo);
GL15.glDeleteBuffers(cbo);
GL15.glDeleteBuffers(ibo);
GL15.glDeleteBuffers(tbo);
GL30.glDeleteVertexArrays(vao);
material.destroy();
}
public Vertex[] getVertices() {
return vertices;
}
public int[] getIndices() {
return indices;
}
public int getVAO() {
return vao;
}
public int getPBO() {
return pbo;
}
public int getCBO() {
return cbo;
}
public int getTBO() {
return tbo;
}
public int getIBO() {
return ibo;
}
public Material getMaterial() {
return material;
}
}
Shader.java
public class Shader {
private String vertexFile, fragmentFile;
private int vertexID, fragmentID, programID;
public Shader(String vertexPath, String fragmentPath) {
vertexFile = FileUtil.loadAsString(vertexPath);
fragmentFile = FileUtil.loadAsString(fragmentPath);
}
public void create() {
programID = GL20.glCreateProgram();
vertexID = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
GL20.glShaderSource(vertexID, vertexFile);
GL20.glCompileShader(vertexID);
if (GL20.glGetShaderi(vertexID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.err.println("Vertex Shader: " + GL20.glGetShaderInfoLog(vertexID));
return;
}
fragmentID = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
GL20.glShaderSource(fragmentID, fragmentFile);
GL20.glCompileShader(fragmentID);
if (GL20.glGetShaderi(fragmentID, GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE) {
System.err.println("Fragment Shader: " + GL20.glGetShaderInfoLog(fragmentID));
return;
}
GL20.glAttachShader(programID, vertexID);
GL20.glAttachShader(programID, fragmentID);
GL20.glLinkProgram(programID);
if (GL20.glGetProgrami(programID, GL20.GL_LINK_STATUS) == GL11.GL_FALSE) {
System.err.println("Program Linking: " + GL20.glGetProgramInfoLog(programID));
return;
}
GL20.glValidateProgram(programID);
if (GL20.glGetProgrami(programID, GL20.GL_VALIDATE_STATUS) == GL11.GL_FALSE) {
System.err.println("Program Validation: " + GL20.glGetProgramInfoLog(programID));
return;
}
}
public int getUniformLocation(String name) {
return GL20.glGetUniformLocation(programID, name);
}
public void setUniform(String name, float value) {
GL20.glUniform1f(getUniformLocation(name), value);
}
public void setUniform(String name, int value) {
GL20.glUniform1i(getUniformLocation(name), value);
}
public void setUniform(String name, boolean value) {
GL20.glUniform1i(getUniformLocation(name), value ? 1 : 0);
}
public void setUniform(String name, Vector2f value) {
GL20.glUniform2f(getUniformLocation(name), value.getX(), value.getY());
}
public void setUniform(String name, Vector3f value) {
GL20.glUniform3f(getUniformLocation(name), value.getX(), value.getY(), value.getZ());
}
public void setUniform(String name, Matrix4f value) {
FloatBuffer matrix = MemoryUtil.memAllocFloat(Matrix4f.SIZE * Matrix4f.SIZE);
matrix.put(value.getAll()).flip();
GL20.glUniformMatrix4fv(getUniformLocation(name), true, matrix);
}
public void bind() {
GL20.glUseProgram(programID);
}
public void unbind() {
GL20.glUseProgram(0);
}
public void destroy() {
GL20.glDetachShader(programID, vertexID);
GL20.glDetachShader(programID, fragmentID);
GL20.glDeleteShader(vertexID);
GL20.glDeleteShader(fragmentID);
GL20.glDeleteProgram(programID);
}
}
Window 设置:
GLFWVidMode videoMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
windowPosX[0] = (videoMode.width());
windowPosY[0] = (videoMode.height() - height) / 2;
GLFW.glfwSetWindowPos(window, windowPosX[0], windowPosY[0]);
GLFW.glfwMakeContextCurrent(window);
GL.createCapabilities();
GL11.glShadeModel(GL_SMOOTH);
GL11.glEnable(GL_DEPTH_TEST);
GL11.glEnable(GL_LIGHTING);
GL11.glEnable(GL_LIGHT0);
GL11.glLightModelfv(GL_LIGHT_MODEL_AMBIENT, new float[]{0.1f, 0.05f, 0.05f, 1f});
GL11.glLightfv(GL_LIGHT0, GL_POSITION, new float[]{0, 0, 0, 1});
GL11.glEnable(GL_CULL_FACE);
GL11.glCullFace(GL_BACK);
GL11.glEnable(GL_COLOR_MATERIAL);
GL11.glColorMaterial(GL_FRONT, GL_DIFFUSE);
另一个注意事项:我是从程序加载的另一个 .jar 文件中添加渲染函数。这不太可能是问题所在,因为没有点亮程序就可以正常工作。
问题是您从未为索引为 1
的通用顶点属性设置顶点源(VBO - 通过 glVertexAttribPointer
),而是通过 glEnableVertexAttribArray(1)
启用该属性。您不能拥有未初始化的已启用通用顶点属性。
您只调用 storeData(positionBuffer, 0, 3)
和 storeData(positionBuffer, 2, 3)
但永远不会调用通用顶点属性索引 1
.
这会导致崩溃。