Skip to content

Add OES_texture_npot extension for OpenGL ES#3716

Closed
Zombieschannel wants to merge 1 commit into
SFML:masterfrom
Zombieschannel:fix-npot
Closed

Add OES_texture_npot extension for OpenGL ES#3716
Zombieschannel wants to merge 1 commit into
SFML:masterfrom
Zombieschannel:fix-npot

Conversation

@Zombieschannel

Copy link
Copy Markdown
Contributor

For some reason since the first ever mobile SFML version 12 years ago, the GLEXT_texture_non_power_of_two support has been hardcoded to false on mobile devices. It clearly says in the comment above the name of the extension but it is set to false anyway.
Since I had some texture scaling issues with imgui-sfml, I decided to investigate what was going on and simply enabling this extension seems to have fixed my issue, textures with imgui-sfml now look fine.

The issue was likely here: https://github.com/SFML/SFML/blob/master/src/SFML/Graphics/Texture.cpp#L1073
SFML thinking the system does not support non power of two textures when it does.

@Zombieschannel Zombieschannel changed the title Add OES_texture_npot extension to OpenGL ES Add OES_texture_npot extension for OpenGL ES May 18, 2026
@binary1248

Copy link
Copy Markdown
Member

Hardcoding it to false was always correct here. The comment above the line (just like the comment above every other line) is merely an explanation for when the extension became part of the core standard. We are not using OpenGL ES 2.x or later here, so conservatively hardcoding support to false while we limit ourselves to OpenGL ES 1.x is correct. POT texture support is guaranteed to be available on all OpenGL ES implementations.

In absence of NPOT texture support the code you linked returns the next larger valid POT texture size which the caller can then use when creating a texture. This should prevent the GL implementation from returning NPOT errors which it would have otherwise done if requesting a NPOT texture on a system that does not support it.

Whatever issue you are having cannot be related to the fact that we are rounding sizes up to the next POT so nothing has to be fixed here. Code that uses the sfml-graphics API has to be aware that the internally allocated texture size is not always equal to the size that was requested during texture creation. Not taking this into account will lead to unexpected results.

@Zombieschannel

Copy link
Copy Markdown
Contributor Author

Ah I see, the issue is just imgui-sfml using Texture::getSize which then may return the NPOT texture size. Would be useful if Texture::getValidSize was public instead of private for this scenario then (since imgui-sfml uses the native handle and texture coordinates in 0 - 1).

I still don't get why is support for NPOT textures on GLES hardcoded to false? If we're only using the functionality OpenGL ES 1.0, then why aren't all 2.0+ extensions hardcoded to false (SF_GLAD_GL_OES_framebuffer_object, SF_GLAD_GL_OES_packed_depth_stencil...)?
If the system supports NPOT textures, why not use it?
Same goes for desktop OpenGL, for NPOT it uses SF_GLAD_GL_ARB_texture_non_power_of_two which as it says is also OpenGL 2.0+. SFML is still using OpenGL 1.1 on desktop so why not also set it to false?

@binary1248

Copy link
Copy Markdown
Member

The OpenGL ES ecosystem is maintained differently from desktop OpenGL. While desktop OpenGL implementations are provided by ICDs (installable client drivers) which can be user-upgraded over time to fix or add new functionality, OpenGL ES implementations are more often than not bound more tightly to the hardware platforms and operating systems they are running on.

This means that the likelihood of newer extensions being made available to older base versions is much lower for OpenGL ES than it is for desktop OpenGL. Couple this with the fact that OpenGL ES decided that going from 1.x to 2.x is a breaking change without any backwards compatibility means that functionality that got merged into 2.x is unlikely to be backported to 1.x on most platforms.

OpenGL ES is meant to run on resource constrained systems, so they don't want to have to carry any unnecessary baggage. Desktop driver packages can reach into the GBs nowadays. I don't think phone users would be happy knowing that a large chunk of their precious storage space is taken up by a huge driver package.

Expecting applications targeting ES to commit to a specific version of the API for the entirety of their service lifecycle is more acceptable than if the same were to be attempted for desktop applications. This is why your typical Android or iOS app might stop functioning after a few upgrades of the operating system whereas your Windows application from 20 years ago still runs fine today.

@Zombieschannel

Copy link
Copy Markdown
Contributor Author

I'd say it is valid to focus only on OpenGL ES 1.x stuff, but SFML already uses some OpenGL ES 2.0 and even OpenGL ES 3.0 extensions, so I don't see what makes this extension "not worthy" of being used as well. Did this extension not exist at the time when SFML mobile ports were initially made? Was it buggy on devices? Something else? I don't get it...

@binary1248

Copy link
Copy Markdown
Member

Did this extension not exist at the time when SFML mobile ports were initially made?

According to the specification, the first version was published in 2005. This is not the right question to ask, it is common for industry standards to take many years to reach widespread adoption after their initial specification was ratified. It doesn't make sense to jump on every new extension we can just because they exist. Maintaining code paths to handle extensions is additional work and if we have the feeling it won't benefit the majority of SFML users we just save it for some time in the future.

Was it buggy on devices?

It probably still is buggy on some devices as of today. As I said previously, maintaining older ES implementations isn't exactly a high priority for the developers tasked with ES work. If their market research tells them the majority of the API users already moved on to newer standards it is very likely they won't spend time fixing bugs/regressions in older versions. Adding purely optional extensions is even less attractive of a task and if they do bother doing it the implementation is likely to contain bugs and other strange behaviour.

Anecdotal evidence suggests that NPOT textures still exhibit unexpected behaviour on certain ES platforms as of today. It would be unwise for us to start relying on functionality that still has not become stable enough for general use even this many years after it became available. Debugging these kinds of issues on desktop platforms is already hard enough, we don't have to burden ourselves with writing workarounds for weird ES implementations as well, especially since it would be almost impossible for those writing the code to properly test it because the behaviour is so implementation dependent.

Simply put: The current implementation just works. Sure it is conservative, but until users come with a credible use case where over-allocating texture memory is causing them to run out faster than would otherwise be the case, I don't see the practical advantage either the maintainers or users would have by starting to probe for the extension. This cannot be compared to the desktop extension. It is much easier for us to reproduce issues on the desktop platform because the implementations are user-installable and besides drivers from Nvidia, AMD, and Intel there aren't really any others as of today.

For applications where over-allocating a large number of textures could start to become a problem, the standard solution was always to batch textures into an atlas. And even though it is barely measurable, the arithmetic that has to performed to make use of the atlas benefits from optimizations that can be made when working with power-of-two values. Even though I don't have any hard evidence, it wouldn't surprise me if the big engines also prefer using POT textures if they have a choice. The integer and floating-point maths around power-of-two values is just nicer to deal with.

@Zombieschannel

Copy link
Copy Markdown
Contributor Author

Alright, thanks for the answer

@Zombieschannel Zombieschannel deleted the fix-npot branch May 20, 2026 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants