opengl es - OES_vertex_array_object y estado del cliente
opengl-es opengl-es-2.0 (4)
Bueno, una cita de las especificaciones de extensión lo explica de manera bastante simple:
¿Debería permitirse que un objeto de matriz de vértices encapsule matrices de vértices de cliente?
RESUELTO: No. El grupo de trabajo de OpenGL ES estuvo de acuerdo en que la compatibilidad con OpenGL y la capacidad de guiar a los desarrolladores a un diseño más eficiente al imponer el uso de VBO eran más importantes que la posibilidad de perjudicar la adopción de VAO.
Por lo tanto, puede unir dos búferes diferentes en un VAO, (bueno, el enlace del búfer no está almacenado en el VAO, de todos modos, solo los búferes de origen de los atributos individuales, configurados mediante glVertexAttribPointer
) pero no puede usar la memoria de espacio del cliente en un VAO, solo VBOs. Esto es lo mismo para el escritorio GL.
Así que le aconsejo que almacene todos sus datos de vértice en VBO. Si desea utilizar la memoria del cliente porque los datos se actualizan dinámicamente y cree que los VBO no le comprarán nada allí, ese sigue siendo el enfoque equivocado. Simplemente use un VBO con un uso dinámico ( GL_DYNAMIC_DRAW
o incluso GL_STREAM_DRAW
) y actualícelo usando glBuffer(Sub)Data
o glMapBuffer
(o la buena glBufferData(..., NULL); glMapBuffer(GL_WRITE_ONLY)
).
Quiero un objeto de matriz de vértices en OpenGL ES 2.0 para contener dos atributos de diferentes búferes, el segundo búfer se lee de la memoria del cliente ( glBindBuffer(GL_ARRAY_BUFFER, 0)
) Pero obtengo un error de tiempo de ejecución:
GLuint my_vao;
GLuint my_buffer_attrib0;
GLfloat attrib0_data[] = { 0, 0, 0, 0 };
GLfloat attrib1_data[] = { 1, 1, 1, 1 };
void init()
{
// setup vao
glGenVertexArraysOES(1, &my_vao);
glBindVertexArrayOES(my_vao);
// setup attrib0 as a vbo
glGenBuffers( 1, &my_buffer_attrib0 );
glBindBuffer(GL_ARRAY_BUFFER, my_buffer_attrib0);
glBufferData( GL_ARRAY_BUFFER, sizeof(attrib0_data), attrib0_data, GL_STATIC_DRAW );
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray( 0 );
glEnableVertexAttribArray( 1 );
// "end" vao
glBindVertexArrayOES( 0 );
}
void draw()
{
glBindVertexArrayOES(my_vao);
// (now I assume attrib0 is bound to my_buffer_attrib0,
// and attrib1 is not bound. but is this assumption true?)
// setup attrib1
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, attrib1_data);
// draw using attrib0 and attrib1
glDrawArrays( GL_POINTS, 0, 1 ); // runtime error: Thread1: EXC_BAD_ACCESS (code=2, address=0x0)
}
Lo que quiero lograr es ajustar el enlace de dos atributos como un buffer de matriz de vértices:
void draw_ok()
{
glBindVertexArrayOES( 0 );
// setup attrib0
glBindBuffer( GL_ARRAY_BUFFER, my_buffer_attrib0 );
glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, 0, 0);
// setup attrib1
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, attrib1_data);
glEnableVertexAttribArray( 0 );
glEnableVertexAttribArray( 1 );
// draw using attrib0 and attrib1
glDrawArrays( GL_POINTS, 0, 1); // ok
}
¿Es posible unir dos búferes diferentes en un objeto de matriz de vértices? ¿OES_vertex_array_object es diferente de los objetos de matriz de vértices OpenGL (simples)? También tenga en cuenta que recibo este error en XCode con el simulador de iOS. Estos son enlaces relacionados:
Después de algunas excavaciones (lectura), se encontraron respuestas encontradas en OES_vertex_array_object . Parece que el enfoque de OES_vertex_array_object en el estado en el lado del servidor y el estado del cliente se usan solo si el objeto cero está vinculado. Queda por responder si OES_vertex_array_object es lo mismo que OpenGL VAO. Comente si conoce la respuesta a esto. A continuación hay citas de OES_vertex_array_object :
This extension introduces vertex array objects which encapsulate
vertex array states on the server side (vertex buffer objects).
* Should a vertex array object be allowed to encapsulate client
vertex arrays?
RESOLVED: No. The OpenGL ES working group agreed that compatibility
with OpenGL and the ability to to guide developers to more
performant drawing by enforcing VBO usage were more important than
the possibility of hurting adoption of VAOs.
An INVALID_OPERATION error is generated if
VertexAttribPointer is called while a non-zero vertex array object
is bound, zero is bound to the <ARRAY_BUFFER> buffer object binding
point and the pointer argument is not NULL [fn1].
[fn1: This error makes it impossible to create a vertex array
object containing client array pointers, while still allowing
buffer objects to be unbound.]
And the presently attached vertex array object has the following
impacts on the draw commands:
While a non-zero vertex array object is bound, if any enabled
array''s buffer binding is zero, when DrawArrays or
DrawElements is called, the result is undefined.
¡Así que EXC_BAD_ACCESS fue el resultado indefinido!
Eliminar la siguiente línea:
glBindBuffer( GL_ARRAY_BUFFER, 0 );
de la función draw()
. No has enlazado ningún buffer antes y puede estropear el estado del buffer.
La funcionalidad que desea ahora ha sido aceptada por la comunidad como una extensión de WebGL:
http://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/