Results 1 to 2 of 2

Thread: How to use QGLBuffer and vertex/index buffer correctly

  1. #1
    Join Date
    Dec 2010
    Posts
    76
    Thanks
    13
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default How to use QGLBuffer and vertex/index buffer correctly

    I am trying to use VBO correctly with Qt's OpenGl and I am currently using Qt 4.8. I do not have the capability at this time to go to the latest Qt version. However I would like to take advantage of Qt's implementation of Vertex/Index Buffers. I currently set up my VBOs in the following way:

    Qt Code:
    1. #include "VBOMesh.h"
    2.  
    3. #include <QtOpenGL>
    4.  
    5. ///////////////////////////////////////////////////////////
    6. // Constructor, does what constructors do... set everything to zero or NULL
    7. CVBOMesh::CVBOMesh(void)
    8. : vertexDataVBO(QGLBuffer::VertexBuffer)
    9. , normalDataVBO(QGLBuffer::VertexBuffer)
    10. , textureDataVBO(QGLBuffer::VertexBuffer)
    11. , indexDataVBO(QGLBuffer::IndexBuffer)
    12.  
    13. {
    14. pIndexes = NULL;
    15. pVerts = NULL;
    16. pNorms = NULL;
    17. pTexCoords = NULL;
    18.  
    19. nMaxIndexes = 0;
    20. nNumIndexes = 0;
    21. nNumVerts = 0;
    22. }
    23.  
    24. ////////////////////////////////////////////////////////////
    25. // Free any dynamically allocated memory. For those C programmers
    26. // coming to C++, it is perfectly valid to delete a NULL pointer.
    27. CVBOMesh::~CVBOMesh(void)
    28. {
    29. // Just in case these still are allocated when the object is destroyed
    30. delete [] pIndexes;
    31. delete [] pVerts;
    32. delete [] pNorms;
    33. delete [] pTexCoords;
    34.  
    35. // Delete buffer objects
    36. vertexDataVBO.destroy();
    37. normalDataVBO.destroy();
    38. textureDataVBO.destroy();
    39. indexDataVBO.destroy();
    40. }
    41.  
    42. ////////////////////////////////////////////////////////////
    43. // Start assembling a mesh. You need to specify a maximum amount
    44. // of indexes that you expect. The EndMesh will clean up any uneeded
    45. // memory. This is far better than shreading your heap with STL containers...
    46. // At least that's my humble opinion.
    47. void CVBOMesh::BeginMesh(GLuint nMaxVerts)
    48. {
    49. // Just in case this gets called more than once...
    50. delete [] pIndexes;
    51. delete [] pVerts;
    52. delete [] pNorms;
    53. delete [] pTexCoords;
    54.  
    55. nMaxIndexes = nMaxVerts;
    56. nNumIndexes = 0;
    57. nNumVerts = 0;
    58.  
    59. // Allocate new blocks
    60. pIndexes = new GLushort[nMaxIndexes];
    61. pVerts = new M3DVector3f[nMaxIndexes];
    62. pNorms = new M3DVector3f[nMaxIndexes];
    63. pTexCoords = new M3DVector2f[nMaxIndexes];
    64. }
    65.  
    66. /////////////////////////////////////////////////////////////////
    67. // Add a triangle to the mesh. This searches the current list for identical
    68. // (well, almost identical - these are floats you know...) verts. If one is found, it
    69. // is added to the index array. If not, it is added to both the index array and the vertex
    70. // array grows by one as well.
    71. void CVBOMesh::AddTriangle(M3DVector3f verts[3], M3DVector3f vNorms[3], M3DVector2f vTexCoords[3])
    72. {
    73. const float e = 0.000001; // How small a difference to equate
    74.  
    75. // First thing we do is make sure the normals are unit length!
    76. // It's almost always a good idea to work with pre-normalized normals
    77. m3dNormalizeVector(vNorms[0]);
    78. m3dNormalizeVector(vNorms[1]);
    79. m3dNormalizeVector(vNorms[2]);
    80.  
    81.  
    82. // Search for match - triangle consists of three verts
    83. for(GLuint iVertex = 0; iVertex < 3; iVertex++)
    84. {
    85. GLuint iMatch = 0;
    86. for(iMatch = 0; iMatch < nNumVerts; iMatch++)
    87. {
    88. // If the vertex positions are the same
    89. if(m3dCloseEnough(pVerts[iMatch][0], verts[iVertex][0], e) &&
    90. m3dCloseEnough(pVerts[iMatch][1], verts[iVertex][1], e) &&
    91. m3dCloseEnough(pVerts[iMatch][2], verts[iVertex][2], e) &&
    92.  
    93. // AND the Normal is the same...
    94. m3dCloseEnough(pNorms[iMatch][0], vNorms[iVertex][0], e) &&
    95. m3dCloseEnough(pNorms[iMatch][1], vNorms[iVertex][1], e) &&
    96. m3dCloseEnough(pNorms[iMatch][2], vNorms[iVertex][2], e) &&
    97.  
    98. // And Texture is the same...
    99. m3dCloseEnough(pTexCoords[iMatch][0], vTexCoords[iVertex][0], e) &&
    100. m3dCloseEnough(pTexCoords[iMatch][1], vTexCoords[iVertex][1], e))
    101. {
    102. // Then add the index only
    103. pIndexes[nNumIndexes] = iMatch;
    104. nNumIndexes++;
    105. break;
    106. }
    107. }
    108.  
    109. // No match for this vertex, add to end of list
    110. if(iMatch == nNumVerts)
    111. {
    112. memcpy(pVerts[nNumVerts], verts[iVertex], sizeof(M3DVector3f));
    113. memcpy(pNorms[nNumVerts], vNorms[iVertex], sizeof(M3DVector3f));
    114. memcpy(pTexCoords[nNumVerts], &vTexCoords[iVertex], sizeof(M3DVector2f));
    115. pIndexes[nNumIndexes] = nNumVerts;
    116. nNumIndexes++;
    117. nNumVerts++;
    118. }
    119. }
    120. }
    121.  
    122.  
    123.  
    124. //////////////////////////////////////////////////////////////////
    125. // Compact the data. This is a nice utility, but you should really
    126. // save the results of the indexing for future use if the model data
    127. // is static (doesn't change).
    128. void CVBOMesh::EndMesh(void)
    129. {
    130. // Create the buffer objects
    131. vertexDataVBO.create();
    132. normalDataVBO.create();
    133. textureDataVBO.create();
    134. indexDataVBO.create();
    135.  
    136. // Copy data to video memory
    137. // Vertex data
    138. vertexDataVBO.bind();
    139. vertexDataVBO.allocate(pVerts, sizeof(GLfloat)*nNumVerts*3);
    140. vertexDataVBO.setUsagePattern(QGLBuffer::StaticDraw);
    141.  
    142. // Normal data
    143. normalDataVBO.bind();
    144. normalDataVBO.allocate(pNorms, sizeof(GLfloat)*nNumVerts*3);
    145. normalDataVBO.setUsagePattern(QGLBuffer::StaticDraw);
    146.  
    147. // Texture coordinates
    148. textureDataVBO.bind();
    149. textureDataVBO.allocate(pTexCoords, sizeof(GLfloat)*nNumVerts*2);
    150. textureDataVBO.setUsagePattern(QGLBuffer::StaticDraw);
    151.  
    152. // Indexes
    153. indexDataVBO.bind();
    154. textureDataVBO.allocate(pIndexes, sizeof(GLushort)*nNumIndexes);
    155. textureDataVBO.setUsagePattern(QGLBuffer::StaticDraw);
    156.  
    157. // Free older, larger arrays
    158. delete [] pIndexes;
    159. delete [] pVerts;
    160. delete [] pNorms;
    161. delete [] pTexCoords;
    162.  
    163. // Reasign pointers so they are marked as unused
    164. pIndexes = NULL;
    165. pVerts = NULL;
    166. pNorms = NULL;
    167. pTexCoords = NULL;
    168. }
    169.  
    170. //////////////////////////////////////////////////////////////////////////
    171. // Draw - make sure you call glEnableClientState for these arrays
    172. void CVBOMesh::Draw(void)
    173. {
    174. // Here's where the data is now
    175. vertexDataVBO.bind();
    176. glVertexPointer(3, GL_FLOAT,0,0);
    177.  
    178. // Normal data
    179. normalDataVBO.bind();
    180. glNormalPointer(GL_FLOAT, 0, 0);
    181.  
    182. // Texture coordinates
    183. textureDataVBO.bind();
    184. glTexCoordPointer(2, GL_FLOAT, 0, 0);
    185.  
    186. // Indexes
    187. indexDataVBO.bind();
    188. glDrawElements(GL_TRIANGLES, nNumIndexes, GL_UNSIGNED_SHORT, 0);
    189. }
    190.  
    191. ///////////////////////////////////////////////////////////////////////////
    192. // Scale of the vertices. The only way to do this is to map the VBO back
    193. // into client memory, then back again
    194. void CVBOMesh::Scale(GLfloat fScaleValue)
    195. {
    196. vertexDataVBO.bind();
    197. M3DVector3f *pVertexData = (M3DVector3f *)vertexDataVBO.map(QGLBuffer::ReadWrite);
    198.  
    199. if(pVertexData != NULL)
    200. {
    201. for(unsigned int i = 0; i < nNumVerts; i++)
    202. m3dScaleVector3(pVertexData[i], fScaleValue);
    203.  
    204. vertexDataVBO.unmap();
    205. }
    206. }
    207.  
    208. ///////////////////////// GLWidget class, both ThunderbirdBody and ThunderbirdGlass are CVBOMesh classes
    209. void GLWidget::DrawThunderBird()
    210. {
    211. glEnableClientState(GL_VERTEX_ARRAY);
    212. glEnableClientState(GL_NORMAL_ARRAY);
    213. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    214.  
    215. glActiveTexture(GL_TEXTURE1);
    216. glDisable(GL_TEXTURE_CUBE_MAP);
    217. glActiveTexture(GL_TEXTURE0);
    218.  
    219. glPushMatrix();
    220. glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
    221. glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    222. glBindTexture(GL_TEXTURE_2D, textureObjects[BODY_TEXTURE]);
    223. thunderBirdBody.Draw();
    224. glPopMatrix();
    225.  
    226. glActiveTexture(GL_TEXTURE1);
    227. glEnable(GL_TEXTURE_CUBE_MAP);
    228. glActiveTexture(GL_TEXTURE0);
    229.  
    230. glEnable(GL_BLEND);
    231. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    232. glColor4f(1.0f, 1.0f, 1.0f, 0.25f);
    233. glBindTexture(GL_TEXTURE_2D, textureObjects[GLASS_TEXTURE]);
    234.  
    235. glTranslatef(0.0f, 0.132f, 0.555f);
    236.  
    237. glFrontFace(GL_CW);
    238. thunderBirdGlass.Draw();
    239. glFrontFace(GL_CCW);
    240. thunderBirdGlass.Draw();
    241. glDisable(GL_BLEND);
    242.  
    243. glDisableClientState(GL_VERTEX_ARRAY);
    244. glDisableClientState(GL_NORMAL_ARRAY);
    245. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    246. }
    To copy to clipboard, switch view to plain text mode 

    I believe the problem is in the Draw function because I can compile green however when I run the program everything renders except the commands related to the Draw function in this class. This is taken straight out of the OpenGl SuperBible 4th edition and I changed it to match Qt's VBO implementation. If there is something I am missing please let me know because as of right now I am stumped.

    Thanks for any help!
    Last edited by jshafferman; 25th June 2014 at 16:07.

  2. #2
    Join Date
    Dec 2010
    Posts
    76
    Thanks
    13
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: How to use QGLBuffer and vertex/index buffer correctly

    Oh my.... I found the error I made, you have to set usage pattern before allocating memory size. It says so in the Qt documentation, I just didn't realize that was what was wrong. Everything rendering great now!

Similar Threads

  1. Vertex Buffer Object -> Segmentation Fault
    By BlastDV in forum Qt Programming
    Replies: 1
    Last Post: 4th March 2014, 15:15
  2. Replies: 2
    Last Post: 30th December 2010, 17:03
  3. QGLBuffer instead of Vertex Buffer Object -> How To?
    By FlashMuller in forum Qt Programming
    Replies: 0
    Last Post: 18th November 2010, 11:41
  4. OpenGL Vertex Buffer Array/Object
    By Denarius in forum Qt Programming
    Replies: 1
    Last Post: 8th April 2010, 08:59
  5. Replies: 1
    Last Post: 9th November 2009, 14:16

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.