Archived

This topic is now archived and is closed to further replies.

BriTeg

texture sizes other than powers of 2???

Recommended Posts

In Nehe''s lesson #6, it says "...there are a few VERY important things you need to know about the images you plan to use as textures. The image height and width MUST be a power of 2. The width and height must be at least 64 pixels, and for compatability reasons, shouldn''t be more than 256 pixels. If the image you want to use is not 64, 128 or 256 pixels on the width or height, resize it in an art program. There are ways around this limitation, but for now we''ll just stick to standard texture sizes." What are the "ways around this limitation"? I would like to support texture sizes other than powers of 2, and also wider than 256. Does anyone know how this would be done, or know of any links that explain what to do? Thanks, Brian

Share this post


Link to post
Share on other sites
well if the texture is bigger then 256 you can make 2 or more out of it and set them acrose quads (need to draw more polys this way). but theres no way around the <64 pixel one

hope that helps

-Ian

Share this post


Link to post
Share on other sites
I am writing a tool that let''s end users supply bitmaps to be used as textures. Suppose the bitmap they want to use is 297x451. Is it possible to make a texture of these dimensions? Just considering the width, two textures (256 and 64) = 320 which is too much, and apparently I can''t go smaller than 64 for the second texture. But I don''t even want a second texture anyway! Is there no way to have textures with odd widths like this? I suppose I could resize the bitmaps in code, but I risk loosing image quality if I have to shrink everything down to 256. Any ideas?

Share this post


Link to post
Share on other sites
quote:
Original post by BriTeg
... and apparently I can''t go smaller than 64 for the second texture...


Actually, the minimum texture size is 1x1. An implementation must support texture sizes up to at least 64x64, maybe you misread something.

---
Visit Da Shovvkejs.

Share this post


Link to post
Share on other sites
There is no lower limit on texture size. The statement that it must be greater then 64 is incorrect.
To get a strange sized image into a texture, you could scale it so it is a power of 2 (gluScaleImage will do it), or you could look into the NV_texture_rectangle extension.
Also, almost all modern cards support textures larger than 256. For example, even a TNT supports up to 1024x1024.

http://users.ox.ac.uk/~univ1234

Share this post


Link to post
Share on other sites
Thanks for the replies! They help.

Is there any way to determine at runtime the maximum texture sizes a video card supports?

Share this post


Link to post
Share on other sites
SMALL TEXTURES
That''s right that you can use textures lower than 64. Though if your texture is really small, say 2x2, you may need to call glPixelStore for proper data alignment.


BIG TEXTURES
Of course you can use texture higher than 256, but that depends on the card''s limitations obviously. If you have a 256x256 texture, and if the card does not support textures higher than 128x128, I''m afraid the only solution is to shrink the picture to fit hardware requirements.

I do not recommend to get the maximum available texture size with GL_MAX_TEXTURE_SIZE. This is depreceated and you''d rather use glTexImage2D with GL_PROXY_TEXTURE_2D.


NON POWER-OF-TWO TEXTURES
And finally, YES you can use non-power-of-two textures. This has the very annoying, yet not deadly, disadvantage to forbid texture repetition. The trick is very simple : create a bigger texture (power-of-two sized) and fill partially the texture with the non-power-of-two picture.

For example with your 297x451 bitmap : first call glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL) to allocate memory for the 512x512 texels, and then fill a part of it with your bitmap thanks to glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 297, 451, GL_RGB, GL_UNSIGNED_BYTE, bimap_pixels).
(note: the later function is available since OpenGL1.1, just like glBindTexture).

The problem with repetition is pretty obvious I think.

Remember that you may not fill your texture with gluBuild2DMipmaps because this function will try to resize the texture to its closest power-of-two size (thus losing quality). That also means that you have to perform your own mipmaps if you want them. Also note that mipmapping may show seams. If you already know how to take care of seams with borders, the solution is the same.

Share this post


Link to post
Share on other sites
Right but you would lose quality, more or less significantly depending of the picture type (photo or cartoon) and depending on the filter applied during the resize.

Share this post


Link to post
Share on other sites
You don''t lose quality from expanding the texture... not really. If you looked very closely at it, you might notice there seems to be higher resolution horizontally than vertically or vice versa, but it''s minor.

It also allows mipmaps to work correctly. They won''t work otherwise, not correctly.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
Why dont you use Nehe''s iPicture? It loads bitmaps, and jpegs and other formats i think. There is no size limitation so you can load whatever you want. To get the loading code to work all you realy have to do is cut and paste (dont forget includes - or something, i think). Anyway i find that iPicture usually solves all of my texture problems. Good luck

Share this post


Link to post
Share on other sites
quote:
You don''t lose quality from expanding the texture... not really.

I agree than it may not be noticeable on some (most?) cases, but since there is a loss, if there is another method without loss then I would choose it instead. It''s just a matter of preference though. Either way, it all depends on the application.

quote:
It also allows mipmaps to work correctly. They won''t work otherwise, not correctly.

I''m sorry but I have to disagree with that point. What will not work correctly is the gluBuild2DMipmaps function, but OpenGL''s mipmapping functionality will work correctly.

Share this post


Link to post
Share on other sites
It''s not accurate to say there is a loss, as no data is lost. All that happens is the resolution in one direction is slightly higher than the resolution in another, and even this isn''t always true - if the width:height ratio of the original texture is equal to the width:height ratio of the power-of-two one, then there''s no noticeable difference at all.

If the ratios are not the same, then even the difference resolutions are barely noticeable since the texture will be scaled to its correct size. You have to keep that in mind - if you were to open the bitmap in an image editor, it would look distorted, but it would not look distored in the game because of teh way you scale it.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites
That's true that there is no loss at all in some particular cases (though, be careful of using the right resize filter depending on texture's magnification/minification filter) and so forth the only disadvantage of resizing is the computation time of the resize. Unfortunately this case happens rarely. Fortunately, as you wrote, even the loss is (merely) not noticeable.

[edited by - vincoof on October 24, 2002 5:30:20 AM]

Share this post


Link to post
Share on other sites
If it can''t be tiled, this is because it uses a trick similar as the technique I''ve described above (allocating a bigger texture and filling a subtexture). You can get the full specifications of the NV_texture_rectangle extension here.

Advantages of NV_texture_rectangle over the technique I described :
- Uses less memory (in theory) because there''s no need to allocate a "bigger powere-of-two dimensioned" texture,
- Easier to clamp (and clamp_to_edge and clamp_to_border).

Disadvantages of NV_texture_rectangle :
- no mipmap, even though the technique I descibred can not do "easy" mipmaps,
- no repeat, even though the technique I described may not be able to do it either in most cases
- available on NVIDIA cards _only_ (and also a few other cards)

Share this post


Link to post
Share on other sites
That''s what I do, to deal with odd size textures:
I convert them, with an image editor, into a power of 2. In most of the cases, your program doesn''t have to rely on user selected textures, so, if you have a game, or something, it''s better to just resize/rescale them BEFORE even loading them in your aplication.

Advantages:
It can tile
Can have mipmaps
Higher image quality (since the resizing is made with a special software that usually does it better than your quick hacks)
No extra code

Dissadvantages:
Won''t work if the user selects whatever textures s/he has
Might take a little more disk space

Which is worse? Ignorance or apathy? Who knows?! Who cares?!

Share this post


Link to post
Share on other sites
That seems like a very useful extension. I find it simplest just resizing my textures to powers of two... I do this with the bitmap itself, I don''t have the program do it.

~CGameProgrammer( );

Share this post


Link to post
Share on other sites