不了解的OpenGL基础

时间:2018-08-24 15:31:47

标签: java opengl lwjgl

问候OpenGL爱好者!

  • 首先,我使用 LWJGL 2 ,所以下面是Java代码。
  • 第二。我想说的是,我用Google搜索了每个问题 将在这篇文章中问。主要问题是答案不同 彼此之间,所以我无法建立对事物的具体理解 这在下面的代码中发生了。
  • 第三。我刚刚开始学习OpenGL,但我也没有任何Java经验。因此,除了您对我的问题的解释之外,如果您还有其他建议,请随时提出批评/建议。除了用C ++进行OpenGL:)

现在开始吧。

public class Loader {
public void createVAO(int[] indices) {
    int vaoID = glGenVertexArrays();

    glBindVertexArray(vaoID);
    createIndicesVBO(indices);
    glEnableVertexAttribArray(0);
}

public void createVBO(float[] vertices) {
    int vboID = glGenBuffers(); 
    glBindBuffer(GL_ARRAY_BUFFER, vboID);
    FloatBuffer buffer = makeByteBufferFromArrayOfFloats(vertices);
    glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, false, 0,0);
}

public void createIndicesVBO(int[] indices) {
    int vboID = glGenBuffers();
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
    IntBuffer buffer = makeByteBufferFromArrayOfInts(indices);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
}

public void pleaseDraw(float[] vertices, int[] indices) {
    glClearColor(0, 0, 1, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    glDrawElements(GL_TRIANGLES, indices.length, GL_UNSIGNED_INT,0);

}
public void cleanUp() {
    glDeleteBuffers(0);
    glDeleteVertexArrays(0);
}
public FloatBuffer makeByteBufferFromArrayOfFloats(float[] vertices) {

    FloatBuffer FloatByteBuffer = BufferUtils.createFloatBuffer(vertices.length);
    FloatByteBuffer.put(vertices);
    FloatByteBuffer.flip();
    return FloatByteBuffer;
}

public IntBuffer makeByteBufferFromArrayOfInts(int[] array) {

    IntBuffer IntByteBuffer = BufferUtils.createIntBuffer(array.length);
    IntByteBuffer.put(array);
    IntByteBuffer.flip();
    return IntByteBuffer;
}
}

注意-此代码有效,并输出一个蓝色的窗口,中间有一个黑色的四边形。 问题:

  1. glBindBuffer(GL_ARRAY_BUFFER, vboID);我不清楚 GL_Array缓冲区的含义。据我所知,它只是向OpenGL当前状态显示此VBO将在某个点存储数组数据。但是从下面的函数中,我可以猜到它不仅是一种数据,而且就像 数据的容器,并且对于当前状态来说只能是 active 。我说对了吗?还是我错过了什么?
  2. glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);同样是这个 GL_Array_Thing 。而且似乎此功能将数据放入GPU或将当前VBO放入VAO?我不确定。
  3. glVertexAttribPointer(0, 3, GL_FLOAT, false, 0,0);因此VAO由属性组成,在这里我们向OpenGL展示了如何读取0属性。如果我错了,请纠正我。
  4. 如果我了解了VAO中的属性如何正常工作,那么我可以将glEnableVertexAttribArray(0);glVertexAttribPointer(0, 3, GL_FLOAT, false, 0,0);这行更改为glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, false, 0,0);。最终渲染没有任何变化,但实际上黑色四边形并未出现。不知道为什么。
  5. 我使用索引来绘制四边形。但是OpenGL在世界上如何理解如何读取我提供的数据,因为我没有指定如何使用它。我只想象这行可以帮助我做到glDrawElements(GL_TRIANGLES, indices.length, GL_UNSIGNED_INT,0);

还有很多其他问题,但是它们之所以出现,是因为我对我上面描述的问题缺乏理解。请帮我弄清楚有关OpenGL基础知识的问题。对于那些能够阅读甚至回答此信息的人-非常感谢!

1 个答案:

答案 0 :(得分:0)

glBindBuffer(GL_ARRAY_BUFFER, vboID);

手段:我有几个VBO。选择(供下次使用)由vboID标识的那个。 GL_ARRAY_BUFFER模式用于原始(字节)数据。

glBufferData(GL_ARRAY_BUFFER, size, buffer, GL_STATIC_DRAW); //Notice I added "size" for C++. LWJGL doesn't need it.

方法:用size个字节填充当前绑定的array_buffer(带有“ glBindBuffer”);从buffer(CPU RAM中的地址)中获取它们。我的目的(GL_STATIC_DRAW是GPU读取数据的次数很多,而不是对其进行修改。

glVertexAttribPointer(0, 3, GL_FLOAT, false, stride, 0,0); // "stride" added

GPU从一个或多个VBO读取。例如,VBO可能由x,y,z坐标(3个浮点数)组成,后跟R,G,B,A颜色分量(4个字节),并对其他顶点重复该序列。
glVertexAttribPointer建立VBO与所需属性之间的关系。在示例中:第一个属性(0)需要3类型的GL_FLOAT值,这些值未经规范化(false)(不在[0.0,1.0]范围内)。该属性的下一个序列是stride个字节远(使用0表示属性被紧紧包装)。最后一个0.0是第一个属性在VBO中的偏移量。

可以从相同的VBO或不同的颜色将颜色读取为另一个属性。该属性的“名称”可能是1,因为0已经用于坐标。因此,它需要自己的glVertexAttribPointer调用。

属性标识符由GPU选择。由于OpenGL> = 3.3(强烈建议使用),因此最好选择它们(通过着色器中的“位置= 0”填充)

VAO包含缓冲区绑定和属性绑定。每次您需要从某些VBO渲染数据时,都不需要再次使用所需的glBindBufferglVertexAttribPointer。只需使用glBindVertexArray

“索引渲染”意味着您使用两个VBO:一个用于坐标,另一个用于索引。 (其他VBO也可以用于其他属性)。带索引的VBO告诉GPU从第一个VBO(和其他VBO)开始的“顺序”顺​​序。这些允许多次读取同一顶点,而无需重复其属性。请注意,三角剖分在多个三角形之间共享相同的顶点。您可以避免将重复的数据发送到GPU。