Question

I'm trying to render my stored data using VBOs. However, nothing is actually rendered, although no error is thrown by glGetError();

void Model::initDrawing()
{
    glewInit(); 

    glGenBuffers(1, &_bufferID);
    glBindBuffer(GL_ARRAY_BUFFER, _bufferID);

    const GLsizeiptr vertex_size = sizeof(_modelMesh->vertices);
    const GLsizeiptr normal_size = sizeof(_modelMesh->vertices);
    glBufferData(GL_ARRAY_BUFFER, vertex_size+normal_size, 0, GL_STATIC_DRAW);


    GLvoid * vbo_buffer = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
        memcpy(vbo_buffer, &_modelMesh->vertices[0], vertex_size);
        vbo_buffer += vertex_size;      
        memcpy(vbo_buffer, &_modelMesh->normals[0], normal_size);       
    glUnmapBuffer(GL_ARRAY_BUFFER);

    glVertexPointer(4, GL_FLOAT, 0, (GLvoid*)((char*)NULL));
    glNormalPointer(GL_FLOAT, 0, (GLvoid*)((char*)NULL+vertex_size));       
}

void Model::draw()
{
    glBindBuffer(GL_ARRAY_BUFFER, _bufferID);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glDrawElements(GL_TRIANGLE_STRIP, _modelMesh->vertices.size(), GL_UNSIGNED_INT, (GLvoid*)((char*)NULL));

    GLenum err;
    while ((err = glGetError()) != GL_NO_ERROR)
    {
        cerr << "OpenGL error: " << err << endl;
    }
}

where Mesh *_modelMesh consists of (among the others):

std::vector<Vertex4f> vertices;
std::vector<Normal3f> normals;

which are simply just vectors of numbers of GLfloat type:

typedef struct _vertex4f {
    Vertex3f vertex;
    GLfloat weight;
} Vertex4f;
typedef struct _vertex3f {
    GLfloat x, y, z;
} Vertex3f;

Is defining vectors and normals enough for drawing?

I'm also using light when rendering.

Était-ce utile?

La solution

For one thing, your positions and normals are not sized correctly.

Their sizes should be something like _modelMesh->vertices.size () * sizeof (GLfloat) * 4 and _modelMesh->normals.size () * sizeof (GLfloat) * 3 respectively. They are not the same size.

You also do not want to use sizeof (_modelMesh->vertices), because vertices is a templated container. That will not give you the size of its contained elements, just the size of the instantiated std::vector <Vertex4f> object (which is probably a couple of pointers).

Finally, I do not see anywhere in this code where you bind anything to GL_ELEMENT_ARRAY_BUFFER.

Likewise, glBindBuffer(GL_ARRAY_BUFFER, _bufferID); is not necessary in Model::draw (...), because the only time the thing bound to GL_ARRAY_BUFFER matters is when you call gl...Pointer (...). From that point on, it does not matter what, if anything is bound to GL_ARRAY_BUFFER; its only purpose is to tell the Pointer command which buffer's memory the pointer is relative to.

Autres conseils

Settings made by calls to gl…Pointer are not persistent within the buffer. Either you contain them within a Vertex Array Object, or you set them right before the gl…Draw calls. Furthermore, yor call to glDrawElements looks like you're intending to fetch indices from a Vertex Element Array buffer. I don't see you generating one.

These changes are required:

void Model::initDrawing()
{
    glewInit(); 

    glGenBuffers(1, &_bufferID);
    glBindBuffer(GL_ARRAY_BUFFER, _bufferID);

    const GLsizeiptr vertex_size = sizeof(_modelMesh->vertices);
    const GLsizeiptr normal_size = sizeof(_modelMesh->vertices);
    glBufferData(GL_ARRAY_BUFFER, vertex_size+normal_size, 0, GL_STATIC_DRAW);


    GLvoid * vbo_buffer = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
        memcpy(vbo_buffer, &_modelMesh->vertices[0], vertex_size);
        vbo_buffer += vertex_size;      
        memcpy(vbo_buffer, &_modelMesh->normals[0], normal_size);       
    glUnmapBuffer(GL_ARRAY_BUFFER);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glGenBuffers(1, &element_bufferID);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_bufferID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertex_size+normal_size, 0, GL_STATIC_DRAW);
    GLvoid * element_buffer = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
       /* fill element buffer */
    glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

}

void Model::draw()
{
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, _bufferID);
    glVertexPointer(4, GL_FLOAT, 0, (GLvoid*)((char*)NULL));
    glNormalPointer(GL_FLOAT, 0, (GLvoid*)((char*)NULL+vertex_size));       

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_bufferID);
    glDrawElements(GL_TRIANGLE_STRIP, _modelMesh->vertices.size(), GL_UNSIGNED_INT, (GLvoid*)((char*)NULL));

    GLenum err;
    while ((err = glGetError()) != GL_NO_ERROR)
    {
        cerr << "OpenGL error: " << err << endl;
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top