Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: Trying in vain to get a VBO implementation working

  1. #1
    Junior Member Newbie
    Join Date
    Sep 2011
    Posts
    19

    Trying in vain to get a VBO implementation working

    I've wrestled with VBOs for quite some time, never satisfactorily implementing a class in C++ that handles the basic "VNT" VBO (one which most readily replaces immediate mode).

    I have read almost every tutorial worth a glance on the net and I have got to the following situation through careful implementation and reading many different function specifications, tutorials and Wiki entries on the topic.

    I fully understand that VBOs have components defined in a C struct that are then passed to the GPU via glBufferData and related functions. I understand indices and 'auto-interleaving' as well as the optimal type choices.

    I'm confused about the usefulness of a VAO, and even how to create one. However, the thing I'm trying to accomplish shouldn't require one, based on "VBO Examples" from the Wiki.


    Situation:
    I have a list of triangles indexed in a linked list of linked lists of vertexes.

    I copied these from a unit cube PLY:

    unitcube.ply:

    ply
    format ascii 1.0
    comment Cube
    element vertex 24
    property float x
    property float y
    property float z
    property float nx
    property float ny
    property float nz
    element face 6
    property list uchar uint vertex_indices
    end_header
    1.000000 1.000000 -1.000000 0.000000 0.000000 -1.000000
    1.000000 -1.000000 -1.000000 0.000000 0.000000 -1.000000
    -1.000000 -1.000000 -1.000000 0.000000 0.000000 -1.000000
    -1.000000 1.000000 -1.000000 0.000000 0.000000 -1.000000
    1.000000 0.999999 1.000000 0.000000 -0.000000 1.000000
    -1.000000 1.000000 1.000000 0.000000 -0.000000 1.000000
    -1.000000 -1.000000 1.000000 0.000000 -0.000000 1.000000
    0.999999 -1.000001 1.000000 0.000000 -0.000000 1.000000
    1.000000 1.000000 -1.000000 1.000000 -0.000000 0.000000
    1.000000 0.999999 1.000000 1.000000 -0.000000 0.000000
    0.999999 -1.000001 1.000000 1.000000 -0.000000 0.000000
    1.000000 -1.000000 -1.000000 1.000000 -0.000000 0.000000
    1.000000 -1.000000 -1.000000 -0.000000 -1.000000 -0.000000
    0.999999 -1.000001 1.000000 -0.000000 -1.000000 -0.000000
    -1.000000 -1.000000 1.000000 -0.000000 -1.000000 -0.000000
    -1.000000 -1.000000 -1.000000 -0.000000 -1.000000 -0.000000
    -1.000000 -1.000000 -1.000000 -1.000000 0.000000 -0.000000
    -1.000000 -1.000000 1.000000 -1.000000 0.000000 -0.000000
    -1.000000 1.000000 1.000000 -1.000000 0.000000 -0.000000
    -1.000000 1.000000 -1.000000 -1.000000 0.000000 -0.000000
    1.000000 0.999999 1.000000 0.000000 1.000000 0.000000
    1.000000 1.000000 -1.000000 0.000000 1.000000 0.000000
    -1.000000 1.000000 -1.000000 0.000000 1.000000 0.000000
    -1.000000 1.000000 1.000000 0.000000 1.000000 0.000000
    4 0 1 2 3
    4 4 5 6 7
    4 8 9 10 11
    4 12 13 14 15
    4 16 17 18 19
    4 20 21 22 23
    [/B]

    The quads are split into the corresponding triangles, and the draw method is GL_TRIANGLES.

    Normals are calculated on each triangle before they are passed to the GPU, or use the ones from the file, with no difference.

    I have tried both the open ended and "deprecated?" method:

    glEnableVertexAttribArray(0); // Vertices on stream 0
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VBO_VNTC), BUFFER_OFFSET(0));
    glEnableVertexAttribArray(1); // Normals on stream 1
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VBO_VNTC), BUFFER_OFFSET(4+4+4));
    glEnableVertexAttribArray(2); // Texture coordinates on stream 2
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VBO_VNTC), BUFFER_OFFSET(4*3+4*3));
    glEnableVertexAttribArray(3); // RGBA color values on stream 3


    or


    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, sizeof(VBO_VNT), BUFFER_OFFSET(0));
    glEnableClientState(GL_NORMAL_ARRAY);
    glNormalPointer(GL_FLOAT, sizeof(VBO_VNT), BUFFER_OFFSET(4+4+4));
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(2, GL_FLOAT, sizeof(VBO_VNT), BUFFER_OFFSET(4*3+4*3));



    I use this line to render:

    glDrawElements(draw_method,count,preferred_type_en um,BUFFER_OFFSET(0));


    It renders the VBO red (a good sign) except it's just not the same cube (features are missing). Face culling on or off makes no difference in the output. What gives?

    Over top of this, I also ran through each triangle in immediate mode, transparently adding "green" versions over the "red" VBO render pass.

    The output for a cube is garbled on the VBO, yet looks fine on the immediate mode.

    Both used GL_TRIANGLES and the same source data.

  2. #2
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948

    Re: Trying in vain to get a VBO implementation working

    Your data appears to lack either texture coordinates or normals. Showing us a file is meaningless if that's not exactly what you load up into your buffer. Show us the buffer itself.

    Also, learn to use [ code ] tags.

  3. #3
    Junior Member Newbie
    Join Date
    Sep 2011
    Posts
    19

    Re: Trying in vain to get a VBO implementation working

    TCs are calculated for this test with "poots mapping" -- not that it matters because I'm not providing any texture.

    Render segment:
    Code :
     void Render() {
    //  glDisable(GL_CULL_FACE);
      lap.Apply();
      glMatrixMode(GL_MODELVIEW);
      glPushMatrix();
      glTranslatef((GLfloat) position.x,(GLfloat) position.y,(GLfloat) position.z);
      glRotatef((GLfloat) rotation.x, 1.0, 0.0, 0.0);
      glRotatef((GLfloat) rotation.y, 0.0, 0.0, 1.0);
      glColor3d(1.0,0.0,0.0);
    //  lights.On();
      vbo.Render();
      Blending(transparency);
      glColor4d(0.0,1.0,0.0,0.25);
      test->model.Render();
    //  lights.Off();
      glPopMatrix();
    //  glEnable(GL_CULL_FACE);
     }

    Normals are calculated for this test with the following:
    Code :
    // Given a triangle, calculate the normal. (Windedness matters here.)
    Vertex *Vertex::TriNormal( Vertex *a, Vertex *b, Vertex *c ) {
     Vertex *normal=new Vertex;
     Vertex U; U.Subtract(b,a);
     Vertex V; V.Subtract(c,a);
     normal->x=(U.y * V.z) - (U.z * V.y);
     normal->y=(U.z * V.x) - (U.x * V.z);
     normal->z=(U.x * V.y) - (U.y * V.x);
     normal->normalize();
     return normal;
    }

    Screenshots of debugger output is attached.
    Output from the debugger showing all of the data in the VBO at the time of uploading is in attached as PDF.

  4. #4
    Junior Member Newbie
    Join Date
    Sep 2011
    Posts
    19

    Re: Trying in vain to get a VBO implementation working

    Still trying to get this one solved.

  5. #5
    Junior Member Newbie
    Join Date
    Sep 2011
    Posts
    19

    Re: Trying in vain to get a VBO implementation working

    This problem was solved when I noted that count did not include the right value. Also, glDrawElements() was used in the render and I switched to glDrawRangeElements()

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •