stoney78us's picture

Drawing multiple objects from one Vertex Buffer Object in OpenGL/OpenTK

I am trying to experimenting drawing method using VBO in OpenGL. Many people normally use 1 vbo to store one object data array. I was trying to do something quite opposite which is storing multiple object data into 1 vbo then drawing it. There is story behind why i want to do this. I want to group many of objects as a single object sometime. However my code doesn't do the justice. Following is my pseudo code:

    //Data
    int[] _vBO = new int[1]; //vertex buffer objects
 
    _triangleVertices = new float[] 
                      { 0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, //first triangle lineloop, positions in the middle of the screen.
                        3.0f, 1.0f, 0.0f, 2.0f, -1.0f, 0.0f, 4.0f, -1.0f, 0.0f, //second triangle lineloop, positions on the left side of the first triangle.
                        -3.0f, 1.0f, 0.0f, -4.0f, -1.0f, 0.0f, -2.0f, -1.0f, 0.0f  }; //third triangle lineloop, positions on the right side of the first triangle.
 
    //Setting Up
    void init()
    {
       GL.GenBuffers(1, _vBO);
       GL.BindBuffer(BufferTarget.ArrayBuffer, _vBO[0]);
       GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(sizeof(float) * _triangleVertices.Length), _triangleVertices, BufferUsageHint.StaticDraw);
       GL.VertexPointer(3, VertexPointerType.Float, 0, 0);
       GL.EnableClientState(Array.VertexArray);
    }
 
    //Drawing
    void display()
    {
        GL.Clear(ClearBufferMask.ColorBufferBit);
        GL.Clear(ClearBufferMask.DepthBufferBit);
 
        //setting up camera and projection.
        float[] eyes = { 0.0f, 0.0f, -10.0f };
        float[] target = { 0.0f, 0.0f, 0.0f };
        Matrix4 projection = Matrix4.CreatePerspectiveFieldOfView(0.785398163f, 4.0f / 3.0f, 0.1f, 100f);  //45 degree = 0.785398163 rads
        Matrix4 view = Matrix4.LookAt(eyes[0], eyes[1], eyes[2], target[0], target[1], target[2], 0, 1, 0);
        Matrix4 model = Matrix4.Identity;
        Matrix4 MV = view * model;
 
        GL.MatrixMode(MatrixMode.Projection);
        GL.LoadIdentity();
        GL.LoadMatrix(ref projection);
 
        GL.MatrixMode(MatrixMode.Modelview);
        GL.LoadIdentity();
        GL.LoadMatrix(ref MV);
 
 
        GL.Viewport(0, 0, glControlWindow.Width, glControlWindow.Height);
        GL.Enable(EnableCap.DepthTest); //Enable correct Z Drawings
        GL.DepthFunc(DepthFunction.Less); //Enable correct Z Drawings
        GL.MatrixMode(MatrixMode.Modelview);
 
        //Draw
        drawTriangleLineLoops();
 
 
        //Finally...
        GraphicsContext.CurrentContext.VSync = true; //Caps frame rate as to not over run GPU
        glControlWindow.SwapBuffers(); //Takes from the 'GL' and puts into control
    }
 
 
    void drawTriangleLineLoops()
    {
       GL.BindBuffer(BufferTarget.ArrayBuffer, _vBO[0]);
       GL.VertexPointer(3, VertexPointerType.Float, 0, 0);
       GL.EnableClientState(ArrayCap.VertexArray);
       GL.DrawArrays(BeginMode.LineLoop, 0, 3); //drawing first triangle lineloop, first vertex starts at index 0.
       GL.DrawArrays(BeginMode.LineLoop, 9, 3); //drawing second triangle lineloop, first vertex starts at index 9.
       GL.DrawArrays(BeginMode.LineLoop, 18, 3); //drawing third triangle lineloop, first vertex starts at index 18.
       GL.DisableClientState(ArrayCap.VertexArray);
    }

I expect 3 different triangles to be drawn, but only one was drawn. I don't know what went wrong.

Inline Images
TriangleLineLoops

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
flopoloco's picture

From what I see is better to go fully OpenGL3 because once something goes wrong, you can spot the problem ASAP, there are lots of active projects and references to look.

Try these stuff instead.
For more information look here...
http://www.opentk.com/node/2293

Create VAO
1) Generate vertex array and 2) bind it
3) EnableVertexAttribArray and 4) set VertexAttribPointer (repeat for each data struct)

Draw VAO
1) BindVertexArray, 2) EnableVertexAttribArray, 3) DrawArrays (extremely important to call only once),

the Fiddler's picture
stoney78us wrote:

I am trying to experimenting drawing method using VBO in OpenGL. Many people normally use 1 vbo to store one object data array. I was trying to do something quite opposite which is storing multiple object data into 1 vbo then drawing it. There is story behind why i want to do this. I want to group many of objects as a single object sometime. However my code doesn't do the justice. Following is my pseudo code:
[...]
I don't know what i did wrong but i think technically it should work where we can tell OpenGL which part of the data in the vBO to be drawn.

Your code appears alright to me. What output are you getting?

Check if GL.GetErrors() returns anything interesting.

stoney78us's picture

I just rewrote my code which might describe my problem better. the second and third calls of GL.DrawArrays don't work at all.

the Fiddler's picture

glDrawArrays parameter first is the vertex index, interpreted according to your vertex format.

            GL.DrawArrays(BeginMode.LineLoop, 0, 3); //drawing first triangle lineloop, first vertex starts at index 0.
            GL.DrawArrays(BeginMode.LineLoop, 3, 3); //drawing second triangle lineloop, first vertex starts at index 3.
            GL.DrawArrays(BeginMode.LineLoop, 6, 3); //drawing third triangle lineloop, first vertex starts at index 6.

Furthermore, you don't need to enable vsync every frame, just once in your init.