LWJGL - VBO 在一个系统上渲染,但在另一个系统上渲染
LWJGL - VBO rendering on one system but not the other
我最近决定重新审视我根据 LWJGL wiki 上的教程使用索引 VBO 编写的一些 LWJGL 渲染代码。在我的台式电脑上一切正常,但当我切换到我的学校笔记本电脑时,它拒绝渲染任何东西。
我有以下渲染代码:
GL20.glUseProgram(pId);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Bind to the VAO that has all the information about the vertices and colors
GL30.glBindVertexArray(vaoId);
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Bind to the index VBO that has all the information about the order of the vertices
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);
// Draw the vertices
GL11.glDrawElements(GL11.GL_TRIANGLES, indicesCount, GL11.GL_UNSIGNED_INT, 0);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Put everything back to default (deselect)
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL30.glBindVertexArray(0);
GL20.glUseProgram(0);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
这是我的 vertex/fragment 着色器
#version 130
uniform mat4 MVP;
in vec4 in_Position;
in vec4 in_Color;
out vec4 pass_Color;
void main(void) {
gl_Position = MVP * in_Position;
pass_Color = in_Color;
}
#version 130
in vec4 pass_Color;
out vec4 out_Color;
void main(void) {
out_Color = pass_Color;
}
这是我的 VBO 初始化函数
public void initialize(float[] vertices, float[] colors, int[] indices) {
shaderSetup();
//create the buffers to hold vertex color and index data
FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesBuffer.put(vertices);
verticesBuffer.flip();
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
FloatBuffer colorsBuffer = BufferUtils.createFloatBuffer(colors.length);
colorsBuffer.put(colors);
colorsBuffer.flip();
// OpenGL expects vertices in counter clockwise order by default
indicesCount = indices.length;
IntBuffer indicesBuffer = BufferUtils.createIntBuffer(indicesCount);
indicesBuffer.put(indices);
indicesBuffer.flip();
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Create a new Vertex Array Object in memory and select it (bind)
vaoId = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoId);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Create a new Vertex Buffer Object in memory and select it (bind) - VERTICES
vboId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 4, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Create a new Vertex Buffer Object in memory and select it (bind) - COLORS
vbocId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbocId);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, colorsBuffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(1, 4, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Deselect (bind to 0) the VAO
GL30.glBindVertexArray(0);
// Create a new VBO for the indices and select it (bind) - INDICES
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
vboiId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
}
着色器设置代码:
int errorCheckValue = GL11.glGetError();
// Load the vertex shader
vsId = this.loadShader("Shaders/vertex.glsl", GL20.GL_VERTEX_SHADER);
// Load the fragment shader
fsId = this.loadShader("Shaders/fragment.glsl", GL20.GL_FRAGMENT_SHADER);
// Create a new shader program that links both shaders
pId = GL20.glCreateProgram();
GL20.glAttachShader(pId, vsId);
GL20.glAttachShader(pId, fsId);
GL20.glLinkProgram(pId);
// Position information will be attribute 0
GL20.glBindAttribLocation(pId, 0, "in_Position");
// Color information will be attribute 1
GL20.glBindAttribLocation(pId, 1, "in_Color");
GL20.glValidateProgram(pId);
errorCheckValue = GL11.glGetError();
if (errorCheckValue != GL11.GL_NO_ERROR) {
System.out.println("ERROR - Could not create the shaders");
System.exit(-1);
}
我家里的台式机(按预期渲染所有内容)运行的是 nVidia GTX 460 显卡,而我学校的笔记本电脑(不渲染任何东西)有 AMD Firepro m4000 显卡。我最好的猜测是 VBO render/creation/shader 代码的某些部分与我的 m4000 卡不兼容,但我无法使用 glGetError() 找到任何错误。
您在着色器设置代码中的调用顺序将无法按预期工作:
GL20.glLinkProgram(pId);
GL20.glBindAttribLocation(pId, 0, "in_Position");
GL20.glBindAttribLocation(pId, 1, "in_Color");
glBindAttribLocation()
需要在glLinkProgram()
之前调用才能生效。来自 man page:
Attribute bindings do not go into effect until glLinkProgram is called. After a program object has been linked successfully, the index values for generic attributes remain fixed (and their values can be queried) until the next link command occurs.
因此调用顺序需要为:
GL20.glBindAttribLocation(pId, 0, "in_Position");
GL20.glBindAttribLocation(pId, 1, "in_Color");
GL20.glLinkProgram(pId);
虽然不是正确性问题,但您也没有非常有效地使用 VAO。属性 enable/disable 值和 GL_ELEMENT_ARRAY_BUFFER
绑定是 VAO 状态的一部分。因此,您可以在设置期间调用 glEnableVertexAttribArray()
和 GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId)
一次,同时绑定 VAO。然后在draw call中,只需要绑定VAO就可以设置所有的state。
我最近决定重新审视我根据 LWJGL wiki 上的教程使用索引 VBO 编写的一些 LWJGL 渲染代码。在我的台式电脑上一切正常,但当我切换到我的学校笔记本电脑时,它拒绝渲染任何东西。
我有以下渲染代码:
GL20.glUseProgram(pId); System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Bind to the VAO that has all the information about the vertices and colors
GL30.glBindVertexArray(vaoId);
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Bind to the index VBO that has all the information about the order of the vertices
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);
// Draw the vertices
GL11.glDrawElements(GL11.GL_TRIANGLES, indicesCount, GL11.GL_UNSIGNED_INT, 0);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Put everything back to default (deselect)
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL30.glBindVertexArray(0);
GL20.glUseProgram(0);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
这是我的 vertex/fragment 着色器
#version 130
uniform mat4 MVP;
in vec4 in_Position;
in vec4 in_Color;
out vec4 pass_Color;
void main(void) {
gl_Position = MVP * in_Position;
pass_Color = in_Color;
}
#version 130
in vec4 pass_Color;
out vec4 out_Color;
void main(void) {
out_Color = pass_Color;
}
这是我的 VBO 初始化函数
public void initialize(float[] vertices, float[] colors, int[] indices) {
shaderSetup();
//create the buffers to hold vertex color and index data
FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
verticesBuffer.put(vertices);
verticesBuffer.flip();
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
FloatBuffer colorsBuffer = BufferUtils.createFloatBuffer(colors.length);
colorsBuffer.put(colors);
colorsBuffer.flip();
// OpenGL expects vertices in counter clockwise order by default
indicesCount = indices.length;
IntBuffer indicesBuffer = BufferUtils.createIntBuffer(indicesCount);
indicesBuffer.put(indices);
indicesBuffer.flip();
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Create a new Vertex Array Object in memory and select it (bind)
vaoId = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoId);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Create a new Vertex Buffer Object in memory and select it (bind) - VERTICES
vboId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 4, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Create a new Vertex Buffer Object in memory and select it (bind) - COLORS
vbocId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbocId);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, colorsBuffer, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(1, 4, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
// Deselect (bind to 0) the VAO
GL30.glBindVertexArray(0);
// Create a new VBO for the indices and select it (bind) - INDICES
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
vboiId = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
System.out.println("NO Error? " + (GL11.glGetError() == GL11.GL_NO_ERROR));
}
着色器设置代码:
int errorCheckValue = GL11.glGetError();
// Load the vertex shader
vsId = this.loadShader("Shaders/vertex.glsl", GL20.GL_VERTEX_SHADER);
// Load the fragment shader
fsId = this.loadShader("Shaders/fragment.glsl", GL20.GL_FRAGMENT_SHADER);
// Create a new shader program that links both shaders
pId = GL20.glCreateProgram();
GL20.glAttachShader(pId, vsId);
GL20.glAttachShader(pId, fsId);
GL20.glLinkProgram(pId);
// Position information will be attribute 0
GL20.glBindAttribLocation(pId, 0, "in_Position");
// Color information will be attribute 1
GL20.glBindAttribLocation(pId, 1, "in_Color");
GL20.glValidateProgram(pId);
errorCheckValue = GL11.glGetError();
if (errorCheckValue != GL11.GL_NO_ERROR) {
System.out.println("ERROR - Could not create the shaders");
System.exit(-1);
}
我家里的台式机(按预期渲染所有内容)运行的是 nVidia GTX 460 显卡,而我学校的笔记本电脑(不渲染任何东西)有 AMD Firepro m4000 显卡。我最好的猜测是 VBO render/creation/shader 代码的某些部分与我的 m4000 卡不兼容,但我无法使用 glGetError() 找到任何错误。
您在着色器设置代码中的调用顺序将无法按预期工作:
GL20.glLinkProgram(pId);
GL20.glBindAttribLocation(pId, 0, "in_Position");
GL20.glBindAttribLocation(pId, 1, "in_Color");
glBindAttribLocation()
需要在glLinkProgram()
之前调用才能生效。来自 man page:
Attribute bindings do not go into effect until glLinkProgram is called. After a program object has been linked successfully, the index values for generic attributes remain fixed (and their values can be queried) until the next link command occurs.
因此调用顺序需要为:
GL20.glBindAttribLocation(pId, 0, "in_Position");
GL20.glBindAttribLocation(pId, 1, "in_Color");
GL20.glLinkProgram(pId);
虽然不是正确性问题,但您也没有非常有效地使用 VAO。属性 enable/disable 值和 GL_ELEMENT_ARRAY_BUFFER
绑定是 VAO 状态的一部分。因此,您可以在设置期间调用 glEnableVertexAttribArray()
和 GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId)
一次,同时绑定 VAO。然后在draw call中,只需要绑定VAO就可以设置所有的state。