Texture Size confirmation

BlitzMax Forums/BlitzMax Programming/Texture Size confirmation

Grey Alien(Posted 2006) [#1]
So sorry to bang on about this but I can't seem to find a proper answer.

I know that textures get rounded up to power of 2 e.g. 200 = 256, but does BMax keep the texture rectangular (e.g. 512x128) or make it square based on the bsed on the biggest edge (512x512)? (to make it compatible with all 3D cards, or so I've heard) Thanks.

Basically I have say a game HUD which is long and thin and I'm wondering if BMax makes it into a giant square with most of it blank, or if it becomes are power of 2 rectangle?

This is important for programming bitmap fonts because if you put them in a giant strip and keep it in memory it could be huge, whereas several ros of text in a square image would be more efficient.

Thanks.


tonyg(Posted 2006) [#2]
It rounds them to it's next pow2 size.
So, 512*128 = 512*128.Check d3d7max2d.bmx pow2size function within TD3D7ImageFrame create function.
For GL check glmax2d.bmx private function pow2size.
<edit : Take out a facetious remark about having the source code>.


bradford6(Posted 2006) [#3]
From what I understand, the power of 2 rule is still in effect on even the most recent cards

64 x 128
512 x 256
128 x 1024

the Square rule is mostly defunct I believe. It would really depend on the target audience. If you are going low tech>>older hardware then use the square rule.


Grey Alien(Posted 2006) [#4]
OK I just was reading a thread the other day going on about BMax making the textures square, it may have been Dreamora, so I wondered it if was true.

As for the source code, sure I have the module source code but I don't necessarily have the cognitive abilities to understand what the hell it's doing or where to look, hence why I ask things sometimes.


tonyg(Posted 2006) [#5]
I don't necessarily have the cognitive abilities to understand what the hell it's doing or where to look,

Which is a shame 'cos understanding the source is soooo helpful and not as difficult as you'd think.
In this case you know the command to be interested in is DrawImage.
From the Bmax command Index, DrawImage is contained in Max2d.bmx.
Opening Max2D.bmx and searching for DrawImage shows it calls TImage.Frame method. Using Windows search or a bit of guess work leads us to image.bmx.
Load Image.bmx and you notice the TImage.frame method points to _max2dDriver.CreateFrameFromPixmap.
_max2dDriver will be either D3D7Max2D or GLMax2D. Either way you can search on CreateFrameFromPixmap and get just a few results.
In DX case we open D3D7Max2D.bmx, search for CreateFrameFromPixmap and notice it points to
TD3D7ImageFrame.Create which contains function pow2size.
It might seem convoluted but is well worth the effort.
HotDocs can help to some degree.
Hope it helps


ImaginaryHuman(Posted 2006) [#6]
AFAIK OpenGL cannot do non-rectangular textures without extensions and the v1.2 that comes with BlitzMax does not support anything other than square textures. So yes under GL the texture is going to have a whole bunch of empty space with a thin strip at one edge. You can't get textures like 512x128 without the rectangular texture extension. That feature was introduced somewhere in GL 1.3-1.5

I don't know that dx supports rectangular textures - why would BRL make an inconsistency?


tonyg(Posted 2006) [#7]
I don't understand then.
glmax2d.bmx calls pow2size for texture height and width converting each to pow2 but not necessarily so they're square. It uses the results in glTexImage2D without changing them.


ImaginaryHuman(Posted 2006) [#8]
Official BRL answer?

All I know is the OpenGL specification does not support non-rectangular textures until later versions and does not come supported as standard in the default OpenGL in BlitzMax. I don't know how BRL are getting around it, maybe they know something about allocation of textures by the system that we don't know.


Gabriel(Posted 2006) [#9]
All I know is the OpenGL specification does not support non-rectangular textures until later versions and does not come supported as standard in the default OpenGL in BlitzMax. I don't know how BRL are getting around it, maybe they know something about allocation of textures by the system that we don't know.


I think you're confused. When the OpenGL specification refers to rectangular textures, it ( confusingly ) means non-power-of-two textures. It is not referring to power-of-two textures which just happen to be non-square. I know that's not a very clever way to name things, but that's what it says.

The OpenGL site says ( and this is referring to 1.1 )

OpenGL texturing is limited to images with power-of-two dimensions and an optional 1-texel border.


It says nothing about equal dimensions. Just power of two.


ImaginaryHuman(Posted 2006) [#10]
Hmm, now that is interesting to know!

Quote from the red book: "The width and height parameters give the dimensions of the texture image; border indicates the width of the border, which is usually zero. (See "Using a Texture's Borders." ) Both width and height must have the form 2m+2b, where m is an integer (which can have a different value for width than for height) and b is the value of border. The maximum size of a texture map depends on the implementation of OpenGL, but it must be at least 64 × 64 (or 66 × 66 with borders). If width or height is set to zero, texture mapping is effectively disabled. "

So yes you're right, the texture can be DIFFERENT width and height, but both width and height must, individually, be a power-of-2 size, e.g. 64x128, 256x2048, and can also be the same width and height e.g. 256x256 etc.

:-)


Regular K(Posted 2006) [#11]
A bit off topic, sorry but


The maximum size of a texture map depends on the implementation of OpenGL, but it must be at least 64 × 64 (or 66 × 66 with borders)



Does that mean the smallest size is 64x64 (until it gets resized of course)? So all of these 32x32 sprites would get resized to 64x64?


Gabriel(Posted 2006) [#12]
So yes you're right, the texture can be DIFFERENT width and height, but both width and height must, individually, be a power-of-2 size, e.g. 64x128, 256x2048, and can also be the same width and height e.g. 256x256 etc.

Thanks for the confirmation. I couldn't lay my hands on the red book to confirm it, but the OpenGL site seemed to be on point.

Does that mean the smallest size is 64x64 (until it gets resized of course)? So all of these 32x32 sprites would get resized to 64x64?

Yeah, that's a surprise to me too, but it appears that way.


bradford6(Posted 2006) [#13]
all my sprites are 53 X 42 and I ain't changin 'em. Dagnabbit!


Robert Cummings(Posted 2006) [#14]
Blitzmax makes everything rounded UP to the nearest power of 2, and SQUARE.

1029x768 becomes 2048x2048 I think.

And, thats not a typo.


bradford6(Posted 2006) [#15]
Lowcs, do you have any references for that assertion?

OpenGL 1.1 and GLEW both support non-square textures.

DX7 supports non-square textures.

It would be nice to know What BlitzMax does so we are not fighting the system on this.


Gabriel(Posted 2006) [#16]
Blitzmax makes everything rounded UP to the nearest power of 2, and SQUARE.

Why would it do that? Blitz3d certainly doesn't.

all my sprites are 53 X 42 and I ain't changin 'em. Dagnabbit!

Fortunately, you don't really need to. I'm not sure whether BMax adjusts the UV coordinates or just scales your sprites, but it takes things into account either way. It would be much better if it adjusted the UV coordinates though, because resizing makes them unecessarily blurry. You're effectively scaling up and then scaling back down again when you draw. Which would be silly.


Steve Elliott(Posted 2006) [#17]

The maximum size of a texture map depends on the implementation of OpenGL, but it must be at least 64 × 64



I've heard this mentioned before so I guess it must be true. But it's probably best to leave my (32 X 32) smaller sprites as they are so if the user switches to DirectX (BlitzMax will scale-up easily) things will run a bit more efficiently - and save a bit of hard disk space.


Grey Alien(Posted 2006) [#18]
see what I mean. No one can agree so I'd like BRL to chirp up and finalise this issue.

Certainly it makes sense that rectangular not square should be used as square would be really crap.

As for smaller than 64x64. Yeah I'll leave mine smaller so they are faster in DirextX (to make up for the DirectX lag issue). This could be very important for particles!

You're effectively scaling up and then scaling back down again when you draw. Which would be silly.

I'm confused by this. Surely it just adds blank space round the existing sprite. Why would it scale it up then down to draw...?


JoshK(Posted 2006) [#19]
Cards that support non-power-of-two sizes still resample the image to a power-of-two, so you might as well stick to 2^ to begin with.


Yan(Posted 2006) [#20]
I'm confused by this.
Gabriel was saying *if* Bmax scaled the pixmap up to fit the texture (which it doesn't BTW), it would be silly...And I concur. ;o)


Here's my understanding (from actually reading the GL code and *not* just making assumptions ;op) of what happens when an image is created...

1) The pixmap is loaded

2) Bmax checks that a texture with the dimensions of the pixmap, scaled up to the nearest POW2, can be created. The texture's *not* made square, but I think some drivers/cards scale the texture square, internally.

3) If the creation will fail, the width and height of the texture are continually halved until a texture can be created or errors out

4) If the proposed texture size is smaller than the pixmap, the pixmap is scaled down to fit. If the pixmap is shorter or thinner than the texture, the appropriate edge(s) of the pixmap are smeared.

5) The texture is created, the pixmap is slapped into the top left corner and the image's UVs are set.

Job done!


Grey Alien(Posted 2006) [#21]
Cards that support non-power-of-two sizes still resample the image to a power-of-two, so you might as well stick to 2^ to begin with.
So resample infers there could be some loss or approximation, is that correct? I would have thought if the size was not ^2 that it would just add space around it, easy. Also are you saying that some cards can only handle SQUARE ^2 so will resize to that so you might as well always use square ones?

Yan: Thanks, OK that *seems* to confirm it.


Yan(Posted 2006) [#22]
Check out 'AdjustTexSize()' and 'TGLImageFrame.CreateFromPixmap()' in 'GLMax2D.bmx'.

The code's easy to follow and it's even commented.


ImaginaryHuman(Posted 2006) [#23]
Regardless of how small your images are, a sprite 32x32 HAS to be put onto a 64x64 texture, that is the absolute smallest that OpenGL will support, so it will waste some space. The image won't be scaled up to 64x64, it will just have some blank space that is unused.

One thing that does concern me is the commend that some graphics cards scale the texture to square textures internally, so if I asked for 2048x64 it'd actually make a 2048x2048 texture. If ANY cards do this kind scaling, doesn't that mean that the only `safe` texture sizing is to deliberately use square textures only?

If you are making own OpenGL code you have full control over what size textures you want (albeit that x and y have to be powers of 2 and at least 64x64), where on the texture you put the graphic, how much space you waste or use, and which texture coords are used to read the texture when drawing a quad.


Gabriel(Posted 2006) [#24]
Gabriel was saying *if* Bmax scaled the pixmap up to fit the texture (which it doesn't BTW), it would be silly...And I concur. ;o)

Yes, that's exactly what I meant, thanks, and sorry to Grey if I was confusing.


TartanTangerine (was Indiepath)(Posted 2006) [#25]
Regardless of how small your images are, a sprite 32x32 HAS to be put onto a 64x64 texture, that is the absolute smallest that OpenGL will support, so it will waste some space. The image won't be scaled up to 64x64, it will just have some blank space that is unused.

Assuming your client is using OGL, in DX a 32x32 sprite will outperform a 64x64 on a shitty (sub $50) GFX card.


Grey Alien(Posted 2006) [#26]
Indiepath: yeah that's why I said I'd leave mine smaller for DX performance (which is the norm on most PCs).

Gabriel: ah OK, sure.


Yan(Posted 2006) [#27]
I'm still not convinced about the minimum texture size in GL, so I'll move stuff from my previous post here..

As far as I can tell, Bmax makes no attempt at limiting the minimum texture size and GL seems to allow textures under 64x64...

...GL appears to create a 16x32 texture and even returns those figures as the texture size (unless I've misunderstood what glGetTexLevelParameteriv() does?).

??


Grey Alien(Posted 2006) [#28]
This site ought to be called BlitzMisinformation.com ;-)


Steve Elliott(Posted 2006) [#29]
Grey why don't you email BRL and post their answer here?


Grey Alien(Posted 2006) [#30]
Call me a pessamist but I'm not sure I'll get a response...


Steve Elliott(Posted 2006) [#31]
I got a response within 48hrs the only time I emailed them.


MGE(Posted 2008) [#32]
I can't believe the developers of Blitzmax never answered anyone on this important topic.

I'm still not sure if BMax makes the image the next "square" size up or the next "power of 2" size up.


tonyg(Posted 2008) [#33]
Next POW2 size.
The only argument is
a) whether OGL uses 64*64 as the smallest texture size although everybody agrees this doesnt affect the size of the image shown.
b) whether some video cards force square textures. For DX you can use this to check the device caps where you'd need to check D3DPTEXTURECAPS_SQUAREONLY
P.S. BRL commenting is the exception not the rule. Terrible I know but the way it is.


Grey Alien(Posted 2008) [#34]
Next POW2 size.
Please remind me again how we know this? thx. I've based some commands in my framework that calc the VRAM used per image on this fact anyway.


tonyg(Posted 2008) [#35]
From the source code when the surface is created.


Grey Alien(Posted 2008) [#36]
Ah OK fine.


Yan(Posted 2008) [#37]
Please remind me again how we know this?
Because *I* said so, of course. ;op


ImaginaryHuman(Posted 2008) [#38]
As far as OpenGL goes, the minimum texture has to be no smaller than 64x64, although you can make/use images smaller than that - it'll be stored within a 64x64 texture.

Then texures have to be a power of 2 in each direction separately. You are allowed square or rectangular textures so long as each side is a power of 2 - and doesn't have to be the same power of 2. e.g. 64x128, 1024x64, etc are allowed.

Whether non-square textures are supported by the driver implementation of GL is another matter. They're supposed to support it but who knows.

You can ask GL with glGetIntegerv(params) what the maximum texture size is, but not whether it is squares only, because the GL spec states you're supposed to be able to use non-square.


Yan(Posted 2008) [#39]
ImaginaryHuman, can you please explain what's happening in the code I've posted above?


ImaginaryHuman(Posted 2008) [#40]
Not sure. Try reading back errors from OpenGL at every step and see if it gives you an error code for any commands. Otherwise maybe the driver on your computer allows sizes below 64x64, or just handles it as 64x64 internally or something, who knows. I don't know if I'd rely on it too much, though, to work on all machines. I'd probably force the use of a 64x64 just to be safe.


Yan(Posted 2008) [#41]
Thanks for that, I just wasn't sure if my decidedly dodgy knowledge of OGL was the problem. :o)

Hmmm, still a bit of a grey area then?

As the code above shows, BMax doesn't impose any limitations on the minimum size of a texture when it creates an image. I'd of thought that any problems would have shown up by now, considering the length of time BMax has been out in the wild.

I'll just have to remain unconvinced either way and continue to err of the side of caution. :o)