不能使OpenGL缓冲阵列工作 - glVertex工作

时间:2018-02-16 00:13:58

标签: opengl

我有一个带有顶点(N * 3)和面(N * 3)的Eigen :: MatrixXf作为变量mvTemp2和mF。

如果我定期绘制顶点,它们会根据以下代码给出正确的输出:

 using (ClassContext context = new ClassContext()){
       ((IObjectContextAdapter)context).ObjectContext.Connection.Open();

        //SOMETHING TO DO......

       ((IObjectContextAdapter)context).ObjectContext.Connection.Close(); 
 }

enter image description here

但是,如果我使用顶点缓冲区,我会得到垃圾输出:

while(1){
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glEnable(GL_LIGHTING);
    glShadeModel( GL_SMOOTH );
    glEnable( GL_TEXTURE_2D );

    glViewport( 0, 0, (float)renderWidth/1, (float)renderHeight/1. );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 60, (float)renderWidth/(float)renderHeight, 0.1, 10000. );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
    glPushMatrix();
    glTranslatef(0,-0.5,-0.5);
//        glBindVertexArray(vao);
//        glDrawElements(GL_TRIANGLES, indexdata.size(), GL_UNSIGNED_BYTE,     (void*)0);

    for(int i=0; i<smpl.mF.rows(); i++){
        glBegin(GL_POLYGON);
        for(int j=0; j<smpl.mF.cols(); j++){
            indexdata.push_back(smpl.mF(i,j)+1);

        }
        glVertex3fv((const GLfloat*)&vertexdata[smpl.mF(i,0)].position);
        glVertex3fv((const GLfloat*)&vertexdata[smpl.mF(i,1)].position);
        glVertex3fv((const GLfloat*)&vertexdata[smpl.mF(i,2)].position);
        glEnd();
    }

    glPopMatrix();

    glutSwapBuffers();
    glutPostRedisplay();
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    glutMainLoopEvent();
}

enter image description here

我无法理解我做错了什么。我可以使用常规的旧glVertex正常绘制面部并且它可以工作,但速度太慢。所以我想使用顶点缓冲区,但代码总是提供垃圾输出。为什么会这样? 修改

我已经解决了这个问题,但是我的法线现在已经错了。如果我使用Vertex和Normal调用正常绘制它,它可以工作:

// Iterate v
for(int i=0; i<smpl.mVTemp2.rows(); i++){
    Vertex v;
    for(int j=0; j<smpl.mVTemp2.cols(); j++){
        v.position[j] = smpl.mVTemp2(i,j);
    }
    vertexdata.push_back(v);
}

std::vector<GLubyte> indexdata;

// Iterate f
for(int i=0; i<smpl.mF.rows(); i++){
    for(int j=0; j<smpl.mF.cols(); j++){
        indexdata.push_back(smpl.mF(i,j));
    }
}

// Create and bind a VAO
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

// Create and bind a BO for vertex data
GLuint vbuffer;
glGenBuffers(1, &vbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vbuffer);

// copy data into the buffer object
glBufferData(GL_ARRAY_BUFFER, vertexdata.size() * sizeof(Vertex), &vertexdata[0], GL_STATIC_DRAW);

// set up vertex attributes
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position)); // vertices
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, sizeof(Vertex), (void*)offsetof(Vertex, normal)); // normals
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texcoord)); // normals

// Create and bind a BO for index data
GLuint ibuffer;
glGenBuffers(1, &ibuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuffer);

// copy data into the buffer object
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexdata.size() * sizeof(GLubyte), &indexdata[0], GL_STATIC_DRAW);

glBindVertexArray(0);

while(1){
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glEnable(GL_LIGHTING);
    glShadeModel( GL_SMOOTH );
    glEnable( GL_TEXTURE_2D );

    glViewport( 0, 0, (float)renderWidth/1, (float)renderHeight/1. );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 60, (float)renderWidth/(float)renderHeight, 0.1, 10000. );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
    glPushMatrix();
    glTranslatef(0,-0.5,-0.5);
    glBindVertexArray(vao);
    glDrawElements(GL_TRIANGLES, indexdata.size(), GL_UNSIGNED_BYTE, (void*)0);
    glPopMatrix();

    glutSwapBuffers();
    glutPostRedisplay();
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    glutMainLoopEvent();
}

enter image description here

但是,如果我将它与顶点缓冲区一起使用,则不会:

std::vector<Vertex> vertexdata;
for(int i=0; i<object.vertices.size(); i++){
    Vertex v;
    v.position[0] = object.vertices.at(i).coords[0];
    v.position[1] = object.vertices.at(i).coords[1];
    v.position[2] = object.vertices.at(i).coords[2];
    v.normal[0] = object.computedNormals.at(i).coords[0];
    v.normal[1] = object.computedNormals.at(i).coords[1];
    v.normal[2] = object.computedNormals.at(i).coords[2];
    vertexdata.push_back(v);
}

std::vector<GLushort> indexdata;
for(int i=0; i<object.faces.size(); i++){
    OBJFace& face = object.faces.at(i);
    indexdata.push_back(face.items[0].vertexIndex);
    indexdata.push_back(face.items[1].vertexIndex);
    indexdata.push_back(face.items[2].vertexIndex);

    glBegin(GL_POLYGON);
    glNormal3fv(vertexdata[face.items[0].vertexIndex].normal);
    glVertex3fv(vertexdata[face.items[0].vertexIndex].position);
    glNormal3fv(vertexdata[face.items[1].vertexIndex].normal);
    glVertex3fv(vertexdata[face.items[1].vertexIndex].position);
    glNormal3fv(vertexdata[face.items[2].vertexIndex].normal);
    glVertex3fv(vertexdata[face.items[2].vertexIndex].position);
    glEnd();
}

enter image description here

2 个答案:

答案 0 :(得分:1)

您没有使用着色器进行顶点处理。因此,不能使用通用顶点属性(由VertexAttrib函数提供)。因此,您可以切换到使用着色器,或使用固定功能属性:

// set up vertex attributes
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, position)); // vertices
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, normal)); // normals
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)offsetof(Vertex, texcoord)); // normals

答案 1 :(得分:1)

除了Nicol Bolas的回答

看起来索引的数量太多,无法用字节(GLubyte)对它们进行编码。一个字节可以存储[0,255]范围内的数据,因此一个字节中只能编码256个索引。请改用GLushortGLushort的范围是[0,65535]:

std::vector<GLushort> indexdata;

....

GLuint ibuffer;
glGenBuffers(1, &ibuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuffer);

glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexdata.size()*sizeof(GLushort),
    indexdata.data(), GL_STATIC_DRAW);

....

glDrawElements(GL_TRIANGLES, indexdata.size(), GL_UNSIGNED_SHORT, (void*)0);