2

Let's say we are drawing a bunch of rectangles in OpenGL. That is, we're filling up a vertex buffer and then drawing them all in a single call call via drawArrays, like this:

let count = 3;

gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

gl.drawArrays(gl.TRIANGLES, 0, 6 * count);

My question is: is it guaranteed that later rectangles will be drawn on top of prior rectangles? I'm not using depth testing, and everything is 2D and on the same z-axis.

It always seems to be the case in my testing, but my reason for assuming it may not always be the case is that GPUs are parallel. That is, say we were to draw 100,000 rectangles. Obviously the GPU is not rendering them sequentially, as the GPU is a parallel device, and the rendering completes in milliseconds.

If that is indeed the case, then is it possible for rectangles earlier in the buffer to be drawn on top of rectangles later in the buffer? Because they are all drawn at the same time? And if so, is there any way to prevent this? For my application, I want to be positive that quads later in the vertex buffer are always drawn on top of previous quads.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Ryan Peschel
  • 11,087
  • 19
  • 74
  • 136
  • @Rabbid76 That is good to hear. I guess I'm curious as to _how_ this is possible though. Aren't they all drawn simultaneously? How can this be guaranteed? Don't get me wrong, I'm ecstatic that this is the case, but I am still curious how this sort of thing is possible with a parallel operation. – Ryan Peschel Jul 29 '21 at 19:01
  • Oh, welp. Is there any way _to_ guarantee it? I am sorting all my sprites right now and drawing each one individually, but I'd like to change it to draw them all in a single draw call. But I guess this isn't possible? How do other games do it? Apparently you can't use z-indexes because then you lose opacity / transparency.. so.. not sure what to do here. – Ryan Peschel Jul 29 '21 at 19:09
  • (Desktop-)OpenGL guarantees that primitives are drawn in the order they are specified in the buffers (see [OpenGL 4.6 Spec](https://www.khronos.org/registry/OpenGL/specs/gl/glspec46.core.pdf), Section 7.13.1). Unfortunately, the OpenGL ES specs don't mention shader access memory order at all, so it is not guaranteed and there is no way to guarantee it. (unless you are planning to render each primitive with a separate draw call). But since the OpenGL spec requires it, I'd assume (and my own tests also confirm it on the drivers available to me) that Desktop GPUs will draw in that order. – BDL Jul 29 '21 at 19:35
  • @BDL But isn't OpenGL ES just version 2 of Desktop OpenGL basically? I really hope it's not the case that this is guaranteed on desktop but not on mobile. Do you think that's a possibility? Hmm.. – Ryan Peschel Jul 29 '21 at 19:50
  • 1
    Np. OpenGL ES and _desktop OpenGL are completely different specifications. Compare [OpenGL ES Specification - Khronos OpenGL ES Registry](https://www.khronos.org/registry/OpenGL/index_es.php) and [OpenGL specification - Khronos OpenGL registry](https://www.khronos.org/registry/OpenGL/index_gl.php). – Rabbid76 Jul 29 '21 at 19:51
  • Unfortunate. Another question: where in section 7.13.1 of that above link does it mention that primitives are drawn in the order specified in the buffers? I can't find the line. – Ryan Peschel Jul 29 '21 at 19:53
  • @RyanPeschel: In the middle of Page 160 (pdf page 182), specifically the sentence: *while fragment shader outputs are always written to the framebuffer in primitive order* See also [Does the order of the pixels drawn depend on the indices in glDrawElements?](https://stackoverflow.com/questions/22207460/does-the-order-of-the-pixels-drawn-depend-on-the-indices-in-gldrawelements) – BDL Jul 29 '21 at 19:56
  • Okay, cool. So it still looks like I'll be fine then relying on this assumption. That is good news. So I guess the conclusion is.. "It's guaranteed on OpenGL, but not OpenGL ES, although it seems to be the case in OpenGL ES that it follows this behavior, and exactly how this works (considering drawing is a parallel operation), is magic"? – Ryan Peschel Jul 29 '21 at 19:59
  • See also [Primitive Assembly](https://www.khronos.org/opengl/wiki/Primitive_Assembly). – Rabbid76 Jul 29 '21 at 20:03
  • You might want to read [Parallelism in GPU's rasterization process](https://gamedev.stackexchange.com/questions/141085/parallelism-in-gpus-rasterization-process) about how modern GPUs tend to parallelize. At least all driver implementations I saw till now implicitly order triangles in buffer order because of the order in which they arrive in the tile bucket sorting algorithm. But my experience is almost only on desktop and server GPUs, not on mobile ones. – BDL Jul 29 '21 at 20:07

0 Answers0