Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Drawing Vertex Array with big Texture  (Read 3878 times)

0 Members and 1 Guest are viewing this topic.

vokazoo

  • Newbie
  • *
  • Posts: 18
    • View Profile
    • Email
Drawing Vertex Array with big Texture
« on: January 24, 2024, 10:52:52 pm »
Hello, I know there have been some posts regarding max texture size, but I haven't found anything for this specific case.

What can be done if I have VertexArray and the Texture used while drawing it is bigger than Texture::getMaximumSize()? Neither storing multiple smaller Textures in an array to act as one nor thor::bigTexture are of any help here.

Also, how can I adjust my program so it's compatible with different Texture max sizes? All I can think of is simply not exceeding Texture sizes of 512x512, which is very limiting, or split Texture into multiple smaller ones, but then I lose some features of Texture, one of which is drawing them with VertexArray as mentioned above; or make multiple versions of the program, one for each max size, so users whose systems can hold larger Textures can benefit in performance while not locking out those whose can't.

Thank you for your time :)

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Drawing Vertex Array with big Texture
« Reply #1 on: January 25, 2024, 04:27:51 am »
I'm not sure I fully understand what your "specific case" is.

First thing to note is that you cannot have a texture larger that the maximum size; that maximum is given by the limitations of the graphics hardware.

What exactly are you trying to achieve? If you need a larger image to be displayed that can be stored on a texture, you can break it into multiple textures and draw them next to each other. It takes multiple draw calls, of course, as each texture switch requires a draw call. This is - I believe - what Thor's big texture and big sprite do.
A very low-end graphics card may have some issues if there are too many textures though as the ability to store all those images require the memory to do so.

As for which texture size to use, there's not guarantee. You can put some effort into providing smaller-sized images so that they will fit on a smaller texture (in addition to the size you actually prefer) to allow lower end graphics cards to use your textures.
With that said, it's generally accepted that you can "safely" use a texture size of about 2048x2048 since the majority of cards - even lower ones now - can do this. 1024x1024 is an almost certainty for compatibility. The 2k ones should be available even on phones.

Maybe this list can help (1% cannot use 2k, pretty much everyone can use 1k):
https://feedback.wildfiregames.com/report/opengl/feature/GL_MAX_TEXTURE_SIZE

This is also an interesting list:
https://store.steampowered.com/hwsurvey?platform=pc
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

vokazoo

  • Newbie
  • *
  • Posts: 18
    • View Profile
    • Email
Re: Drawing Vertex Array with big Texture
« Reply #2 on: January 25, 2024, 05:38:01 am »
Thank you for quick response,

By specific case I meant drawing VertexArray with a Texture, not necessarily displaying the whole Texture, but having the problem of Texture being too big. Since VertexArray could be drawn with only one Texture, breaking it into multiple Textures wouldn't help and as far as I know, this cannot be done with thor::BigTexture like this:
void draw(sf::RenderTarget& target, sf::RenderStates states) const override
{
        states.transform *= getTransform();
        const thor::BigTexture* bigTexture;
        states.texture = bigTexture; //error
       
        target.draw(m_vertices, states); //m_vertices of type sf::VertexArray
}

If I use multiple smaller Textures that would require multiple VertexArrays and multiple draw calls. Is this achievable in one draw call?

Not that it technically matters, but to be exact: I'm making animated bitmap text, so it makes sense I'll use VertexArray to store characters as quads, just changing texCoords as needed to update animation. With having 256+ glyphs, font sprite sheet image can easily exceed 5000x5000 px size, especially with hi-res glyphs or many animation frames. Even if I make multiple Textures and VertexArrays, not only does performance take an unnecessary hit which may be a tolerable compromise, but also Shaders that modify the VertexArray and the Texture will get messed up and I'm not sure if I'll be able adjust them, provided it's even possible. So I'd like to avoid multiple textures if anyhow possible, or at least mitigate issues caused by using them.
« Last Edit: January 25, 2024, 08:00:43 am by vokazoo »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11027
    • View Profile
    • development blog
    • Email
Re: Drawing Vertex Array with big Texture
« Reply #3 on: January 25, 2024, 11:17:53 am »
The way sf::Text kind of solves this is, that it only loads the used glyphs in the size it needs into a texture from a font size.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Drawing Vertex Array with big Texture
« Reply #4 on: January 25, 2024, 02:56:07 pm »
Yes, if you split a texture into multiple textures, you'd need to make multiple vertex arrays with multiple draw calls.

As far as I know, Thor's "big texture" is used by its "big sprite" and that can automatically draw its parts. I have no experience with using it with vertex arrays.

Ah, frame animation. The bane of image storage.
From what you've said, it sounds like you have a single-sized text that can have multiple frames of animation per character.
If this is the case - and all of the text animates together (where when the 1st character is on frame 3, the 10th character is also on frame 3) - then you can store a single set of characters per texture and switch the texture depending on the frame, allowing a single texture for the entire text.

However, if you need different frames per character, you will need multiple vertex arrays for each texture as mentioned previously. However, you can do some optimisation such as fitting multiple (some not all) frames of character sets on the same image/texture as well as drawing all of the characters that can be drawn by that texture be drawn at once. This would require some sorting. The number of textures used would be no more than the number of different frames that characters are using - if still using only one frame per texture.

Any shader will need to be adjusted to take into account multiple textures and also know which one each part needs to use.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

vokazoo

  • Newbie
  • *
  • Posts: 18
    • View Profile
    • Email
Re: Drawing Vertex Array with big Texture
« Reply #5 on: January 26, 2024, 03:08:24 am »
sf::Text lacks some control such as moving and modifying characters individually, which was the main reason I started writing my own bitmap text class.

Since I need to be able to update each character's animation individually, as it is right now and as I understood so far, one way or the other it seems multiple Textures are unavoidable... I'm just not sure how complicated it would be to adjust the Shaders. :-X

Either way, thank you for the help and ideas.
Of course if someone comes up with something in the future or has something to add feel free to reply or contact me.
« Last Edit: January 26, 2024, 03:11:42 am by vokazoo »

fallahn

  • Hero Member
  • *****
  • Posts: 505
  • Buns.
    • View Profile
    • Trederia
Re: Drawing Vertex Array with big Texture
« Reply #6 on: January 26, 2024, 11:39:00 am »
If you're willing to get your hands dirty with some OpenGL the Array Texture would help here (and would also be a nice addition to SFML, but that's another matter ;))

For example, if you have individual textures, as Hapax says, each containing an atlas of a single frame, you can load each one of these into a slot in the texture array - resulting in a single texture bind/single vertex array for all the frames.

In the first case where all characters are on the same frame, you can simply set the current frame index in the shader:

Code: [Select]
uniform sampler2DArray u_texture;
uniform float u_frameIndex;

in vec2 v_texCoord;

out vec4 o_colour;

void main()
{
    o_colour = texture(u_texture, vec3(v_texCoord, u_frameIndex));
}

Animating characters individually is a little more work, however can be done by setting the frame index of a character in its vertex data:

Code: [Select]
//vertex shader
in vec2 a_position;
in vec2 a_texCoord;
in float a_frameIndex;

out vec2 v_texCoord;
flat out float v_frameIndex;

void main()
{
    gl_Position = //usual stuff here
    v_texCoord = a_texCoord;
    v_frameIndex = a_frameIndex;
}

//then in the fragment shader we do as before, only the frame index comes from the vertex shader, not a uniform:

uniform sampler2DArray u_texture;

in vec2 v_texCoord;
flat in float u_frameIndex;

out vec4 o_colour;

void main()
{
    o_colour = texture(u_texture, vec3(v_texCoord, u_frameIndex));
}

In the latter case you could even combine the coordinates in the vertex shader if you don't mind losing the flat qualifier. It's a relatively large chunk of work to set up, however it results in a single vertex array and a single texture object for your text, and if encapsulated would be a nice addition to any library :)

hdsiria

  • Newbie
  • *
  • Posts: 23
    • View Profile
Re: Drawing Vertex Array with big Texture
« Reply #7 on: January 26, 2024, 12:02:55 pm »
What is the maximum texture size that sfml can draw?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11027
    • View Profile
    • development blog
    • Email
Re: Drawing Vertex Array with big Texture
« Reply #8 on: January 26, 2024, 01:27:56 pm »
That depends on your GPU (and your driver), you can query it with sf::Texture::getMaximumSize()
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
Re: Drawing Vertex Array with big Texture
« Reply #9 on: January 27, 2024, 04:10:13 am »
Of course these max sizes are the theoretical max size supported by the gpu/driver. It doesn't necessarily mean you can actually create one that big because it might not currently fit in memory.
For example a single 16384x16384 texture takes up 1GB of video ram.

Array textures do look like a good solution, especially since they do eliminate edge bleeding that atlases can suffer from. But getting that into SFML might be a little tricky. I've also heard bindless textures are the new preferred way, but I've never looked into them (again, not in SFML so might be tricky).

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Drawing Vertex Array with big Texture
« Reply #10 on: January 28, 2024, 05:37:32 pm »
sf::Texture::getMaximumSize()
I've noticed that this cannot be used immediately and requires a little bit of preparation first (albeit not much).
I don't know the exact requirement for preparation before this method can be called. However, creating an sf::RenderWindow first does seem to work. Just creating a sf::Context doesn't help.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11027
    • View Profile
    • development blog
    • Email
Re: Drawing Vertex Array with big Texture
« Reply #11 on: January 28, 2024, 06:00:23 pm »
I've noticed that this cannot be used immediately and requires a little bit of preparation first (albeit not much).
I don't know the exact requirement for preparation before this method can be called. However, creating an sf::RenderWindow first does seem to work. Just creating a sf::Context doesn't help.
What version are you on?

I've fixed an issue with sf::Texture::getMaximumSize() in 2.6.1: https://github.com/SFML/SFML/pull/2603
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Drawing Vertex Array with big Texture
« Reply #12 on: January 28, 2024, 07:00:50 pm »
Haha! I checked the master to see if that issue was around but didn't think to check before then. I'm still using 2.6.0 so you can probably ignore my ignorant post above. ;D
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

vokazoo

  • Newbie
  • *
  • Posts: 18
    • View Profile
    • Email
Re: Drawing Vertex Array with big Texture
« Reply #13 on: January 29, 2024, 01:15:31 am »
If you're willing to get your hands dirty with some OpenGL the Array Texture would help here (and would also be a nice addition to SFML, but that's another matter ;))
I'm not against the idea, I just have no clue how I'd approach it.

The way you describe it, Array Texture seems perfect. However, how would I use it with SFML? Is it even possible? Also, it looks like you used a non-legacy version of glsl in those examples which I'm not sure how to use with SFML too. For example, how are these values provided into shader?:
//vertex shader
in vec2 a_position;
in vec2 a_texCoord;
in float a_frameIndex;
//
uniform sampler2DArray u_texture;

I'm aware that may be due to my lack of understanding of OpenGL, so if that's the case please let me know. Thank you

fallahn

  • Hero Member
  • *****
  • Posts: 505
  • Buns.
    • View Profile
    • Trederia
Re: Drawing Vertex Array with big Texture
« Reply #14 on: January 29, 2024, 10:54:59 am »
Quote
I'm not against the idea, I just have no clue how I'd approach it.
I'm aware that may be due to my lack of understanding of OpenGL, so if that's the case please let me know. Thank you

I apologise if this is jumping in at the deep end a little - I just wanted to highlight what's possible if you're able to mix some OpenGL with SFML.

However, if there are any SFML devs reading this, I think sf::ArrayTexture might not be a bad idea? It would also be useful for animating sprites, for example. Array textures are available though this extension.