Tengo que dibujar varios cubos (dependiendo de los datos, desde 6k hasta, en un caso extremo, 11k objetos).

Los cubos tienen posiciones fijas que no cambian durante la animación, sin embargo, el color cambia en cada cuadro. Creo que es posible dibujar geometría una vez y luego volver a dibujar el color, pero ¿cómo se puede lograr eso de manera eficiente?

Además, soy un principiante total, por lo que solo tengo un conocimiento básico de OpenGL. ¿Cuál es la mejor práctica (asumiendo el uso de PyOpenGL)?

1
LemurPwned 12 nov. 2017 a las 00:11

2 respuestas

La mejor respuesta

Ha pasado un tiempo, pero mientras tanto resolví este problema y pensé que publicar una respuesta podría ser útil.

Generalmente, como sugirió BeyelerStudios, glBufferData se puede usar para determinar si el contenido de un búfer debe cambiarse dinámicamente configurando GL_DYNAMIC_DRAW o {{ X2}} como parámetro usage. Sin embargo, hay un poco más de esto, ya que podemos ir aún más lejos. Voy a usar PyOpenGl para explicar eso, pero probablemente lo mismo se aplica a la api de C ++.

Echemos un vistazo a un conjunto de funciones que podrían ser responsables de crear VBO:

def create_vbo(self):

    buffers = gl.glGenBuffers(2)
    # vertices buffer is static, so GL_STATIC_DRAW
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, buffers[0])
    gl.glBufferData(gl.GL_ARRAY_BUFFER,
                    self.vectors_list,
                    gl.GL_STATIC_DRAW)
    # colour buffer
    # note the parameter GL_DYNAMIC DRAW - this buffer will be rebound
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, buffers[1])
    gl.glBufferData(gl.GL_ARRAY_BUFFER,
                    self.colour_vectors[self.i],
                    gl.GL_DYNAMIC_DRAW)
    return buffers

def vbo_cubic_draw(self):
    ... # make sure buffers are not None i.e. were created
    # actually replaces data in colour buffer
    gl.glBufferSubData(gl.GL_ARRAY_BUFFER, 0, self.buffer_len,
                                        colour_vectors[self.i])
    self.draw_vbo() # call drawing


 def draw_vbo(self):
    ... # enable client states
    # bind vertex buffer - will be static
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.buffers[0])
    gl.glVertexPointer(4, gl.GL_FLOAT, 0, None)
    # bind color buffer which is dynamic
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.buffers[1])
    gl.glColorPointer(3, gl.GL_FLOAT, 0, None)
    ... # do more stuff and actually draw 

Básicamente, la función create_vbo declara dos búferes: búfer de vértice como estático y búfer de color como dinámico. Un paso adicional que podemos tomar es utilizar glBufferSubdata en lugar de glBufferData para el búfer dinámico en vbo_cubic_draw. Entonces solo se requiere volver a dibujar el búfer de color y luego podemos llamar a alguna función de dibujo (por ejemplo, glDrawArrays) en draw_vbo. Obviamente, tal enfoque requiere dos búferes separados, uno para el color y otro para los vértices, lo que a veces no es deseado. Pero mirando glBufferSubdata doc, No creo que sea posible usarlo para búferes intercalados individuales, ya que solo tenemos el parámetro offset . ¿Quizás alguien tiene una opinión diferente sobre eso? EDITAR. En realidad, podría ser muy posible si la matriz está bien empaquetada y estructurada correctamente; sospecho que puede usar solo un búfer grande en lugar de muchos.

0
LemurPwned 18 jun. 2018 a las 11:14

No tengo ninguna experiencia con pyOpenGL específicamente, pero tengo mucha experiencia con webGL y algunas con openGL, así que espero que esto sea útil.

No estoy completamente seguro de lo que quiere decir con dibujar geometría una vez y luego simplemente dibujar color, ¿quiere decir simplemente tener un búfer para la posición y otro para el color y luego solo cambiar el color? Si es así, no creo que sea posible, porque creo que openGL solo puede manejar un búfer de atributo de vértice a la vez.

Yo diría que la mejor manera de hacer esto es poner todos los cubos en el mismo búfer para reducir las llamadas de dibujo y establecer el uso del búfer en GL_DYNAMIC_DRAW como comentó BeyelerStudios, ya que los búferes dinámicos están destinados a ser accedidos con frecuencia. Luego, actualiza tanto la posición como los datos de color en este búfer al cambiar el color.

¡Espero que esto ayude!

0
kylengelmann 12 nov. 2017 a las 00:32