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 4 of 4

Thread: Whats with with my VBO code?

  1. #1
    Junior Member Newbie
    Join Date
    Feb 2010
    Posts
    20

    Whats with with my VBO code?

    I agree this is pretty boiled down but this is where something I believe is a miss. In here I have three calls. One to build a VBO object, one to render the VBO object and one to render using Vertex Arrays. The application calls either RenderVBO() or RenderArrays() based on the state of a key passing the same arguments to each method, BuildVBO is always called.

    The RenderArrays renders properly with geometry, lighting and texels using the activated shader. The RenderVBO call renders the geometry and lighting correctly but the texels are random. See attached screen shots. Not sure whats wrong. Do I need to pass the buffer offsets along somewhere for texels? Why would lighting work if that's the case?

    For anyone who may ask the code branch is...

    if (blnUseVBO) {
    VBO
    .Instance.RenderVBO(objModel.arySegments[0], a_vVertex, a_vNormal, a_vTexel);
    } else {
    VBO
    .Instance.RenderArrays(objModel.arySegments[0], a_vVertex, a_vNormal, a_vTexel);
    }

    BTW...This is some C# code using OpenTK and TAO.Compatibility in a Windows form for rapid development.

    Any insight is greatly appreciated.

    Code :
    using System;
     
    using Tao.OpenGl;
     
    using Engine;
    using Engine.DataTypes;
    using Engine.MathLib;
     
    namespace VBOShaders
    {
      class VBO : Singleton<VBO>
      {
        public void BuildVBO(Segment objSegment)
        {
          // Calculate sizes
          int tri_buf_size = objSegment.intTriangleCount * Vector3s.SizeInBytes;  // Size of triangle array in bytes
          int vrt_buf_size = objSegment.intVertexCount   * Vector3f.SizeInBytes;  //         vertex
          int nrm_buf_size = objSegment.intVertexCount   * Vector3f.SizeInBytes;  //         normal
          int txl_buf_size = objSegment.intVertexCount   * Vector2f.SizeInBytes;  //         texel
          int geo_buf_size = vrt_buf_size + nrm_buf_size + txl_buf_size;          // all geometry arrays in bytes
          int offset = 0;                                                          // current buffer starting location
     
          // Setup geometry array and allocate space
          Gl.glGenBuffers(1, out objSegment.geometryVBOId);
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, objSegment.geometryVBOId);
          Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)geo_buf_size, IntPtr.Zero, Gl.GL_STATIC_DRAW);
     
          // Copy geometry data to the hardware buffer starting at offset
          Gl.glBufferSubData(Gl.GL_ARRAY_BUFFER, (IntPtr)offset, (IntPtr)vrt_buf_size, objSegment.aryVertexes);
          offset += vrt_buf_size;
          Gl.glBufferSubData(Gl.GL_ARRAY_BUFFER, (IntPtr)offset, (IntPtr)nrm_buf_size, objSegment.aryVNormals);
          offset += nrm_buf_size;
          Gl.glBufferSubData(Gl.GL_ARRAY_BUFFER, (IntPtr)offset, (IntPtr)txl_buf_size, objSegment.aryVertexes);
     
          // Setup indices array and allocate space
          Gl.glGenBuffers(1, out objSegment.indicesVBOId);
          Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, objSegment.indicesVBOId);
          Gl.glBufferData(Gl.GL_ELEMENT_ARRAY_BUFFER, (IntPtr)tri_buf_size, IntPtr.Zero, Gl.GL_STATIC_DRAW);
     
          // Copy index data to the hardware buffer starting at offset 0
          Gl.glBufferSubData(Gl.GL_ELEMENT_ARRAY_BUFFER, IntPtr.Zero, (IntPtr)tri_buf_size, objSegment.aryTriangles);
     
          // Unbind any buffers so remaining GL stays happy
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);
          Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, 0);
        }
     
        public void RenderVBO(Segment objSegment, int a_vVertex, int a_vNormal, int a_vTexel)
        {
          // Step 1 
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, objSegment.geometryVBOId);
          Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, objSegment.indicesVBOId);
     
          // Step 2 
          Gl.glEnableVertexAttribArray(a_vVertex);
          Gl.glVertexAttribPointer(a_vVertex, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, IntPtr.Zero);
          Gl.glEnableVertexAttribArray(a_vNormal);
          Gl.glVertexAttribPointer(a_vNormal, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, IntPtr.Zero);
          Gl.glEnableVertexAttribArray(a_vTexel);
          Gl.glVertexAttribPointer(a_vTexel, 2, Gl.GL_FLOAT, Gl.GL_FALSE, 0, IntPtr.Zero);
     
          // Step 3 
          int tcount = objSegment.intTriangleCount * 3;
          Gl.glDrawElements(Gl.GL_TRIANGLES, tcount, Gl.GL_UNSIGNED_SHORT, IntPtr.Zero);
     
          // Step 4 
          Gl.glDisableVertexAttribArray(a_vVertex);
          Gl.glDisableVertexAttribArray(a_vNormal);
          Gl.glDisableVertexAttribArray(a_vTexel);
     
          // Step 5 
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);
          Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, 0);
        }
     
        public void RenderArrays(Segment objSegment, int a_vVertex, int a_vNormal, int a_vTexel)
        {
          // Step 2 
          Gl.glEnableVertexAttribArray(a_vVertex);
          Gl.glVertexAttribPointer(a_vVertex, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, objSegment.aryVertexes);
          Gl.glEnableVertexAttribArray(a_vNormal);
          Gl.glVertexAttribPointer(a_vNormal, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, objSegment.aryVNormals);
          Gl.glEnableVertexAttribArray(a_vTexel);
          Gl.glVertexAttribPointer(a_vTexel, 2, Gl.GL_FLOAT, Gl.GL_FALSE, 0, objSegment.aryVTexels);
     
          // Step 3 
          int tcount = objSegment.intTriangleCount * 3;
          Gl.glDrawElements(Gl.GL_TRIANGLES, tcount, Gl.GL_UNSIGNED_SHORT, objSegment.aryTriangles);
     
          // Step 4 
          Gl.glDisableVertexAttribArray(a_vVertex);
          Gl.glDisableVertexAttribArray(a_vNormal);
          Gl.glDisableVertexAttribArray(a_vTexel);
        }
      }
    }
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	vbo.jpg 
Views:	73 
Size:	58.3 KB 
ID:	941   Click image for larger version. 

Name:	array.jpg 
Views:	70 
Size:	29.9 KB 
ID:	940  
    Last edited by bmcclint_gl; 01-12-2013 at 03:36 PM.

  2. #2
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    456
    The offsets you provide in RenderVBO() should be the same as the offsets you loaded the data to in BuildVBO():
    Code :
    offset =0;
    glVertexAttribPointer(..., (IntPtr)offset);
    offset+=vrt_buf_size;
    glVertexAttribPointer(..., (IntPtr)offset);
    offset+=nrm_buf_size;
    glVertexAttribPointer(..., (IntPtr)offset);

  3. #3
    Junior Member Newbie
    Join Date
    Feb 2010
    Posts
    20
    You know I actually tried this prior to posting but with no change. I am actually tracking the offsets in the structure with the VBO Ids. I added logic as suggested and no change.

    See below.

    What gets me though is the normal appear to be correct. My diffuse and specular lighting is correct. I only see this affect when adding texture coordinates. I still need to add tangents and the like so I can only suspect the problem to get worse.

    I'm beginning to suspect the TAO framework/driver implementation. I may need to port to C++ and see if its a .Net/Managed issue or an actual problem with the logic. It's either something really simple that I am overlooking or in an area I cannot address.

    Anyone have an thoughts?

    Code :
    using System;
     
    using Tao.OpenGl;
     
    using Engine;
    using Engine.DataTypes;
    using Engine.MathLib;
     
    namespace VBOShaders
    {
      class VBO : Singleton<VBO>
      {
        public void BuildVBO(Segment objSegment)
        {
          // Calculate sizes
          int tri_buf_size = objSegment.intTriangleCount * Vector3s.SizeInBytes;  // Size of triangle array in bytes
          int vrt_buf_size = objSegment.intVertexCount   * Vector3f.SizeInBytes;  //         vertex
          int nrm_buf_size = objSegment.intVertexCount   * Vector3f.SizeInBytes;  //         normal
          int txl_buf_size = objSegment.intVertexCount   * Vector2f.SizeInBytes;  //         texel
          int geo_buf_size = vrt_buf_size + nrm_buf_size + txl_buf_size;          // all geometry arrays in bytes
          int offset = 0;                                                          // current buffer starting location
     
          // Setup geometry array and allocate space
          Gl.glGenBuffers(1, out objSegment.geometryVBOId);
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, objSegment.geometryVBOId);
          Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)geo_buf_size, IntPtr.Zero, Gl.GL_STATIC_DRAW);
     
          // Copy geometry data to the hardware buffer starting at offset
          Gl.glBufferSubData(Gl.GL_ARRAY_BUFFER, (IntPtr)offset, (IntPtr)vrt_buf_size, objSegment.aryVertexes);
          offset += vrt_buf_size;
          Gl.glBufferSubData(Gl.GL_ARRAY_BUFFER, (IntPtr)offset, (IntPtr)nrm_buf_size, objSegment.aryVNormals);
          offset += nrm_buf_size;
          Gl.glBufferSubData(Gl.GL_ARRAY_BUFFER, (IntPtr)offset, (IntPtr)txl_buf_size, objSegment.aryVertexes);
     
          // Setup indices array and allocate space
          Gl.glGenBuffers(1, out objSegment.indicesVBOId);
          Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, objSegment.indicesVBOId);
          Gl.glBufferData(Gl.GL_ELEMENT_ARRAY_BUFFER, (IntPtr)tri_buf_size, IntPtr.Zero, Gl.GL_STATIC_DRAW);
     
          // Copy index data to the hardware buffer starting at offset 0
          Gl.glBufferSubData(Gl.GL_ELEMENT_ARRAY_BUFFER, IntPtr.Zero, (IntPtr)tri_buf_size, objSegment.aryTriangles);
     
          // Unbind any buffers so remaining GL stays happy
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);
          Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, 0);
        }
     
        public void RenderVBO(Segment objSegment, int a_vVertex, int a_vNormal, int a_vTexel)
        {
          int vrt_buf_size = objSegment.intVertexCount   * Vector3f.SizeInBytes;  //         vertex
          int nrm_buf_size = objSegment.intVertexCount   * Vector3f.SizeInBytes;  //         normal
          int offset = 0;                                                          // current buffer starting location
     
          // Step 1 
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, objSegment.geometryVBOId);
          Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, objSegment.indicesVBOId);
     
          // Step 2 
          Gl.glEnableVertexAttribArray(a_vVertex);
          Gl.glVertexAttribPointer(a_vVertex, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, (IntPtr)offset);
          offset += vrt_buf_size;
          Gl.glEnableVertexAttribArray(a_vNormal);
          Gl.glVertexAttribPointer(a_vNormal, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, (IntPtr)offset);
          offset += nrm_buf_size;
          Gl.glEnableVertexAttribArray(a_vTexel);
          Gl.glVertexAttribPointer(a_vTexel,  2, Gl.GL_FLOAT, Gl.GL_FALSE, 0, (IntPtr)offset);
     
          // Step 3 
          int tcount = objSegment.intTriangleCount * 3;
          Gl.glDrawElements(Gl.GL_TRIANGLES, tcount, Gl.GL_UNSIGNED_SHORT, IntPtr.Zero);
     
          // Step 4 
          Gl.glDisableVertexAttribArray(a_vVertex);
          Gl.glDisableVertexAttribArray(a_vNormal);
          Gl.glDisableVertexAttribArray(a_vTexel);
     
          // Step 5 
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);
          Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, 0);
        }
     
        public void RenderArrays(Segment objSegment, int a_vVertex, int a_vNormal, int a_vTexel)
        {
          // Step 2 
          Gl.glEnableVertexAttribArray(a_vVertex);
          Gl.glVertexAttribPointer(a_vVertex, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, objSegment.aryVertexes);
          Gl.glEnableVertexAttribArray(a_vNormal);
          Gl.glVertexAttribPointer(a_vNormal, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, objSegment.aryVNormals);
          Gl.glEnableVertexAttribArray(a_vTexel);
          Gl.glVertexAttribPointer(a_vTexel, 2, Gl.GL_FLOAT, Gl.GL_FALSE, 0, objSegment.aryVTexels);
     
          // Step 3 
          int tcount = objSegment.intTriangleCount * 3;
          Gl.glDrawElements(Gl.GL_TRIANGLES, tcount, Gl.GL_UNSIGNED_SHORT, objSegment.aryTriangles);
     
          // Step 4 
          Gl.glDisableVertexAttribArray(a_vVertex);
          Gl.glDisableVertexAttribArray(a_vNormal);
          Gl.glDisableVertexAttribArray(a_vTexel);
        }
      }
    }

  4. #4
    Junior Member Newbie
    Join Date
    Feb 2010
    Posts
    20
    Solved...Kinda...

    OK...Found another post where new buffers were created for each array of information. So...created a new VBO buffer ID for vertex, normal and texel data. Buffered the data during the initial glBufferData call. During render I bind each buffer just prior to glVertexAttribPointer but not sure if order here really matter, need to test that. But it works.

    Problem with glBufferSubData ??? Not sure. Was I doing something wrong?

    Anyway, any disadvantage to creating a new VBO buffer ID for each array? For many VBOs to create it would mean many handles. Any concern with overloading GL if too many handles are created?

    Code :
    using System;
     
    using Tao.OpenGl;
     
    using Engine;
    using Engine.DataTypes;
    using Engine.MathLib;
     
    namespace VBOShaders
    {
      class VBO : Singleton<VBO>
      {
        public void BuildVBO(Segment objSegment)
        {
          // Calculate sizes
          int tri_buf_size = objSegment.intTriangleCount * Vector3s.SizeInBytes;  // Size of triangle array in bytes
          int vrt_buf_size = objSegment.intVertexCount   * Vector3f.SizeInBytes;  //         vertex
          int nrm_buf_size = objSegment.intVertexCount   * Vector3f.SizeInBytes;  //         normal
          int txl_buf_size = objSegment.intVertexCount   * Vector2f.SizeInBytes;  //         texel
     
          // Setup geometry array and allocate space
          Gl.glGenBuffers(1, out objSegment.vertexVBOId);
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, objSegment.vertexVBOId);
          Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)vrt_buf_size, objSegment.aryVertexes, Gl.GL_STATIC_DRAW);
     
          Gl.glGenBuffers(1, out objSegment.normalVBOId);
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, objSegment.normalVBOId);
          Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)vrt_buf_size, objSegment.aryVNormals, Gl.GL_STATIC_DRAW);
     
          Gl.glGenBuffers(1, out objSegment.texelVBOId);
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, objSegment.texelVBOId);
          Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)vrt_buf_size, objSegment.aryVTexels, Gl.GL_STATIC_DRAW);
     
          // Setup indices array and allocate space
          Gl.glGenBuffers(1, out objSegment.indicesVBOId);
          Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, objSegment.indicesVBOId);
          Gl.glBufferData(Gl.GL_ELEMENT_ARRAY_BUFFER, (IntPtr)tri_buf_size, objSegment.aryTriangles, Gl.GL_STATIC_DRAW);
     
          // Unbind any buffers so remaining GL stays happy
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);
          Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, 0);
        }
     
        public void RenderVBO(Segment objSegment, int a_vVertex, int a_vNormal, int a_vTexel)
        {
          // Step 1 
          Gl.glEnableVertexAttribArray(a_vVertex);
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, objSegment.vertexVBOId);
          Gl.glVertexAttribPointer(a_vVertex, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, IntPtr.Zero);
     
          Gl.glEnableVertexAttribArray(a_vNormal);
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, objSegment.normalVBOId);
          Gl.glVertexAttribPointer(a_vNormal, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, IntPtr.Zero);
     
          Gl.glEnableVertexAttribArray(a_vTexel);
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, objSegment.texelVBOId);
          Gl.glVertexAttribPointer(a_vTexel,  2, Gl.GL_FLOAT, Gl.GL_FALSE, 0, IntPtr.Zero);
     
          // Step 2 
          int tcount = objSegment.intTriangleCount * 3;
          Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, objSegment.indicesVBOId);
          Gl.glDrawElements(Gl.GL_TRIANGLES, tcount, Gl.GL_UNSIGNED_SHORT, IntPtr.Zero);
     
          // Step 3 
          Gl.glDisableVertexAttribArray(a_vVertex);
          Gl.glDisableVertexAttribArray(a_vNormal);
          Gl.glDisableVertexAttribArray(a_vTexel);
     
          // Step 4 
          Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);
          Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, 0);
        }
     
        public void RenderArrays(Segment objSegment, int a_vVertex, int a_vNormal, int a_vTexel)
        {
          // Step 1 
          Gl.glEnableVertexAttribArray(a_vVertex);
          Gl.glVertexAttribPointer(a_vVertex, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, objSegment.aryVertexes);
     
          Gl.glEnableVertexAttribArray(a_vNormal);
          Gl.glVertexAttribPointer(a_vNormal, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, objSegment.aryVNormals);
     
          Gl.glEnableVertexAttribArray(a_vTexel);
          Gl.glVertexAttribPointer(a_vTexel, 2, Gl.GL_FLOAT, Gl.GL_FALSE, 0, objSegment.aryVTexels);
     
          // Step 2 
          int tcount = objSegment.intTriangleCount * 3;
          Gl.glDrawElements(Gl.GL_TRIANGLES, tcount, Gl.GL_UNSIGNED_SHORT, objSegment.aryTriangles);
     
          // Step 3 
          Gl.glDisableVertexAttribArray(a_vVertex);
          Gl.glDisableVertexAttribArray(a_vNormal);
          Gl.glDisableVertexAttribArray(a_vTexel);
        }
      }
    }

Posting Permissions

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