1
\$\begingroup\$

I have currently in my application 2 VBO one which is a streamed buffer and for the moment the other is a static buffer.

However even when the steam buffer is not bound and the static buffer is bound calling drawarray will use the data from the streamed buffer rather than the static one.

The streamed buffer is used for sprite batching and is created as followed

VBO = new VertexBuffer();
VBO->createBuffer(GL_ARRAY_BUFFER, m_BufferSize, GL_STREAM_DRAW);
//void VertexBuffer::createBuffer(GLenum Type, GLsizei size, GLenum usage)
// {
//  glGenBuffers(1, &m_BufferID);
//  m_size = size;
//  m_Type = Type;
//  bind();
//  glBufferData(m_Type, m_size, NULL,  usage);
//  unbind();
// }

VBO->bind();
//void bind()       {glBindBuffer(m_Type, m_BufferID);}

VBO->setBufferData(NULL, GL_STREAM_DRAW);
//void VertexBuffer::setBufferData(GLvoid* Data, GLenum usage)
// {
//  glBufferData(m_Type, m_size, Data, usage);
// }

//enable the vertex attributes for the VAO in this case vertex pos and texture are needed
glEnableVertexAttribArray((GLuint)MLRenderer::ML_ATT_VERTEXPOS);  // Vertex position
glEnableVertexAttribArray((GLuint)MLRenderer::ML_ATT_TEXTURE0); //vertex texture coord
glEnableVertexAttribArray((GLuint)MLRenderer::ML_ATT_VERTEXCOL);

glVertexAttribPointer(MLRenderer::ML_ATT_VERTEXPOS, 3, GL_FLOAT, GL_FALSE, sizeof(MLFormats::VertexPosTexCol), (GLubyte *)NULL );
glVertexAttribPointer(MLRenderer::ML_ATT_TEXTURE0, 2, GL_FLOAT, GL_FALSE, sizeof(MLFormats::VertexPosTexCol), (GLubyte*)sizeof(Vector3f));
glVertexAttribPointer(MLRenderer::ML_ATT_VERTEXCOL, 4, GL_FLOAT, GL_FALSE, sizeof(MLFormats::VertexPosTexCol), (GLubyte*)(sizeof(Vector2f) + sizeof(Vector3f)));

VBO->unbind();
//void unbind() {glBindBuffer(m_Type, 0);}

Rendering using that buffer is as followed

VBO->bind();
//lock the shader
m_shader->lock();
//apply the uniforms

m_shader->addUniform("inMVP", (MLRenderer::MLCoreGL::getOrtho()));
m_shader->addUniform("Tex1", 0);

//*INFO*
//In order for the mapping to work correctly a max limit needs to be made for the vbo
//this will then be filled with data up to a point. once the data is filled then a new
//mapped range is needed and the draw call can be made. this means only a max amount of sprites
//can be batch drawn but it meas a fixed size index buffer is possible
if (m_BufferOffset +  (count * m_spriteSize) >= m_BufferSize)
{
    //glBufferData(GL_ARRAY_BUFFER, m_BufferSize, NULL, GL_STREAM_DRAW);
    VBO->setBufferData(m_BufferSize, NULL, GL_STREAM_DRAW);
    m_BufferOffset = 0;
}

MLFormats::VertexPosTexCol* mappedData = (MLFormats::VertexPosTexCol*)VBO->mapRange(m_BufferOffset, m_BufferOffset +  (count  * m_spriteSize));

//!!!---set vertex Data----!!!

glBindTexture(GL_TEXTURE_2D, texture);
VBO->unmap();


glDrawArrays(GL_TRIANGLES, (m_BufferOffset/sizeof(MLFormats::VertexPosTexCol)), count * 6);
m_BufferOffset += (count * m_spriteSize);


VBO->unbind();
//unbind the texture
glBindTexture(GL_TEXTURE_2D, 0);

//unlock the shader 
m_shader->unlock();

That all works no problem but its when it comes to my point sprite rendering that I get a problem.

The static buffer is created like so

//create a new buffer with the right size;
m_PointBuffer = new VertexBuffer();
m_PointBuffer->createBuffer(GL_ARRAY_BUFFER, sizeof(Vector3f) * 2, GL_STATIC_DRAW);
m_PointBuffer->bind();

//set the vertex attributes
glEnableVertexAttribArray((GLuint)MLRenderer::ML_ATT_VERTEXPOS);
glVertexAttribPointer(MLRenderer::ML_ATT_VERTEXPOS, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3f), (GLubyte*)NULL);


//DEMO ADD A TEMP POINT
Vector3f v3[2];
v3[0] = Vector3f(400,400, 0);
v3[1] = Vector3f(300,660, 0);
m_PointBuffer->setBufferData(sizeof(Vector3f) * 2, (GLvoid*)v3, GL_STATIC_DRAW);
//void VertexBuffer::setBufferData(GLsizei size, GLvoid* Data, GLenum usage)
// {
//  glBufferData(m_Type, size, Data, usage);
// }
m_PointBuffer->unbind();

Then when I come to draw the point sprites

m_PointBuffer->bind();
m_pointSpriteShader->lock();

m_pointSpriteShader->addUniform("inMV", m_modelView);
m_pointSpriteShader->addUniform("Tex1", 0);
m_pointSpriteShader->addUniform("Size2", m_halfSize);
m_pointSpriteShader->addUniform("ProjectionMat", MLRenderer::MLCoreGL::getOrtho());

glBindTexture(GL_TEXTURE_2D, m_textureID);
glDrawArrays(GL_POINTS, 0, 2);

m_PointBuffer->unbind();

glBindTexture(GL_TEXTURE_2D, 0);

m_pointSpriteShader->unlock();

Im sure there is something im missing completely but at the moment I cant see what the issue is.

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

Dekowta

In your case I would rewrite the draw code next way:

  1. Apply shader
  2. Setup uniforms
  3. Bind needed buffer (glBindBuffer)
  4. Setup attrib pointers (glVertexAttribPointer)
  5. Do not forget to enable them (glEnableVertexAttribArray)
  6. call glDrawArrays
  7. disable attribs (glDisableVertexAttribArray)

OpenGL is a state machine and the fact that you setup vertex attribs between bind/unbind of VBO does not really mean that when you bind your VBO next time all vertex attribs will be enabled again.

Nice documentation about using Vertex Buffer Objects can be found here

\$\endgroup\$
4
\$\begingroup\$

As has been stated many, many times before, glVertexAttribPointer takes the buffer object that was bound to GL_ARRAY_BUFFER at the time the function is called. Changing the GL_ARRAY_BUFFER binding will have no effect on rendering unless you make the glVertexAttribPointer calls again.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged .