2010-11-16 32 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); 
    } 
} 
相关问题