Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenGL交错VBO-如何在Scala中获得sizeof(Float)?_Scala_Opengl_Lwjgl_Sizeof_Opengl 3 - Fatal编程技术网

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

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

我一直在尝试从两个不同的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)
    }
}
数据(位置、纹理坐标)与我以前使用的相同,有两个不同的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编译器如何很好地展现这样的函数组合,但是如果它值函数语言的钱,那么实际生成的代码可以很好地优化,直接压缩到一个平面列表中。