0
\$\begingroup\$

I am practically pretty new to OpenGL development and right now doing some research in Java with LWJGL. But it's really not a question about Java or C++ (GLFW, etc.). It is about OpenGL > 3 api.

Raw circumstances: I want to create a game (using LWJGL), that is kind of a tile based game, but right now i don't want to use textures. I just need colored squares. The squares can be of any size (depending on the zoom level). But they are just colored with one color, no texture.

What I need is defining objects that have size, position, and color (from a visual point of view).

I would like to have a class (sth. like Model or VertexArray or ...) that I can feed with vertex data and an array of indices. The class itself provides a constructor and a render method that take care of all the OpenGL internals (eg. binding buffers, enable vertex attrib arrays, ... and finally doing the glDrawElements(GL_TRIANGLES, this.count, GL_UNSIGNED_BYTE, 0); or similar).

Now I am a bit confused about Shaders (as I am a beginner and my needs are basic, it's just the Vertex and Fragment shaders).

From what I have read, seen and heard, I learned the following.

  1. I can provide the shader program (vertex and fragment) a buffer containing information. With locations I can put in geometric data (x, y, z) as well as coloring info (r, g, b, a) and (I think) anything else I need. The vertex shader will consume the data it needs and pass thru the data it is not interested in (eg. color). The Fragment shader is the next element in OpenGL's rendering pipeline, which will get the color as an input, if defined in the shader program itself. So it will be able to color each pixel in the according color.

  2. I can provide the shader program a buffer with just information about geometric positions. I don't want to put in colors into the buffer which is bound and consumed by the shader(s). I want to provide / change the color via uniforms.

For me it feels more natural to generate vertex array objects based on pure geometric data and change the color by setting uniforms with values that change while updating my game state.

Which one would be the preferred way of achieving this. Or am I on a wrong path?

While I am asking this, I feel that I don't understand the concepts of uniforms and even putting data into buffers, that are present to shaders like magic.

Edit: (thanks to @DMGregory) I just don't know what is the difference in performance or in developer-friendly-wise between defining the squares' colors via uniforms and via buffer data.

Is it just "Many roads lead to Rome" or ...?

\$\endgroup\$
4
  • 3
    \$\begingroup\$ "While I am asking this, I feel that I don't understand the concepts of uniforms and even putting data into buffers" - what leads you to feel this way? Can you outline your current understanding of these concepts, so a reader can check it for errors or clarifications to share in an answer? \$\endgroup\$
    – DMGregory
    Commented Aug 3, 2022 at 22:14
  • 3
    \$\begingroup\$ For what reason do you want to use uniforms instead of vertex data for your tile color? A uniform really only makes sense if you have very large groups of tiles that could be drawn consecutively with the same color. Otherwise you will need a lot of draw calls. There’s a reason every sprite batcher in every game engine I can think of puts color in the sprite vertex data. \$\endgroup\$
    – TenFour04
    Commented Aug 4, 2022 at 2:05
  • \$\begingroup\$ @TenFour04 so if I want to have a scene consisting of hundreds of game objects (not all on screen of course) - each game object consisting of at least 4 squares, I should define their colors among the vertex data? Of course tiles/squares that represent water could change their color from blue to black at night, but this will be done with shaders I guess (then here with uniforms?) ... \$\endgroup\$ Commented Aug 4, 2022 at 20:09
  • \$\begingroup\$ Your tiles have the potential to all be batched into a single draw call if they are drawn using the same shader, using the same values for the uniforms. If you need to change a shader uniform, then you have to finish the draw call before you change that uniform value. A sprite batcher would work by collecting vertex data from many sprites (or game objects) into a single array of vertex data and single array of indices so it can pass it to the GPU all at once using glDrawTriangles, a single draw call. This collecting, then drawing, is typically done every frame. You can cull if you want. \$\endgroup\$
    – TenFour04
    Commented Aug 4, 2022 at 20:18

1 Answer 1

0
\$\begingroup\$

You say you don't want to use textures right now, but as texturing is done via uniforms, and square colorings are only temporary substitutes for textures, then using uniforms for coloring is an intuitive and natural decision.

On the other hand, texturing brings with it texture coordinates that are passed as yet another attribute. Thus coloring can instead be thought of as a substitute for texture coordinates instead.

Therefore both options are fine if you ask me.

Via the uniform approach you'll have to perform split your draw calls across colors since uniforms are constant per draw calls, but as this is something you'll have to do for textures anyway, this isn't a problem. Furthermore, if you use a texture atlas (basically synonymous with sprite sheet), this again ceases to be a problem, because you can batch all your tiles and draw them at once using the same texture internally.

Either way you'll have things roughly the same number of things to change when/if you switch to textures, so I wouldn't think about it too much.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you, perhaps you just spot my misunderstanding. For me a draw call is what normally would be done at least every render for each game object. In my case all game objects are at least one square. And they won't have any texture. The color could change, depending on its state, but originally an object made of some squares will have a natural color selection. \$\endgroup\$ Commented Aug 4, 2022 at 20:06
  • \$\begingroup\$ @EdgarAlloro If you put colors as an attribute, then you can draw all your squares at once, since they will all share the same uniforms. This is a common optimization in both 3D games where objects may share materials, and 2D games, where sprites come from the same spritesheet. BTW, I've updated my answer for something I didn't account for \$\endgroup\$
    – Poopoo
    Commented Aug 4, 2022 at 20:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .