顶点缓冲和渲染问题

时间:2013-03-21 16:05:48

标签: c++ opengl vertex-buffer stride

我试图使用四边形贴片来近似曲面。我使用GL_QUADS直接渲染并指定四元组补丁的四个顶点。

现在我试图使用顶点缓冲区和顶点和法线的重叠数组(verNor)来获得一些性能。问题是我得到了一些随机的形状,但不是我之前得到的正确形状。

我在这里输入我的代码:

      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);

网格的NP点数为NA,所以我必须绘制(NP-1)*(NA-1)四边形。 另外,只有当我在glVertexPointer()和glNormalPointer()函数中给出错误的偏移和步幅时,才能得到一些东西(但不正确)。我认为是正确的 vertexPointer :: Stride - 6 * sizeof(GLfloat),offset - 0(last argument) normalPointer :: Stride - 6 * sizeof(GLfloat),offset - 3 * sizeof(GLfloat)

0 个答案:

没有答案