Reputation: 3237
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.
Upvotes: 0
Views: 276
Reputation: 162164
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;
}
}
Upvotes: 2
Reputation: 43319
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.
Upvotes: 3