【问题标题】:LWJGL - VBO rendering on one system but not the otherLWJGL - VBO 渲染在一个系统上而不是另一个系统上
【发布时间】:2015-01-09 05:16:03
【问题描述】:

我最近决定重新审视我根据 LWJGL wiki 上的教程使用索引 VBO 编写的一些 LWJGL 渲染代码。在我的台式电脑上一切正常,但是当我切换到我的学校笔记本电脑时,它拒绝渲染任何东西。

我有以下渲染代码:

GL20.glUseProgram(pId); System.out.println("没有错误?" + (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));

这是我的顶点/片段着色器

#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 渲染/创建/着色器代码的某些部分与我的 m4000 卡不兼容,但我无法使用 glGetError() 找到任何错误。

【问题讨论】:

  • 在 Eclipse 中在我女朋友的笔记本电脑上运行程序也不会渲染任何东西。她的笔记本电脑的硬件和我的一样。
  • 驱动版本呢?这也可以有所作为。你确定没有OpenGL错误吗?你在哪里调用glGetError(),你调用了多少次?我建议你用几个glGetErrors() 填充你的代码,以确保没有任何...
  • 代码中是否有任何未显示的内容来确保in_Position 绑定到位置0,而in_Color 绑定到位置1?
  • Dan,我刚刚更新了视频驱动程序并添加了一些 glGetError() 检查。我只是在控制台中为 false 执行 ctrl+F 并没有找到任何东西。我在链接着色器的代码末尾也有一个。
  • Reto,我添加了着色器设置代码。它显示了我如何将 'in_position' 和 'in_color' 绑定到位置 0 和 1

标签: opengl lwjgl vbo


【解决方案1】:

您在着色器设置代码中的调用顺序将无法按预期工作:

GL20.glLinkProgram(pId);
GL20.glBindAttribLocation(pId, 0, "in_Position");
GL20.glBindAttribLocation(pId, 1, "in_Color");

glBindAttribLocation() 需要在之前调用glLinkProgram() 才能生效。来自man page

在调用 glLinkProgram 之前,属性绑定不会生效。成功链接程序对象后,通用属性的索引值保持不变(并且可以查询它们的值),直到出现下一个链接命令。

因此,调用顺序需要为:

GL20.glBindAttribLocation(pId, 0, "in_Position");
GL20.glBindAttribLocation(pId, 1, "in_Color");
GL20.glLinkProgram(pId);

虽然不是正确性问题,但您也没有非常有效地使用 VAO。属性启用/禁用值和GL_ELEMENT_ARRAY_BUFFER 绑定是VAO 状态的一部分。因此,您可以在设置期间调用glEnableVertexAttribArray()GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiId) 一次,在绑定 VAO 时。然后在draw call中,只需要绑定VAO就可以设置好所有的状态了。

【讨论】:

  • 太棒了!谢谢您的帮助!有趣的是,我的桌面显卡能够弄清楚发生了什么。
  • 如果位置是自动分配的,许多实现会按照出现的顺序依次分配它们。默认情况下您会得到 0 和 1,这并不奇怪。但其他人可能会按字母顺序依次分配它们。或者使用完全不同的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-03
  • 2012-01-07
  • 1970-01-01
  • 2022-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多