我一直試圖從兩個不同的VBO切換到只有一個具有交錯屬性。我可以用C++來完成,但在Scala中證明它非常困難。OpenGL交錯VBO - 如何在Scala中獲取sizeof(Float)?
這是我實現:
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)
}
}
的數據(位置,textureCoordinates)是我之前使用的一樣,用兩個不同的駐國際中心組織他們。
現在:
glVertexAttribPointer(0, 3, GL_FLOAT, false, 4*5, 0)
glVertexAttribPointer(1, 2, GL_FLOAT, false, 4*5, 4*3)
如何計算這些進步和偏移你問?
那麼,position是一個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));
這看起來對我來說很奇怪:'prepareFloatBuffer(位置++ textureCoordinates)'希望這是因爲我無法讀取Scala? –
@ AndonM.Coleman:這是數組連接。也是OP問題的根源。 – datenwolf