OpenGL How Many VAOs -
i writing opengl3+ application , have confusion use of vaos. right have 1 vao, normalised quad set around origin. single vao contains 3 vbos; 1 positions, 1 surface normals, , 1 gl_element_array_buffer indexing (so can store 4 vertices, rather 6).
i have set helper methods draw objects scene, such drawcube()
takes position , rotation values , follows procedure;
- bind quad vao.
- per cube face:
- create model matrix represents face.
- upload model matrix
uniform mat4 model
vertex shader variable. - call
gldrawelements()
draw quad position face.
i have set task of adding per-cube colors , realised can't add color vbo single vao change each cube, , doesn't feel right.
i have read question; opengl vao best practices, tells me approach wrong, , should use more vaos save work of setting whole scene every time.
how many vaos should used? approach of having 1 not optimal, should there vao every static surface in scene? ones move?
i writing uniform variable each vertex, correct? read uniform
shader variables should not change mid-frame, if able write different values uniform
variable, how uniforms differ simple in
variables in vertex shader?
clearly approach of having 1 not optimal, should there vao every static surface in scene?
absolutely not. switching vaos costly. if allocate 1 vao per object in scene, need switch vao before rendering such objects. scale few hundred or thousand objects visible , vao changes. questions is, if have multiple objects share common memory layout, i.e. sizes/types/normalization/strides of elements same, why want define multiple vaos store same information? control offset want start pulling vertex attributes directly corresponding draw call.
for non-indexed geometry trivial, since provide first (or array of offsets in multi-draw case) argument gl[multi]drawarrays*() defines offset associated array_buffer's data store.
for indexed geometry, , if store indices multiple objects in single element_array_buffer, can use gl[multi]drawelementsbasevertex provide constant offset indices or manually offset indices adding constant offset before uploading them buffer object.
being able provide offsets buffer store implies can store multiple distinct objects in single array_buffer , corresponding indices in single element_array_buffer. however, how large buffer objects should depends on hardware , vendors differ in recommendations.
i writing uniform variable each vertex, correct? read uniform shader variables should not change mid-frame, if able write different values uniform variable, how uniforms differ simple in variables in vertex shader?
first of all, uniforms , shader input/output variables declared in/out differ in various instances:
input/output variables define interface between shader stages, i.e. output variables in 1 shader stage backed corresponding , equally named input variable in following stage. uniform available in stages if declared same name , constant until changed application.
input variables inside vertex shader filled array_buffer. uniforms inside uniform block backed uniform_buffer.
input variables can written directly using glvertexattrib*() family of functions. single uniforms written using gluniform*() family of functions.
the values of uniforms program state. values of input variables not.
the semantic difference should obvious: uniforms, name suggests, constant among set of primitives, whereas input variables change per vertex or fragment (due interpolation).
edit: clarify , factor in nicol bolas' remark: uniforms cannot changed application set of vertices submitted single draw call, neither can vertex attributes calling glvertexattrib*(). vertex shader inputs backed buffer objects change either once per vertex or @ specific rate set glvertexattribdivisor.
edit2: clarify how vao can theoretically store multiple layouts, can define multiple arrays different indices equal semantics. instance,
glvertexattribpointer(0, 4, ....);
and
glvertexattribpointer(1, 3, ....);
could define 2 arrays indices 0 , 1, component sized 3 , 4 , both refer position attributes of vertices. however, depending on want render, can bind hypothetical vertex shader input
// if have gl_arb_explicit_attrib_location or gl3.3 available, use explicit // locations /*layout(location = 0)*/ in vec4 position;
or
/*layout(location = 1)*/ in vec3 position;
to either index 0 or 1 explicitly or glbindattriblocation() , still use same vao. afaik, spec says nothing happens if attribute enabled not sourced current shader suspect implementation ignore attribute in case.
whether source data said attributes same or different buffer object question of course possible.
personally tend use 1 vbo , vao per layout, i.e. if data made of equal number of attributes same properties, put them single vbo , single vao.
in general: can experiment stuff a lot. it!
Comments
Post a Comment