c++ - Better to update a small vertex buffer, or send a uniform? -


i'm writing/planning gui renderer opengl (core profile) game engine, , i'm not sure how should representing vertex data quads. far, i've thought of 2 possible solutions:

1) straightforward way, every guielement keeps track of it's own vertex array object, containing 2d screen co-ordinates , texture co-ordinates, , updated (glbuffersubdata()) time guielement moved or resized.

2) globally store single vertex array object, co-ordinates (0,0)(1,0)(0,1)(1,1), , upload rect vec4 uniform (x, y, w, h) every frame, , transform vertex positions in vertex shader (vertex.xy *= guirect.zw; vertex.xy += guirect.xy;).

i know method #2 works, want know 1 better.

i idea of option two, however, quite inefficient because requires draw call each element. mentioned other replies, biggest performance gains lie in batching geometry , reducing number of draw calls. (in other words, reducing time application spends communicating gl driver).

so think fastest possible way of drawing 2d objects opengl using technique similar option one, adding batching it.

the smallest possible vertex format need in order draw quadrilateral on screen simple vec2, 4 vec2s per quadrilateral. texture coordinates can generated in lightweight vertex shader, such this:

// xy = vertex position in normalized device coordinates ([-1,+1] range). attribute vec2 vertexpositionndc;  varying vec2 vtexcoords;  const vec2 scale = vec2(0.5, 0.5);  void main() {     vtexcoords  = vertexpositionndc * scale + scale; // scale vertex attribute [0,1] range     gl_position = vec4(vertexpositionndc, 0.0, 1.0); } 

in application side, can set double buffer optimize throughput, using 2 vertex buffers, can write 1 of them on given frame flip buffers , send gl, while start writing next buffer right away:

// update: gluint vbo = vbos[currentvbo]; glbindbuffer(gl_array_buffer, vbo); glbuffersubdata(gl_array_buffer, dataoffset, datasize, data);  // draw: gldrawelements(...);  // flip buffers: currentvbo = (currentvbo + 1) % num_buffers; 

or simpler option use single buffer, allocate new storage on every submission, avoid blocking, so:

glbindbuffer(gl_array_buffer, vbo); glbufferdata(gl_array_buffer, datasize, data, gl_stream_draw); 

this known , used technique simple async data transfers. read this more.

it idea use indexed geometry. keep index buffer of unsigned shorts vertex buffer. 2-byte per element ib reduce data traffic quite bit , should have index range big enough amount of 2d/ui elements might wish draw.


Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

javascript - Highcharts multi-color line -

javascript - Enter key does not work in search box -