2010-11-16 21 views
2

我試圖將我的頂點,索引和紋理點設置爲VBO:s並使用我的繪製方法繪製它們,所有這些都在C#下的TAO/OpenGL TK framwork。但是我的屏幕只顯示黑屏。我已經測試沒有VBO:s,然後它的工作。但是對於我的頂點,索引和紋理點我無法成功。試圖在C#中使用TAO和OpenGL TK框架設置VBO:s

我的代碼:

private float[] vertices; 
private byte[] indices; 
private float[] texture; 

private int[] mVertexBuffer; 
private int[] mIndicesBuffer; 
private int[] mTextureBuffer; 

//...Constructor start 
vertices = new float[] { 
              -1.0f, -1.0f, 1.0f, 
              1.0f, -1.0f, 1.0f, 
              -1.0f, 1.0f, 1.0f, 
              1.0f, 1.0f, 1.0f, 

              1.0f, -1.0f, 1.0f, 
              1.0f, -1.0f, -1.0f, 
              1.0f, 1.0f, 1.0f, 
              1.0f, 1.0f, -1.0f, 

              1.0f, -1.0f, -1.0f, 
              -1.0f, -1.0f, -1.0f, 
              1.0f, 1.0f, -1.0f, 
              -1.0f, 1.0f, -1.0f, 

              -1.0f, -1.0f, -1.0f, 
              -1.0f, -1.0f, 1.0f, 
              -1.0f, 1.0f, -1.0f, 
              -1.0f, 1.0f, 1.0f, 

              -1.0f, -1.0f, -1.0f, 
              1.0f, -1.0f, -1.0f, 
              -1.0f, -1.0f, 1.0f, 
              1.0f, -1.0f, 1.0f, 

              -1.0f, 1.0f, 1.0f, 
              1.0f, 1.0f, 1.0f, 
              -1.0f, 1.0f, -1.0f, 
              1.0f, 1.0f, -1.0f, 
              }; 

texture = new float[] { 
                          0.0f, 1.0f,            1.0f, 1.0f,            0.0f, 0.0f,             1.0f, 0.0f,             
              0.0f, 1.0f, 
              1.0f, 1.0f, 
              0.0f, 0.0f, 
              1.0f, 0.0f, 

              0.0f, 1.0f, 
              1.0f, 1.0f, 
              0.0f, 0.0f, 
              1.0f, 0.0f, 

              0.0f, 1.0f, 
              1.0f, 1.0f, 
              0.0f, 0.0f, 
              1.0f, 0.0f, 

              0.0f, 1.0f, 
              1.0f, 1.0f, 
              0.0f, 0.0f, 
              1.0f, 0.0f, 

              0.0f, 1.0f, 
              1.0f, 1.0f, 
              0.0f, 0.0f, 
              1.0f, 0.0f, 
              }; 

indices = new byte[] { 
              0, 1, 3, 0, 3, 2,            4, 5, 7, 4, 7, 6, 
              8, 9, 11, 8, 11, 10, 
              12, 13, 15, 12, 15, 14, 
              16, 17, 19, 16, 19, 18, 
              20, 21, 23, 20, 23, 22, 
              }; 

mVertexBuffer = new int[1]; 
mIndicesBuffer = new int[1]; 
mTextureBuffer = new int[1]; 

//...Constructor end 

public void setBuffers() { 
     gl.glGenBuffersARB(1, mVertexBuffer); 
     gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, mVertexBuffer[0]); 
     gl.glBufferDataARB(GL.GL_ARRAY_BUFFER_ARB, 
     (IntPtr)(vertices.Length * sizeof(float)), 
    vertices, GL.GL_STATIC_DRAW_ARB); 

     gl.glGenBuffersARB(1, mIndicesBuffer); 
     gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, mIndicesBuffer[0]); 
     gl.glBufferDataARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, 
     (IntPtr)(indices.Length * sizeof(float)), 
    indices, GL.GL_DYNAMIC_DRAW_ARB); 

     gl.glGenBuffersARB(1, mTextureBuffer); 
     gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, mTextureBuffer[0]); 
     gl.glBufferDataARB(GL.GL_ARRAY_BUFFER_ARB, 
     (IntPtr)(texture.Length * sizeof(float)), 
    texture, GL.GL_STATIC_DRAW_ARB); 
    } 

    public void draw() 
    { 
     gl.glBegin(gl.GL_TRIANGLES); 

     gl.glEnableClientState(GL.GL_VERTEX_ARRAY); 
     gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY); 

     gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, mVertexBuffer[0]); 
     gl.glVertexPointer(3, GL.GL_FLOAT, 0, mVertexBuffer); 
     gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, mTextureBuffer[0]); 
     gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, mTextureBuffer); 

     gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, mIndicesBuffer[0]); 

     gl.glDrawElements(GL.GL_TRIANGLES, indices.Length, 
gl.GL_UNSIGNED_BYTE, mIndicesBuffer); 

     gl.glDisableClientState(GL.GL_VERTEX_ARRAY); 
     gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY); 
     gl.glEnd(); 

    } 

頂點/索引/紋理點工作在我的C++ VBO環境,但不是在這裏。所以我猜測我已經錯過了與綁定的東西。

回答

6

其實,我一直在尋找這個幾個星期了。現在我有一個正確的工作解決方案。

您需要注意幾個問題才能成功創建Vertex Buffer Object。第一個問題是人們搞砸了。 GL_INDEX_ARRAY不適合你的indices。當你使用顏色數組來平滑你的vert之間的顏色時,你應該使用GL_INDEX_ARRAY

另一個問題是Tao framework使用IntPtr.Zero作爲偏移而不是普通0。當Vertex Buffer Object時,您將glDrawElements調用中的最後一個參數用作Vertex Array樣式。

另一方面,它看起來像你在混合兩個不同的概念。您正在嘗試將數據加載到緩衝區中,如果您使用發佈的代碼,則完全可以取得成功。但這裏的問題在於您使用錯誤的GL_ARRAY_BUFFER命令。對於您的indices,您應該使用GL_ELEMENT_ARRAY_BUFFER

這樣說我會用標準Vertex Arrays和另一個使用Vertex Buffer Objects顯示一個解決方案。我希望這會清除一切。

頂點數組

public void draw() 
{ 
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY); 
    gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY); 

    gl.glVertexPointer(3, gl.GL_FLOAT, 0, verticesArray); 
    gl.glTexCoordPointer(2, gl.GL_FLOAT, 0, textureArray); 

    //With Vertex Arrays, the last parameter is your pointer to your indices 
    gl.glDrawElements(gl.GL_TRIANGLES, indices.Length, 
           gl.GL_UNSIGNED_SHORT, indicesArray); 

    gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY); 
    gl.glDisableClientState(gl.GL_VERTEX_ARRAY); 
} 

頂點緩衝對象

//This should be used in the constructor 
//or in another method than the draw method 
mVertexBuffer = new int[1]; 
mTextureBuffer = new int[1]; 
mIndexBuffer = new int[1]; 

gl.glGenBuffers(1, mVertexBuffer); 
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, mVertexBuffer[0]); 
gl.glBufferData(gl.GL_ARRAY_BUFFER, 
    (IntPtr)(verticesArray.Length * sizeof(float)), 
        verticesArray, gl.GL_STATIC_DRAW); 

gl.glGenBuffers(1, mTextureBuffer); 
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, mTextureBuffer[0]); 
gl.glBufferData(gl.GL_ARRAY_BUFFER, 
    (IntPtr)(textureArray.Length * sizeof(float)), 
        textureArray, gl.GL_STATIC_DRAW); 

gl.glGenBuffers(1, mIndexBuffer); 
gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer[0]); 
gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, 
    (IntPtr)(indicesArray.Length * sizeof(short)), 
        indicesArray, gl.GL_STATIC_DRAW); 

//Your draw method 
public void draw() 
{  
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY); 
    gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY); 

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, mVertexBuffer[0]); 

    //Notice: IntPtr.Zero is used... 
    gl.glVertexPointer(3, gl.GL_FLOAT, 0, IntPtr.Zero); 

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, mTextureBuffer[0]); 

    //Notice: IntPtr.Zero is used... 
    gl.glTexCoordPointer(2, gl.GL_FLOAT, 0, IntPtr.Zero); 
    gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer[0]); 

    //Notice: IntPtr.Zero is used. Last parameter is 
    //an offset using Vertex Buffer Objects and in Vertex Arrays 
    //it is a pointer 
    gl.glDrawElements(gl.GL_TRIANGLES, indices.Length, 
      gl.GL_UNSIGNED_SHORT, IntPtr.Zero); 

    //Remember to unbind your buffer to prevent it to destroy 
    //other draw calls or objects 
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0); 
    gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, 0); 

    gl.glDisableClientState(gl.GL_VERTEX_ARRAY); 
    gl.glDisableClientState(gl.GL_TEXTURE_COORD_ARRAY);    
} 

我希望這是有益的,我花了一段時間來弄清楚這一點。

1

內聯評論/修改。我沒有設置測試這個,但它很接近:

public void draw() 
    { 
     //gl.glBegin(gl.GL_TRIANGLES); // no glBegin/glEnd at all -- that's immediate mode 

     gl.glEnableClientState(GL.GL_VERTEX_ARRAY); 
     gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY); 
     gl.glEnableClientState(GL.GL_INDEX_ARRAY); // also using index array 

     gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, mVertexBuffer[0]); 
     gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0); // with vertex arrays the last argument is a pointer, with VBOs it's an *offset* 
     gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, mTextureBuffer[0]); 
     gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0); // ditto 

     gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, mIndicesBuffer[0]); 

     //gl.glDrawElements(GL.GL_TRIANGLES, indices.Length, gl.GL_UNSIGNED_BYTE, mIndicesBuffer); // this is vertex-array style 
     gl.glIndexPointer(GL.GL_UNSIGNED_BYTE, 0, 0); // as above for all pointers 
     gl.glDrawArrays(GL.GL_TRIANGLES, 0, indices.length); 

     // You can probably leave these enabled to save time: 
     gl.glDisableClientState(GL.GL_VERTEX_ARRAY); 
     gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY); 
     gl.glDisableClientState(GL.GL_INDEX_ARRAY);    
     //gl.glEnd(); 

    } 
+0

我將對此進行測試。 – Curtain 2010-11-21 16:09:57

+0

嗯,不能讓它工作。我只能看到一個黑屏...感謝您提供的信息。真的非常感謝你爲此付出了時間。我相信這是正確的。 – Curtain 2010-11-21 16:21:16

+0

'GL_INDEX_ARRAY'不適用於'indices'。看看OpenGL文檔。 – Wroclai 2010-11-27 16:20:45

1

下面是根據雪萊的回答工人階級例如:

class Vbo { 
    private float[] vertices; 
    private ushort[] indices; 
    private float[] texture; 

    private int[] mVertexBuffer; 
    private int[] mIndicesBuffer; 
    private int[] mTextureBuffer; 

    public Vbo() { 
     vertices = new float[] { 
             -1.0f, -1.0f, 1.0f, 
             1.0f, -1.0f, 1.0f, 
             -1.0f, 1.0f, 1.0f, 
             1.0f, 1.0f, 1.0f, 

             1.0f, -1.0f, 1.0f, 
             1.0f, -1.0f, -1.0f, 
             1.0f, 1.0f, 1.0f, 
             1.0f, 1.0f, -1.0f, 

             1.0f, -1.0f, -1.0f, 
             -1.0f, -1.0f, -1.0f, 
             1.0f, 1.0f, -1.0f, 
             -1.0f, 1.0f, -1.0f, 

             -1.0f, -1.0f, -1.0f, 
             -1.0f, -1.0f, 1.0f, 
             -1.0f, 1.0f, -1.0f, 
             -1.0f, 1.0f, 1.0f, 

             -1.0f, -1.0f, -1.0f, 
             1.0f, -1.0f, -1.0f, 
             -1.0f, -1.0f, 1.0f, 
             1.0f, -1.0f, 1.0f, 

             -1.0f, 1.0f, 1.0f, 
             1.0f, 1.0f, 1.0f, 
             -1.0f, 1.0f, -1.0f, 
             1.0f, 1.0f, -1.0f, 
             }; 

     texture = new float[] { 
                         0.0f, 1.0f,            1.0f, 1.0f,            0.0f, 0.0f,             1.0f, 0.0f,             
             0.0f, 1.0f, 
             1.0f, 1.0f, 
             0.0f, 0.0f, 
             1.0f, 0.0f, 

             0.0f, 1.0f, 
             1.0f, 1.0f, 
             0.0f, 0.0f, 
             1.0f, 0.0f, 

             0.0f, 1.0f, 
             1.0f, 1.0f, 
             0.0f, 0.0f, 
             1.0f, 0.0f, 

             0.0f, 1.0f, 
             1.0f, 1.0f, 
             0.0f, 0.0f, 
             1.0f, 0.0f, 

             0.0f, 1.0f, 
             1.0f, 1.0f, 
             0.0f, 0.0f, 
             1.0f, 0.0f, 
             }; 

     indices = new ushort[] { 
             0, 1, 3, 0, 3, 2,            4, 5, 7, 4, 7, 6, 
             8, 9, 11, 8, 11, 10, 
             12, 13, 15, 12, 15, 14, 
             16, 17, 19, 16, 19, 18, 
             20, 21, 23, 20, 23, 22, 
             }; 

     for (int i = 0; i < vertices.Length; i++) { 
      vertices[i] *= 2; 
     } 

     mVertexBuffer = new int[1]; 
     mIndicesBuffer = new int[1]; 
     mTextureBuffer = new int[1]; 



     Gl.glGenBuffers(1, mVertexBuffer); 
     Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, mVertexBuffer[0]); 
     Gl.glBufferData(Gl.GL_ARRAY_BUFFER, 
      (IntPtr)(vertices.Length * sizeof(float)), 
          vertices, Gl.GL_STATIC_DRAW); 

     Gl.glGenBuffers(1, mTextureBuffer); 
     Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, mTextureBuffer[0]); 
     Gl.glBufferData(Gl.GL_ARRAY_BUFFER, 
      (IntPtr)(texture.Length * sizeof(float)), 
          texture, Gl.GL_STATIC_DRAW); 

     Gl.glGenBuffers(1, mIndicesBuffer); 
     Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, mIndicesBuffer[0]); 
     Gl.glBufferData(Gl.GL_ELEMENT_ARRAY_BUFFER, 
      (IntPtr)(indices.Length * sizeof(ushort)), 
          indices, Gl.GL_STATIC_DRAW); 
    } 

    public void Render() { 
     Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY); 
     Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY); 

     Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, mVertexBuffer[0]); 

     //Notice: IntPtr.Zero is used... 
     Gl.glVertexPointer(3, Gl.GL_FLOAT, 0, IntPtr.Zero); 

     Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, mTextureBuffer[0]); 

     //Notice: IntPtr.Zero is used... 
     Gl.glTexCoordPointer(2, Gl.GL_FLOAT, 0, IntPtr.Zero); 
     Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, mIndicesBuffer[0]); 

     //Notice: IntPtr.Zero is used. Last parameter is 
     //an offset using Vertex Buffer Objects and in Vertex Arrays 
     //it is a pointer 
     Gl.glDrawElements(Gl.GL_TRIANGLES, indices.Length, Gl.GL_UNSIGNED_SHORT, IntPtr.Zero); 

     //Remember to unbind your buffer to prevent it to destroy 
     //other draw calls or objects 
     Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0); 
     Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, 0); 

     Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY); 
     Gl.glDisableClientState(Gl.GL_TEXTURE_COORD_ARRAY); 
    } 
}