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)
您的问题不是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)将偏移量传递给每个子缓冲区的起始位置.