I am looking for an optimization of my code, which print a Planet. Actually, I want to rotate my camera to see the different parts of my planet, but it is really slow and long.
Here is a part of my pyOpenGL code, which print my differents objects:
def _DrawGLScene(self):
if not self.printed:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
# Camera movements
glTranslatef(0.0, 0.0, self.move_z)
glRotatef(self.rx, 1.0, 0.0, 0.0)
glRotatef(self.ry, 0.0, 1.0, 0.0)
glRotatef(self.rz, 0.0, 0.0, 1.0)
# Print objects
if not self.printed:
self.planet.draw()
self.printed = True
glutSwapBuffers()
The method self.planet.draw()
only draw a Triangle object list with there own draw_triangle
method defined as that:
def draw_triangle(self):
glBegin(GL_POLYGON)
glColor3f(self.color_a[0], self.color_a[1], self.color_a[2])
glVertex3f(self.point_a[0], self.point_a[1], self.point_a[2])
glColor3f(self.color_b[0], self.color_b[1], self.color_b[2])
glVertex3f(self.point_b[0], self.point_b[1], self.point_b[2])
glColor3f(self.color_c[0], self.color_c[1], self.color_c[2])
glVertex3f(self.point_c[0], self.point_c[1], self.point_c[2])
glEnd()
return
When I rotate the camera, I have to redraw all the triangles, which is really slow for something like 100,000 triangles. How can I optimize the usage of OpenGL?
There are various levels of optimization you can use.
A very simple change that might already help you quite a bit is that you should not put glBegin(..)
and glEnd()
around each triangle. It might also be beneficial to use GL_TRIANGLES
instead of GL_POLYGON
as the primitive type. It sounds like your code structure currently looks like this:
draw_triangle
glBegin(GL_POLYGON)
// specify colors, vertices
glEnd()
draw
loop over triangles
draw_triangle
What you should do instead is this:
draw_triangle
// specify colors, vertices
draw
glBegin(GL_TRIANGLES)
loop over triangles
draw_triangle
glEnd()
To take the whole thing to the next level, you need to look into more modern approaches. What you are currently using, with calls like glBegin
, glEnd
, glVertex
is mostly referred to as "immediate mode" drawing, and is deprecated in newer OpenGL versions.
If you search for terms like "vertex buffer objects" (mostly abbreviated "VBO") and "vertex array objects" ("VAO"), you should be able to find good tutorials on how to use those features. You will be using calls like glGenBuffers
, glBindBuffer
, glGenVertexArrays
, glBindVertexArray
, glVertexAttribPointer
, etc. They will allow you to make your drawing much more efficient.