OpenGL交错的VBO - 如何在Scala中获取sizeof(Float)?

Sor*_*ona 0 opengl scala sizeof lwjgl 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
    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)
    }
}
Run Code Online (Sandbox Code Playgroud)

数据(位置,textureCoordinates)与我之前使用的相同,有两个不同的VBO.

现在:

glVertexAttribPointer(0, 3, GL_FLOAT, false, 4*5, 0)
glVertexAttribPointer(1, 2, GL_FLOAT, false, 4*5, 4*3)
Run Code Online (Sandbox Code Playgroud)

我如何计算你问的这些步幅和补偿?

好吧,位置是Vector3(x,y,z)所以3浮动.纹理坐标是两个浮点数.

3 + 2 = 5

浮点数的大小......好吧,我认为它是4个字节.(根据http://wiki.lwjgl.org/wiki/The_Quad_interleaved它是用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));
Run Code Online (Sandbox Code Playgroud)

dat*_*olf 5

您的问题不是sizeof float,而是缓冲区中的数据布局.该声明

val interleavedBuffer: FloatBuffer = prepareFloatBuffer(positions ++ textureCoordinates)
Run Code Online (Sandbox Code Playgroud)

创建布局的缓冲区

xyz[0],xyz[1],…,xyz[n],st[0],st[1],…,st[m]
Run Code Online (Sandbox Code Playgroud)

然而,您配置OpenGL的期望是

xyz[0],st[0],xyz[1],st[1],…,xyz[n],st[n]
Run Code Online (Sandbox Code Playgroud)

你可以正确地交错缓冲区中的属性,你告诉OpenGL每个属性的元素是连续的(0步,或者该属性的一个元素的大小,即xyz为3*4,st为2*4)将偏移量传递给每个子缓冲区的起始位置.