Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

non-power of two textures

160 views
Skip to first unread message

bob smith

unread,
Jul 29, 2012, 3:23:56 PM7/29/12
to
Would I be a jerk if I required all my game users to support non-power of two textures?

How do you tell easily if this feature is supported?

jbwest

unread,
Jul 29, 2012, 10:10:55 PM7/29/12
to

"bob smith" <b...@coolfone.comze.com> wrote in message
news:77498dbf-cda5-468d...@googlegroups.com...
> Would I be a jerk if I required all my game users to support non-power of
> two textures?
>
> How do you tell easily if this feature is supported?


Depends on what other minimum features you need, and your target platforms.
Cell phones? Tablets?

Query for the extension.

jbw


fungus

unread,
Jul 30, 2012, 5:36:39 AM7/30/12
to
On Sunday, July 29, 2012 9:23:56 PM UTC+2, bob smith wrote:
> Would I be a jerk if I required all my game users to support non-power of two textures?
>

Yes.

>
>
> How do you tell easily if this feature is supported?

Unless you're programming for a specific
system it's best to program as if it isn't
supported.

Supporting npo2 should be a bonus feature
added if you have time left over to do it,
not the other way around.



Images which are used in 3D or tiled can be
resized to power-of-two without any real
visual difference (they get filtered and
interpolated anyway as part of mipmapping).

For 2D images that need exact 1:1 pixel
correspondence you can allocate a texture
which is too big and put your image in the
corner. You might be able to use the unused
area for smaller images. If you want to
step up a level you can make textures as
big as the hardware supports and pack several
images into them, optimizing for best fit.

As programmer it's your job to make it work,
even if it looks different on different hardware.

Nobody

unread,
Jul 30, 2012, 6:41:47 AM7/30/12
to
On Sun, 29 Jul 2012 12:23:56 -0700, bob smith wrote:

> Would I be a jerk if I required all my game users to support non-power
> of two textures?

If you're going to be requiring a reasonably modern card for other
reasons, requiring non-2^n textures isn't going to affect the set of
supported platforms.

> How do you tell easily if this feature is supported?

if (strstr(glGetString(GL_EXTENSIONS),
"GL_ARB_texture_non_power_of_two"))
...

bob smith

unread,
Jul 30, 2012, 3:57:28 PM7/30/12
to
For some reason, it doesn't like this:

glGetString(GL_EXTENSIONS);

It returns 0.

BGB

unread,
Jul 30, 2012, 10:19:03 PM7/30/12
to
On 7/30/2012 5:41 AM, Nobody wrote:
> On Sun, 29 Jul 2012 12:23:56 -0700, bob smith wrote:
>
>> Would I be a jerk if I required all my game users to support non-power
>> of two textures?
>
> If you're going to be requiring a reasonably modern card for other
> reasons, requiring non-2^n textures isn't going to affect the set of
> supported platforms.
>

possibly, but it may still be a good idea to not require it.

it isn't too hard to have fallback logic for this case:
odd texture size?
have NPOT support?
use NPOT;
else
resample;
use resampled texture.

I generally prefer power-of-2 textures, unless there is good reason to
do otherwise.


>> How do you tell easily if this feature is supported?
>
> if (strstr(glGetString(GL_EXTENSIONS),
> "GL_ARB_texture_non_power_of_two"))
> ...
>

yep.

Nobody

unread,
Jul 31, 2012, 9:43:16 AM7/31/12
to
On Mon, 30 Jul 2012 12:57:28 -0700, bob smith wrote:

>> if (strstr(glGetString(GL_EXTENSIONS),
>> "GL_ARB_texture_non_power_of_two"))
>> ...
>
> For some reason, it doesn't like this:
>
> glGetString(GL_EXTENSIONS);
>
> It returns 0.

Have you created and bound a context at the point that you call it?

Also, in 3.x and later "core profile", glGetString(GL_EXTENSIONS) is no
longer valid (it will fail with GL_INVALID_ENUM). Instead, you need to
use glGetStringi(), e.g.:

GLint count;
GLuint i;
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
for (i = 0; i < count; i++)
if (strcmp(glGetStringi(GL_EXTENSIONS, i),
"GL_ARB_texture_non_power_of_two") == 0)
...

bob smith

unread,
Jul 31, 2012, 10:02:30 AM7/31/12
to
Yes, glGetString(GL_EXTENSIONS) did fail with GL_INVALID_ENUM.

Here's a list of the extensions on my Macbook Pro:

GL_ARB_instanced_arrays...
GL_ARB_occlusion_query2...
GL_ARB_shader_bit_encoding...
GL_ARB_timer_query...
GL_EXT_texture_compression_s3tc...
GL_EXT_texture_filter_anisotropic...
GL_EXT_texture_sRGB_decode...
GL_APPLE_client_storage...
GL_APPLE_container_object_shareable...
GL_APPLE_object_purgeable...
GL_APPLE_rgb_422...
GL_APPLE_row_bytes...
GL_APPLE_texture_range...

I guess my textures have to be power of two?

Seems weird cause I just bought this thing.

fungus

unread,
Jul 31, 2012, 1:37:06 PM7/31/12
to
On Monday, July 30, 2012 9:57:28 PM UTC+2, bob smith wrote:
> For some reason, it doesn't like this:
>
> glGetString(GL_EXTENSIONS);
>
> It returns 0.

Do you have an active OpenGL context?

fungus

unread,
Jul 31, 2012, 1:42:43 PM7/31/12
to
On Tuesday, July 31, 2012 4:02:30 PM UTC+2, bob smith wrote:
>
> I guess my textures have to be power of two?
>
> Seems weird cause I just bought this thing.

Not at all. OpenGL development is moving
towards OpenGL ES as the standard (becuase
the main OpenGL platform in the future will
be mobile devices - iPhone and Android).

OpenGL ES doesn't support non-power-of-two
textures.

bob smith

unread,
Aug 1, 2012, 11:32:20 AM8/1/12
to
Hmmm… I know I have used non-power-of-two textures in the Android emulator.

Nobody

unread,
Aug 1, 2012, 12:52:35 PM8/1/12
to
On Tue, 31 Jul 2012 07:02:30 -0700, bob smith wrote:

> Yes, glGetString(GL_EXTENSIONS) did fail with GL_INVALID_ENUM.
>
> Here's a list of the extensions on my Macbook Pro:

[snip]

> I guess my textures have to be power of two?

Have you tried?

It's possible (and quite likely) that it's just not listed as an
extension. The OpenGL 2.0 specification says:

I.3 Non-Power-Of-Two Textures

The restriction of textures to power-of-two dimensions has been relaxed
for all texture targets, so that non-power-of-two textures may be
specified without generating errors. Non-power-of-two textures was
promoted from the ARB texture non power of two extension.

So in theory, anything reporting an API version of 2.0 or greater should
support non-2^n textures regardless of any extension.

In theory, you should check whether the functionality is available via the
core OpenGL API (via glGetIntegerv() with GL_MAJOR_VERSION and
GL_MINOR_VERSION), and check whether it's available as an extension as a
fallback. For extensions which add new functions, the function will have a
vendor or ARB suffix if it's an extension, but not if it's part of the
core API.

Most of the implementations I've encountered retain extensions even after
the extension has been incorporated into the core API[1], in order to
maintain compatibility with legacy code. E.g. my (fairly recent) ATI card
reports an API version of 4.2 yet lists 281 extensions, the majority of
which have long since been promoted to the API.

[1] With modern cards, this can result in glGetString(GL_EXTENSIONS) being
long enough to cause problems with older programs (either a buffer overrun
or truncating the string and missing some extensions), which probably
explains the introduction of glGetStringi().

Apparently, Apple's implementation doesn't do this (all of your extensions
are either GL_APPLE_* or are fairly new features). If you're getting
GL_INVALID_ENUM for glGetString(GL_EXTENSIONS), you appear to be getting a
3.x "core profile" context, so backwards compatibility isn't applicable
(lack of support for extensions will probably be less of an issue than the
lack of support for most of the 1.x API).

However: the glTexImage2D manual page for both 3.3 and 4.2 still says:

GL_INVALID_VALUE is generated if non-power-of-two textures are not
supported and the width or height cannot be represented as 2^k+2(border)
for some integer value of k.

In my experience, the manual pages can contain outdated information,
sometimes for long periods. It's likely that the 3.x and 4.x manual pages
were based upon the 2.x manual pages, with new details added and old
details not necessarily removed.

bob smith

unread,
Aug 2, 2012, 7:17:25 PM8/2/12
to
I just tried it with a 1280x800 texture, and it seems to have worked.

Thanks.

fungus

unread,
Aug 4, 2012, 6:51:45 AM8/4/12
to
On Friday, August 3, 2012 1:17:25 AM UTC+2, bob smith wrote:
>
> I just tried it with a 1280x800 texture, and it seems to have worked.
>

So...it works on your particular brand/version
of hardware, even if the extensions list says
it doesn't.

Does that seem to you like a good thing to
rely on when you publish your program? What
does your program do if it fails?

Temia Eszteri

unread,
Aug 4, 2012, 2:33:17 PM8/4/12
to
On Sat, 4 Aug 2012 03:51:45 -0700 (PDT), fungus <to...@artlum.com>
wrote:
In this case, I think the suggestion Nobody wrote out would already
allow a check to make sure - failing an extension return, check the
OpenGL version and variant, and should it be appropriate, it's worth a
shot.

Though really, the unwieldiness of putting together different texture
sizes for theoretical situations - not confirmed situations like if
you knew you were porting to an embedded environment - ultimately
means you either pack a PO2 texture or an NPO2 texture.

~Temia
--
Invective! Verb your expletive nouns!

fungus

unread,
Aug 5, 2012, 11:29:10 AM8/5/12
to
On Saturday, August 4, 2012 8:33:17 PM UTC+2, Temia Eszteri wrote:
>
> In this case, I think the suggestion Nobody wrote out would already
> allow a check to make sure - failing an extension return, check the
> OpenGL version and variant, and should it be appropriate, it's worth a
>

I think the best/simplest check is to try
and create a non-power-of-2 texture and
see if it fails. This is similar to using
a proxy texture in OpenGL to check the
hardware capabilities.

OTOH you have to decide what to do when it
fails. Will you just abort? Will you have
a load of angry customers?

I say it's better to regard non-PO2 as
a luxury. Write your program as if it's
not available. Use it to improve image
quality and/or memory usage when it is.

Resizing images as you load them from
disk is no big deal. It should add no
more than a couple of hours development
time. Not doing it seems like incredible
laziness to me.

fungus

unread,
Aug 5, 2012, 11:31:15 AM8/5/12
to
On Friday, August 3, 2012 1:17:25 AM UTC+2, bob smith wrote:
>
> I just tried it with a 1280x800 texture, and it seems to have worked.
>

That seems suspiciously screen-resolution sized.

Do you use a 2048x1024 texture if it fails?

BGB

unread,
Aug 5, 2012, 12:15:31 PM8/5/12
to
pretty much, and also if the resampling code uses bicubic interpolation
or similar, the visible impact of resampling may be, in-fact, fairly
small (granted, it is a little more expensive, both in time and
implementation effort, than using bilinear interpolation).


Nobody

unread,
Aug 5, 2012, 11:39:31 PM8/5/12
to
On Sun, 05 Aug 2012 08:29:10 -0700, fungus wrote:

> I say it's better to regard non-PO2 as
> a luxury. Write your program as if it's
> not available. Use it to improve image
> quality and/or memory usage when it is.
>
> Resizing images as you load them from
> disk is no big deal. It should add no
> more than a couple of hours development
> time. Not doing it seems like incredible
> laziness to me.

Moving up to the next power of two can require almost four times as much
memory.

Resampling introduces artifacts; blurring if you filter (which isn't an
option for integer textures), aliasing if you don't. Padding won't work if
you need textures to wrap.

If you're going to be requiring a lot of OpenGL 3.x features anyhow,
supporting an implementation which doesn't even provide 2.0 is pointless.
Dealing with the theoretical (but almost certainly non-existent) case of
an implementation which provides 1.x plus extensions for every required
3.x feature *except* non-2^n textures would be sheer pedantry.

Nobody

unread,
Aug 6, 2012, 12:24:59 AM8/6/12
to
On Sat, 04 Aug 2012 03:51:45 -0700, fungus wrote:

> On Friday, August 3, 2012 1:17:25 AM UTC+2, bob smith wrote:
>>
>> I just tried it with a 1280x800 texture, and it seems to have worked.
>>
>
> So...it works on your particular brand/version
> of hardware, even if the extensions list says
> it doesn't.

The extension list is irrelevant; given that he's getting a "core profile"
context, the OpenGL version will be at least 3.0, and non-2^n textures are
part of the 2.0 API.

fungus

unread,
Aug 6, 2012, 1:27:37 AM8/6/12
to
On Monday, August 6, 2012 5:39:31 AM UTC+2, Nobody wrote:
>
> Moving up to the next power of two can require almost four times as much
>
> memory.
>

That's only for really bad image sizes and
where you can't make atlases.

> Resampling introduces artifacts; blurring if you
> filter aliasing if you don't.
>

This only matters if your textures are used
in 2D with no zooming.

> If you're going to be requiring a lot of
> OpenGL 3.x features anyhow,
>
> supporting an implementation which doesn't even provide 2.0 is pointless.
>
> Dealing with the theoretical (but almost certainly non-existent) case of
>
> an implementation which provides 1.x plus extensions for every required
>
> 3.x feature *except* non-2^n textures would be sheer pedantry.

If you're *sure* it will be supported then
whatever.

But ... thread "White texture on Galaxy Tab 10.1"
for what happens to people who make assumptions.

Plus ... there can be performance penalties
for using it.
0 new messages