OpenGL交错VBO-如何在Scala中获得sizeof(Float)?
我一直在尝试从两个不同的VBO切换到一个具有交错属性的VBO。我可以用C++来做,但是在Scala中,它是很难的。 以下是我的实现:OpenGL交错VBO-如何在Scala中获得sizeof(Float)?,scala,opengl,lwjgl,sizeof,opengl-3,Scala,Opengl,Lwjgl,Sizeof,Opengl 3,我一直在尝试从两个不同的VBO切换到一个具有交错属性的VBO。我可以用C++来做,但是在Scala中,它是很难的。 以下是我的实现: class Mesh(positions: Array[Float], textureCoordinates: Array[Float], indices: Array[Int]) { // Create VAO, VBO and a buffer for the indices val vao: Int = glGenVertexArrays
class Mesh(positions: Array[Float], textureCoordinates: Array[Float], indices: Array[Int])
{
// Create VAO, VBO and a buffer for the indices
val vao: Int = glGenVertexArrays
val vbo: Int = glGenBuffers
val ibo: Int = glGenBuffers
setup
private def setup(): Unit =
{
val interleavedBuffer: FloatBuffer = prepareFloatBuffer(positions ++ textureCoordinates)
val indicesBuffer: IntBuffer = prepareIntBuffer(indices)
// One VAO to bind them all!
glBindVertexArray(vao)
glBindBuffer(GL_ARRAY_BUFFER, vbo)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
// Fill buffers with data
glBufferData(GL_ARRAY_BUFFER, interleavedBuffer, GL_STATIC_DRAW)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL_STATIC_DRAW)
// Set vertex attribute pointers
glVertexAttribPointer(0, 3, GL_FLOAT, false, 4*5, 0) // 0 = Position = Vector3(x,y,z) -> 3 (coordinates) * 4 (byte-size of float)
glVertexAttribPointer(1, 2, GL_FLOAT, false, 4*5, 4*3) // 1 = Texture Coordinates = Vector2(x,y) -> 2 (coordinates) * 4 (byte-size of float) => stride = 3 (coordinates) + 2 (texture coordinates) = 5 * 4 (byte-size of float); offset = 3 (coordinates) * 4 (byte-size of float)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)
}
private def prepareIntBuffer(data: Array[Int]): IntBuffer =
{
val buffer: IntBuffer = BufferUtils.createIntBuffer(data.length)
buffer.put(data)
buffer.flip // Make the buffer readable
buffer
}
private def prepareFloatBuffer(data: Array[Float]): FloatBuffer =
{
val buffer: FloatBuffer = BufferUtils.createFloatBuffer(data.length)
buffer.put(data)
buffer.flip // Make the buffer readable
buffer
}
def render(): Unit =
{
glBindVertexArray(vao)
glBindBuffer(GL_ARRAY_BUFFER, vbo)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
glEnableVertexAttribArray(0) // Vertices are in zero
glEnableVertexAttribArray(1) // Texture Coords are in one
glDrawElements(GL_TRIANGLES, this.indices.length, GL_UNSIGNED_INT, 0)
glDisableVertexAttribArray(1)
glDisableVertexAttribArray(0)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)
}
}
数据(位置、纹理坐标)与我以前使用的相同,有两个不同的VBO
现在:
我该如何计算这些跨步和偏移量
位置是一个向量3(x,y,z),所以3是浮动的。纹理坐标是两个浮动
3+2=5
浮子的大小是。。。我以为是4个字节。(据了解,它是用Java编写的)
那就是20,或者4*5
对于位置的每个坐标,纹理坐标的偏移量将计算为相同的(3*4)
现在,结果看起来不太好
你能猜出它到底应该是什么吗?(扰流板:立方体)
所以,我想要么我的数学完全崩溃了,要么一个浮点数在Scala中可能有不同的大小
在Java中,我可以使用Float.size,但Scala没有任何类似的功能
<>在C++中,我定义了一个结构,并这样做:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, textureCoordinates));
您的问题不是float的大小,而是缓冲区中的数据布局。声明
val interleavedBuffer: FloatBuffer = prepareFloatBuffer(positions ++ textureCoordinates)
创建布局的缓冲区
xyz[0],xyz[1],…,xyz[n],st[0],st[1],…,st[m]
然而,您配置OpenGL所期望的是
xyz[0],st[0],xyz[1],st[1],…,xyz[n],st[n]
您可以在缓冲区中正确地交错属性,告诉OpenGL每个属性的元素是连续的(0步长,或该属性的一个元素的大小,即xyz为3*4,st为2*4),并将偏移量传递到每个子缓冲区的起始位置 您的问题不是float的大小,而是缓冲区中的数据布局。声明
val interleavedBuffer: FloatBuffer = prepareFloatBuffer(positions ++ textureCoordinates)
创建布局的缓冲区
xyz[0],xyz[1],…,xyz[n],st[0],st[1],…,st[m]
然而,您配置OpenGL所期望的是
xyz[0],st[0],xyz[1],st[1],…,xyz[n],st[n]
您可以在缓冲区中正确地交错属性,告诉OpenGL每个属性的元素是连续的(0步长,或该属性的一个元素的大小,即xyz为3*4,st为2*4),并将偏移量传递到每个子缓冲区的起始位置 这在我看来很奇怪:
prepareFloatBuffer(positions++textureCoordinates)
希望这只是因为我看不懂Scala?@AndonM.Coleman:这是数组连接。这在我看来很奇怪:prepareFloatBuffer(positions++textureCoordinates)
希望这只是因为我看不懂Scala?@AndonM.Coleman:这是数组连接。这也是OP问题的根源。在Scala中没有标准的方法来组合两个数组,不是吗?我必须手动建立一个方法来实现这一点吗?@Teolha:是的。它被称为“压缩”,这就是zip
函数的作用。zip不创建元组集合吗?比如数组[(a,b)]?@Teolha:是的,但是你可以使用flatMap
:-我不知道Scala编译器如何展现这样的函数组合,但是,如果它值函数式语言的钱,那么实际生成的代码可以很好地优化,直接压缩到一个平面列表中?我必须手动建立一个方法来实现这一点吗?@Teolha:是的。它被称为“压缩”,这就是zip
函数的作用。zip不创建元组集合吗?像数组[(a,b)]?@Teolha:是的,但是你可以使用flatMap
:-我不知道Scala编译器如何很好地展现这样的函数组合,但是如果它值函数语言的钱,那么实际生成的代码可以很好地优化,直接压缩到一个平面列表中。