Home > Enterprise >  Opengl - how draw button of any size from tiles using texture atlas
Opengl - how draw button of any size from tiles using texture atlas

Time:01-06

I want create buttons of any size using tiles duplication stored in texture atlas. This means, I am going to duplicate some parts of the texture to preserve correct sizes for corners and border lines.

I created square texture as a skin. It's size is 96x96 pixels. You can see it below.

enter image description here

I split this texture into 9 tiles and I store it in texture atlas. One tile is 32px size.

enter image description here

Now I duplicate corners and borders to create button

enter image description here

If I create buttons with size 96px, 128px, 160px, ...etc - everything is fine. No graphic artifacts

If I create button with not standard size (for example 100px) then by placing tiles side by side is at the end created the hole which is not size of tile. For example, if button's size is 100px then I put 3 tiles of 32px side by side and the rest is 4 pixels.

I can resize 32px tile to remaning 4px, but many times I see there graphic artifacts or it looks a bit differently then the other tiles (of course, it is stretched).

Here is the example:

enter image description here

How to deal with this? Or is this way of making buttons completely wrong?

CodePudding user response:

Your approach does have two major issues:

  1. if your component (Button) has a size, that is not a multiple of the tile extents, scaling or cutting is unavoidable
  2. if you scale the tiles, the radius of the corners and the line thickness of the border will be distorted by the scaling factors

In the comments section above, you mentioned that the border (i assume the radius and the line thickness) should stay intact, no matter the size of the component (Button).

As a solution, i would recommend a two pass rendering:

  1. create a 1 component (GL_RED) texture atlas, which functions as an alpha mask for the border
  2. render the content area of your Button (i am not sure if you use a single color or a texture as filling, if latter, you'll have to use another texture for that). You have two options on how to cut out the border area:
    • use a round rect geometry (coords and tex coords)
    • use the border alpha mask to discard the specific areas
  3. enable blending and render the border. Since the border is specified as an alpha mask, use a uniform to specify the border color (and maybe the opacity, which lets you control the border intensity)

The only downside to this approach is, that your Button will have a minimum size (that would be size of the border: inset left right and bottom top).

The upsides are, that your background is independent from the border (and vice versa) and the borders of all your Buttons/Components will have a consistent visual appearance (maybe you want to present more than one Button at a time), no matter of the individual extents.

  • Related