Use Vertex Buffer Objects for rendering of 3D volumes if possible.

This commit is contained in:
bubnikv 2017-03-16 14:02:28 +01:00
parent c32c7fa1dc
commit 7f7d2da5fe
8 changed files with 257 additions and 103 deletions

View file

@ -540,6 +540,10 @@ sub mouse_wheel_event {
# Reset selection.
sub reset_objects {
my ($self) = @_;
if ($self->{use_VBOs}) {
$self->GetContext;
$self->volumes->release_geometry;
}
$self->volumes->erase;
$self->_dirty(1);
}
@ -944,6 +948,10 @@ sub InitGL {
return unless $self->GetContext;
$self->init(1);
my @gl_version = split(/\./, glGetString(GL_VERSION));
$self->{use_VBOs} = int($gl_version[0]) >= 2;
# print "OpenGL major: $gl_version[0], minor: $gl_version[1]. Use VBOs: ", $self->{use_VBOs}, "\n";
glClearColor(0, 0, 0, 1);
glColor3f(1, 0, 0);
glEnable(GL_DEPTH_TEST);
@ -983,12 +991,15 @@ sub InitGL {
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_MULTISAMPLE);
Slic3r::GUI::_3DScene::_glew_init;
}
sub DestroyGL {
my $self = shift;
if ($self->init && $self->GetContext) {
delete $self->{shader};
$self->volumes->release_geometry;
}
}
@ -1251,58 +1262,7 @@ sub draw_volumes {
glColor4f(@{ $volume->color });
}
glPushMatrix();
glTranslatef(@{$volume->origin});
glCullFace(GL_BACK);
if (1) {
if ($volume->indexed) {
my $quads_cnt = $volume->indexed_quads_to_render_cnt;
my $triangles_cnt = $volume->indexed_triangles_to_render_cnt;
if ($quads_cnt + $triangles_cnt > 0) {
if ($self->{use_VBOs}) {
my ($name_geometry, $name_triangle_indices, $name_quad_indices) = glGenBuffersARB_p(3);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, $name_geometry);
glBufferDataARB_c(GL_ARRAY_BUFFER_ARB, $volume->geometry_size, $volume->triangles_to_render_ptr, GL_STATIC_DRAW_ARB);
glInterleavedArrays_c(GL_N3F_V3F, 0, 0);
if ($quads_cnt) {
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, $name_quad_indices);
glBufferDataARB_c(GL_ELEMENT_ARRAY_BUFFER_ARB, $volume->indexed_quads_cnt * 4, $volume->quad_indices_ptr, GL_STATIC_DRAW_ARB);
glDrawElements_c(GL_QUADS, $quads_cnt, GL_UNSIGNED_INT, $volume->quad_indices_to_render_offset * 4);
}
if ($triangles_cnt) {
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, $name_triangle_indices);
glBufferDataARB_c(GL_ELEMENT_ARRAY_BUFFER_ARB, $volume->indexed_triangles_cnt * 4, $volume->triangle_indices_ptr, GL_STATIC_DRAW_ARB);
glDrawElements_c(GL_TRIANGLES, $triangles_cnt, GL_UNSIGNED_INT, $volume->triangle_indices_to_render_offset * 4);
}
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
glDeleteBuffersARB_p(($name_geometry, $name_triangle_indices, $name_quad_indices));
} else {
glInterleavedArrays_c(GL_N3F_V3F, 0, $volume->triangles_to_render_ptr);
glDrawElements_c(GL_QUADS, $quads_cnt, GL_UNSIGNED_INT, $volume->quad_indices_ptr + $volume->quad_indices_to_render_offset * 4)
if ($quads_cnt);
glDrawElements_c(GL_TRIANGLES, $triangles_cnt, GL_UNSIGNED_INT, $volume->triangle_indices_ptr + $volume->triangle_indices_to_render_offset * 4)
if ($triangles_cnt);
glInterleavedArrays_c(GL_N3F_V3F, 0, 0);
}
}
} elsif (! $volume->empty) {
if ($self->{use_VBOs}) {
my ($name_geometry) = glGenBuffersARB_p(1);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, $name_geometry);
glBufferDataARB_c(GL_ARRAY_BUFFER_ARB, $volume->triangles_to_render_cnt * 6 * 4, $volume->triangles_to_render_ptr, GL_STATIC_DRAW_ARB);
glInterleavedArrays_c(GL_N3F_V3F, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, $volume->triangles_to_render_cnt);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glDeleteBuffersARB_p(($name_geometry));
} else {
glInterleavedArrays_c(GL_N3F_V3F, 0, $volume->triangles_to_render_ptr);
glDrawArrays(GL_TRIANGLES, 0, $volume->triangles_to_render_cnt);
glInterleavedArrays_c(GL_N3F_V3F, 0, 0);
}
}
}
glPopMatrix();
$volume->render;
if ($shader_active) {
glBindTexture(GL_TEXTURE_2D, 0);