\n\n
Wich shows the square slowly being linearly translated towards the upper right corner of the screen by modifying the contents of the VBO.
\n\nbool modify_vertex_data(\n std::vector<vertex_2d_renderer_type<vertex_type> > &data,\n GLsizeiptr start_index) {\n\n if (!vertex_vbo_pointer_ || (start_index + data.size()) >\n static_cast<uint32_t>(vertex_count_)) {\n\n return false;\n }\n glBindBuffer(render_target, vertex_vbo_pointer_);\n vertex_2d_renderer_type<vertex_type> *vbo_data;\n vbo_data = reinterpret_cast<vertex_2d_renderer_type<vertex_type> *>(\n glMapBuffer(render_target, modify_access));\n\n memcpy(vbo_data, data.data(),\n data.size() * sizeof(vertex_2d_renderer_type<vertex_type>));\n\n return (glGetError() == GL_NO_ERROR) && glUnmapBuffer(render_target);\n}\n
\n\nThe code that calls into this is:
\n\nvoid QtRenderer::paintGL() {\n //makeCurrent();\n count_++;\n\n glMatrixMode(GL_PROJECTION);\n glEnable(GL_SCISSOR_TEST);\n glDisable(GL_DEPTH_TEST);\n glLoadIdentity();\n glViewport(0, 0, width(), height());\n glOrtho(0, width(), 0, height(), -1, 1);\n\n glMatrixMode(GL_MODELVIEW);\n glScissor(0, 0, width(), height());\n glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);\n glClearColor(0.0, 0.0, 0.0, 1.0);\n glLoadIdentity();\n\n glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);\n for (uint32_t i = 0; i < 6; ++i) {\n data_[i].vertex_.x_ += 0.1;\n data_[i].vertex_.y_ += 0.1;\n }\n\n if (!renderer_2d_.modify_vertex_data(data_, 0)) {\n throw std::runtime_error(\"ERROR: Data Modification Error\");\n }\n\n renderer_2d_.draw_vertex_data();\n glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);\n swapBuffers();\n}\n
\n","author":{"@type":"Person","name":"Matthew Hoggan"},"upvoteCount":0,"answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"After spending some time in chat with OP, looking at the code, I found the issue to be a redundant call to his OpenGL data initialization code. OP uses Qt's QGLWidget that provides a virtual method QGLWidget::initializeGL
which is implicitly called by Qt as soon as the OpenGL context is ready to use. By overriding that method one can initialize persistent OpenGL objects like VBOs and such in a reliable way.
However in OP's code this method was also called explicitly, so the client side std::vector buffers for the vertex data got pushed another full copy of the vertex data, which then later got not modified, resulting in that apparent "residual" data.
\nBringing the code back into proper QGLWidget semantics shape solved the issue.
\nYou're not clearing the framebuffer before drawing, so whatever was drawn before becomes the "background" on which you overdraw. OpenGL is not a scenegraph it's a drawing API. If you change data in a VBO it will not "magically" update the screen contents.
Reputation: 7604
The code I would have to paste is too much. I have followed tutorials, however, when trying to implement them by myself nothing seems to work. I will paste the glMapBuffer
routine below. Note that vertex_type
and render_target
are templeted parameters that allow users to set those enumerated values themselves.
An image of what is happening is.
Wich shows the square slowly being linearly translated towards the upper right corner of the screen by modifying the contents of the VBO.
bool modify_vertex_data(
std::vector<vertex_2d_renderer_type<vertex_type> > &data,
GLsizeiptr start_index) {
if (!vertex_vbo_pointer_ || (start_index + data.size()) >
static_cast<uint32_t>(vertex_count_)) {
return false;
}
glBindBuffer(render_target, vertex_vbo_pointer_);
vertex_2d_renderer_type<vertex_type> *vbo_data;
vbo_data = reinterpret_cast<vertex_2d_renderer_type<vertex_type> *>(
glMapBuffer(render_target, modify_access));
memcpy(vbo_data, data.data(),
data.size() * sizeof(vertex_2d_renderer_type<vertex_type>));
return (glGetError() == GL_NO_ERROR) && glUnmapBuffer(render_target);
}
The code that calls into this is:
void QtRenderer::paintGL() {
//makeCurrent();
count_++;
glMatrixMode(GL_PROJECTION);
glEnable(GL_SCISSOR_TEST);
glDisable(GL_DEPTH_TEST);
glLoadIdentity();
glViewport(0, 0, width(), height());
glOrtho(0, width(), 0, height(), -1, 1);
glMatrixMode(GL_MODELVIEW);
glScissor(0, 0, width(), height());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0, 0.0, 0.0, 1.0);
glLoadIdentity();
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
for (uint32_t i = 0; i < 6; ++i) {
data_[i].vertex_.x_ += 0.1;
data_[i].vertex_.y_ += 0.1;
}
if (!renderer_2d_.modify_vertex_data(data_, 0)) {
throw std::runtime_error("ERROR: Data Modification Error");
}
renderer_2d_.draw_vertex_data();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
swapBuffers();
}
Upvotes: 0
Views: 395
Reputation: 162317
After spending some time in chat with OP, looking at the code, I found the issue to be a redundant call to his OpenGL data initialization code. OP uses Qt's QGLWidget that provides a virtual method QGLWidget::initializeGL
which is implicitly called by Qt as soon as the OpenGL context is ready to use. By overriding that method one can initialize persistent OpenGL objects like VBOs and such in a reliable way.
However in OP's code this method was also called explicitly, so the client side std::vector buffers for the vertex data got pushed another full copy of the vertex data, which then later got not modified, resulting in that apparent "residual" data.
Bringing the code back into proper QGLWidget semantics shape solved the issue.
You're not clearing the framebuffer before drawing, so whatever was drawn before becomes the "background" on which you overdraw. OpenGL is not a scenegraph it's a drawing API. If you change data in a VBO it will not "magically" update the screen contents.
Upvotes: 2