1

I am trying to approximate a curved surface using quadrilateral patches. I did it using straight forward rendering using GL_QUADS and specifying the four vertices of the quad patch.

Now I am trying to get some performance using vertex buffers and overlayed array (verNor) of vertices and normals. The problem is that I get some random shapes but not the correct shape I got previously.

Here I am putting my code:

      GLenum err = glewInit();
      if (GLEW_OK != err){
            std::cout<<"Filed to Initialize GLEW :: "<<glewGetErrorString(err)<<std::endl;
      }

      verNor = new GLfloat [NA*NP*6];   // NA and NP are number of points in lets say x and y axis
      indices = new GLuint [(NA)*(NP)*4];   // When the tube is cut an spread out.


      // VBOs
      glGenBuffers(1, &vbo_tube); // Ask the GPU driver for a buffer array. "vbo" now has the ID
      glGenBuffers(1, &ibo_indices);

         // For Vertices and Normals which are interleved
         glBindBuffer(GL_ARRAY_BUFFER, vbo_tube);
         glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6*NA*NP, NULL, GL_STATIC_DRAW);
         // Obtaining the pointer to the memory in graphics buffer
         buffer_verNor = glMapBuffer(GL_ARRAY_BUFFER,GL_WRITE_ONLY);

         // For Indices
         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_indices);
         glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * 4*(NA-1)*(NP-1), NULL, GL_STATIC_DRAW);
         buffer_indices = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER,GL_WRITE_ONLY);

    // Calculate the vertices of the points around the tube. Correctness guarenteed because I can draw exactly what I wanted 
    // using normal stright forward GL_QUADS that is drawing quad by quad and with out any VBOs
    // Calculated vertices are stored in vPoints.


    for (int i=0; i<NP; i++) {
        for (int j=0; j<NA; j++) {


            // Calculate the normals of each and every point above and store them in v3

            // Storing the vertices         
            verNor[6*( (i)*NA+(j) )+0] = (GLfloat)vPoints[i*NA+j].GetX();
            verNor[6*( (i)*NA+(j) )+1] = (GLfloat)vPoints[i*NA+j].GetY();
            verNor[6*( (i)*NA+(j) )+2] = (GLfloat)vPoints[i*NA+j].GetZ();
            // Storing the Normals
            verNor[6*((i-1)*NA+(j-1))+3] = (GLfloat)v3.GetX();
            verNor[6*((i-1)*NA+(j-1))+4] = (GLfloat)v3.GetY();
            verNor[6*((i-1)*NA+(j-1))+5] = (GLfloat)v3.GetZ();

            // Calculating the indices which form the quad
            indices[4*((i)*NA+(j))+0]   =   (GLuint) (i)*NA+j     ;
            indices[4*((i)*NA+(j))+1]   =   (GLuint) (i+1)*NA+j   ;
            indices[4*((i)*NA+(j))+2]   =   (GLuint) (i+1)*NA+j+1 ;
            indices[4*((i)*NA+(j))+3]   =   (GLuint) (i)*NA+j+1   ;
        }
    }


    memcpy(buffer_verNor, verNor, 6*(NA)*(NP));
    glUnmapBuffer(GL_ARRAY_BUFFER);     // Unmapping the buffer

    memcpy(buffer_indices, indices, 4*(NA-1)*(NP-1));
    glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);


    glEnable(GL_LIGHTING);
    // Performing the Vertex Buffer Stuff
    // For Vertices and Normals
    glBindBuffer(GL_ARRAY_BUFFER, vbo_tube);
    glVertexPointer( 3, GL_FLOAT, 6*sizeof(GLfloat), (GLvoid*)((char*)NULL + 0*sizeof(GLfloat)) );
    glNormalPointer( GL_FLOAT, 6*sizeof(GLfloat), (GLvoid*)(((char*)NULL)+3*sizeof(GLfloat)) );

    // For Indices
    // Mapping the indices_vbo memory here
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_indices);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*4*(NA-1)*(NP-1), indices, GL_STATIC_DRAW);

    // Enabling all the buffers and drawing the quad patches
    glBindBuffer(GL_ARRAY_BUFFER, vbo_tube);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_indices);

    // Enabling normals and vertices to draw
    glEnableClientState (GL_NORMAL_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);

    // Drawing the patches
     glDrawElements(GL_QUADS, (NA-1)*(NP-1), GL_UNSIGNED_INT,(GLvoid*)((char*)NULL));
        // Disabling the buffer objects for safety
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);


        glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);

    glDeleteBuffers(1, &vbo_tube);
    glDeleteBuffers(1, &ibo_indices);

The gird has NA by NP points so I have to draw (NP-1)*(NA-1) quads. Also I can only get some thing(but not correct) drawn only when I give wrong offsets and stride in glVertexPointer() and glNormalPointer() function. Correct ones i think are vertexPointer :: Stride - 6*sizeof(GLfloat) , offset - 0(last argument) normalPointer :: Stride - 6*sizeof(GLfloat) , offset - 3*sizeof(GLfloat)

genpfault
  • 51,148
  • 11
  • 85
  • 139
AdityaG
  • 428
  • 1
  • 3
  • 17
  • 2
    Can you post a picture of what is drawn? – Xymostech Mar 21 '13 at 16:11
  • Sidenote: In your case, their is no reason to perform buffer mapping. Calling `glBufferData`, mapping that buffer, filling it with data, and unmapping it requires far more communication with the GPU than is necessary. While the communication latency might be negligible in this case, it is never a good practice in OpenGL to communicate across the bus when not necessary. It would be far better to just fill a local array (or vector) of the same size as your buffer, and the root pointer of this array this as the data argument of `glBufferData`. – Sir Digby Chicken Caesar Mar 21 '13 at 19:00

0 Answers0