opengl opengl-3 vao

OpenGL VAO mejores prácticas



opengl-3 (4)

¿Es esta una práctica correcta?

Sí, esto es perfectamente legal y válido. ¿Esta bien? Bien...

Ha habido algunas pruebas de rendimiento informales en este tipo de cosas. Y parece que, al menos en el hardware de NVIDIA donde esto se probó, el uso "adecuado" de VAO (es decir, lo que todos los demás defendieron) en realidad es más lento en muchos casos. Esto es especialmente cierto si el cambio de VAO no cambia qué búferes están vinculados.

A mi entender, no se han realizado pruebas de rendimiento similares en el hardware de AMD. En general, a menos que algo cambie con ellos, este es un uso aceptable de los VAO.

Estoy enfrentando un problema que creo que depende de VAO, pero no estoy seguro ...

No estoy seguro del uso correcto de un VAO, lo que solía hacer durante la inicialización de GL era simple

glGenVertexArrays(1,&vao)

seguido por un

glBindVertexArray(vao)

y más tarde, en mi proyecto de dibujo, acabo de llamar a glBindBuffer (), glVertexAttribPointer (), glEnableVertexAttribArray () y así sucesivamente ... sin preocuparme por el VAO vinculado inicialmente

¿Es esta una práctica correcta?


La respuesta de Robert anterior funcionó para mí cuando lo probé. Lo que vale aquí es el código, en Go, de usar múltiples Objetos de atributo de Vertex:

// VAO 1

vao1 := gl.GenVertexArray() vao1.Bind() vbo1 := gl.GenBuffer() vbo1.Bind(gl.ARRAY_BUFFER) verticies1 := []float32{0, 0, 0, 0, 1, 0, 1, 1, 0} gl.BufferData(gl.ARRAY_BUFFER, len(verticies1)*4, verticies1, gl.STATIC_DRAW) pa1 := program.GetAttribLocation("position") pa1.AttribPointer(3, gl.FLOAT, false, 0, nil) pa1.EnableArray() defer pa1.DisableArray() vao1.Unbind() // VAO 2 vao2 := gl.GenVertexArray() vao2.Bind() vbo2 := gl.GenBuffer() vbo2.Bind(gl.ARRAY_BUFFER) verticies2 := []float32{-1, -1, 0, -1, 0, 0, 0, 0, 0} gl.BufferData(gl.ARRAY_BUFFER, len(verticies2)*4, verticies2, gl.STATIC_DRAW) pa2 := program.GetAttribLocation("position") pa2.AttribPointer(3, gl.FLOAT, false, 0, nil) pa2.EnableArray() defer pa2.DisableArray() vao2.Unbind()

Luego, en su ciclo principal puede usarlos como tales:

for !window.ShouldClose() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) vao1.Bind() gl.DrawArrays(gl.TRIANGLES, 0, 3) vao1.Unbind() vao2.Bind() gl.DrawArrays(gl.TRIANGLES, 0, 3) vao2.Unbind() window.SwapBuffers() glfw.PollEvents() if window.GetKey(glfw.KeyEscape) == glfw.Press { window.SetShouldClose(true) } }

Si desea ver la fuente completa, está disponible como una idea general y se deriva de los ejemplos en go-gl:

https://gist.github.com/mdmarek/0f73890ae2547cdba3a7

Gracias a todos por las respuestas originales, tuve la misma pregunta que ECrownofFire.


Los VAO actúan de forma similar a los VBO y las texturas con respecto a cómo están vinculados. Tener un único VAO vinculado a la duración total de su programa no arrojará beneficios de rendimiento, ya que también podría estar renderizando sin VAO en absoluto. De hecho, puede ser más lento dependiendo de cómo la implementación intercepta la configuración del atributo de vértice a medida que se dibujan.

El objetivo de un VAO es ejecutar todos los métodos necesarios para dibujar un objeto una vez durante la inicialización y cortar toda la sobrecarga del método extra durante el ciclo principal. El punto es tener varios VAO y cambiar entre ellos cuando se dibuja.

En términos de mejores prácticas, así es cómo debe organizar su código:

initialization: for each batch generate, store, and bind a VAO bind all the buffers needed for a draw call unbind the VAO main loop/whenever you render: for each batch bind VAO glDrawArrays(...); or glDrawElements(...); etc. unbind VAO

Esto evita el desorden de los búferes de enlace / desvinculación y pasa todos los ajustes para cada atributo de vértice y lo reemplaza con una sola llamada a método, vinculando un VAO.


No, así no es como usas VAO. Debe usar VAO de la misma manera que está usando VBO o texturas, o sombreadores. Primero configúralo. Y durante la renderización, únelos, sin modificarlos.

Entonces con VAO haces lo siguiente:

void Setup() { glGenVertexArrays(..); glBindVertexArray(..); // now setup all your VertexAttribPointers that will be bound to this VAO glBindBuffer(..); glVertexAttribPointer(..); glEnableVertexAttribArray(..); } void Render() { glBindVertexArray(vao); // that''s it, now call one of glDraw... functions // no need to set up vertex attrib pointers and buffers! glDrawXYZ(..) }

Ver también estos enlaces: