The new index data gets corrupted after discarding previous index buffer through the glBufferData(GL_ELEMENT_ARRAY_BUFFER, size_, 0, GL_DYNAMIC_DRAW) call.
Some parts of the scene have missing triangles, other parts are looks like a chaotic triangles soup.
I have tested it on ATi HD3850, Catalyst 9.5, WinXP SP3.
I will test tomorrow on nVidia board, but I think there are should not be any problems.
This is a lock method of my dynamic index buffer class:
CDynamicIndexBuffer::write_lock CDynamicIndexBuffer::lock_for_fill(std::size_t stride,
std::size_t count,
std::size_t &start_offset)
{
const std::size_t lock_size = stride*count;
if (lock_size > size_)
throw std::runtime_error("dynamic index lock size is too large");
if (!size_)
return write_lock();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id_);
CHECK_GL_ERRORS();
const std::size_t offset = (stride - (offset_ % stride)) % stride;
offset_ += offset;
const bool discard = offset_ + lock_size > size_;
void *data = 0;
if (GLEW_ARB_map_buffer_range)
{
GLbitfield access = GL_MAP_WRITE_BIT;
if (discard)
{
offset_ = 0;
access |= GL_MAP_INVALIDATE_BUFFER_BIT;
}
else
access |= GL_MAP_INVALIDATE_RANGE_BIT;
data = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset_, lock_size, access);
CHECK_GL_ERRORS();
}
else
{
if (discard)
{
offset_ = 0;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size_, 0, GL_DYNAMIC_DRAW); // discard old buffer
CHECK_GL_ERRORS();
}
data = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
CHECK_GL_ERRORS();
data = data ? advance_pointer<void>(data, offset_) : data;
}
if (!data)
return write_lock();
start_offset = offset_;
offset_ += lock_size;
return write_lock(*this, unlock_wrapper, data);
}
The GLEW_ARB_map_buffer_range branch is working as it should.
The problem is with else branch. It is not working normally. But it will work without any side effects if I remove glBufferData call.
Is it a driver bug or my incorrect usage of OGL?