Sign in to follow this  
Siyfion

Power of two sprites...?

Recommended Posts

I've got a 2D game that I'm in the process of developing at the moment and I'm trying to figure out whether I need to use power of two textures or not, so I've created a little application that looks at the card capabilities and let's me know whether the card supports non-power of two textures unconditionally, conditionally, or not at all.

I've tried this application out on all of my target platforms and they all support non-power of two textures, at least conditionally. So I've now tried to test it, so I've got 4 textures, 2 power of two, 2 non-power of two. And I'm using an ID3DXSprite to draw them (maybe these days I shouldn't be? - Been a while since I did extensive 2D engine work!). They all draw fine, however the non-power of two textures seem to be scaled somehow, not their "original" size. Yet I have no idea why!

If anyone's got any ideas, I'm all-ears!

Share this post


Link to post
Share on other sites
here is what i used to load my texture with (non power of two / does not matter)

[code]
D3DXIMAGE_INFO d3dxImageInfo;

D3DXCreateTextureFromFileEx( D3D9Device,
L"..\\donut.bmp",
320, // I had to set width manually. D3DPOOL_DEFAULT works for textures but causes problems for D3DXSPRITE.
384, // I had to set height manually. D3DPOOL_DEFAULT works for textures but causes problems for D3DXSPRITE.
1, // Don't create mip-maps when you plan on using D3DXSPRITE. It throws off the pixel math for sprite animation.
D3DPOOL_DEFAULT,
D3DFMT_UNKNOWN,
D3DPOOL_DEFAULT,
D3DX_DEFAULT,
D3DX_DEFAULT,
D3DCOLOR_COLORVALUE(0.0f, 0.0f, 0.0f, 1.0f),
&d3dxImageInfo,
NULL,
&texture );

// Create our sprite...
D3DXCreateSprite( D3D9Device, &sprite );
[/code]

did that help ?

Share this post


Link to post
Share on other sites
[quote name='ryan20fun' timestamp='1306316532' post='4815513']
here is what i used to load my texture with (non power of two / does not matter)

[code]
D3DXIMAGE_INFO d3dxImageInfo;

D3DXCreateTextureFromFileEx( D3D9Device,
L"..\\donut.bmp",
320, // I had to set width manually. D3DPOOL_DEFAULT works for textures but causes problems for D3DXSPRITE.
384, // I had to set height manually. D3DPOOL_DEFAULT works for textures but causes problems for D3DXSPRITE.
1, // Don't create mip-maps when you plan on using D3DXSPRITE. It throws off the pixel math for sprite animation.
D3DPOOL_DEFAULT,
D3DFMT_UNKNOWN,
D3DPOOL_DEFAULT,
D3DX_DEFAULT,
D3DX_DEFAULT,
D3DCOLOR_COLORVALUE(0.0f, 0.0f, 0.0f, 1.0f),
&d3dxImageInfo,
NULL,
&texture );

// Create our sprite...
D3DXCreateSprite( D3D9Device, &sprite );
[/code]

did that help ?
[/quote]

well, it helped me at least. (not with what I'm doing right now though) but I didn't know directx had a D3DXCreateSprite. I can go to bed now, because I learned something new. Thanks

Share this post


Link to post
Share on other sites
I'm now using the following settings:

[code]
D3DXCreateTextureFromFileEx(d3ddev,
L"ExampleNon.png",
220,
220,
1,
0,
D3DFMT_FROM_FILE,
D3DPOOL_DEFAULT,
D3DX_DEFAULT,
D3DX_DEFAULT,
0,
NULL,
NULL,
&exampleNon);
[/code]


Which seems to now display the texture at the correct size, but I have had to specify the texture sizes manually to get it to work. This seems like a bit of headache to say the least! As every time I update the graphics I may need to change the CreateTexture params, and thus re-compile the game. :S

Share this post


Link to post
Share on other sites
[quote name='Siyfion' timestamp='1306318353' post='4815520']
I'm now using the following settings:

[code]
D3DXCreateTextureFromFileEx(d3ddev,
L"ExampleNon.png",
220,
220,
1,
0,
D3DFMT_FROM_FILE,
D3DPOOL_DEFAULT,
D3DX_DEFAULT,
D3DX_DEFAULT,
0,
NULL,
NULL,
&exampleNon);
[/code]


Which seems to now display the texture at the correct size, but I have had to specify the texture sizes manually to get it to work. This seems like a bit of headache to say the least! As every time I update the graphics I may need to change the CreateTexture params, and thus re-compile the game. :S
[/quote]

no you do not need to do that, use this to parse a text file that contains your image info

[code]
int numberofframes = 1;
float width = 1;
float height = 1;
float fsx = 1;
float fsy = 1;
float alpha = 0;
wstring ws;

char *buf = new char[20];
memset(buf, 0, 20);

fstream fs(Path);

if(!fs)
{
// failed to open file / create stream
}

fs.getline(buf, 20, '\t'); // read till a TAB space is found
width = (float)atof(buf); // width

fs.getline(buf, 20, '\n');// read till a endofline is found
height = (float)atof(buf); // height

fs.getline(buf, 20, '\t');// read till a TAB space is found
fsx = (float)atof(buf); // frame size x

fs.getline(buf, 20, '\n');// read till a endofline is found
fsy = (float)atof(buf); // frame size y

fs.getline(buf, 20, '\n');// read till a endofline is found
numberofframes = (int)atof(buf); // number of frames

fs.getline(buf, 20, '\n');// read till a endofline is found
alpha = (float)atof(buf); // alpha

fs.getline(buf, 20, '\n');
string s;
s.append(mediafolder);
s.append(buf);
ws.append(s.begin(), s.end()); // path to sprite sheet

delete []buf;
[/code]

does that make sense ?

Share this post


Link to post
Share on other sites
Yeah I get that, however I've got 450MB~ of textures to load into 128MBs of VRAM. Obviously I need to cut it down so I'm looking at ways in which I can do it, SpriteSheets, non-power two textures, DDD / DXT Compression, etc.

Spritesheets didn't seem to help much, as I have a lot of animations that can't really be made into a spritesheet; only 1 frame will ever be drawn on screen at one time, so with a spritesheet I'm loading all the other frames into VRAM and wasting space they are using, making the card swap these large spritesheets in/out of VRAM every frame.

Share this post


Link to post
Share on other sites
[size="2"]To get the width and height of the image you don't have to read it from the file by yourself.
In D3D9 you can just use D3DXGetImageInfoFromFile;

[code]
D3DXIMAGE_INFO ImageInfo;
D3DXGetImageInfoFromFile(L"Example.png", &ImageInfo);

Width = ImageInfo.Width;
Height = ImageInfo.Height;
[/code][/size]

Share this post


Link to post
Share on other sites
[quote name='Texus' timestamp='1306326577' post='4815556']
[size="2"]To get the width and height of the image you don't have to read it from the file by yourself.
In D3D9 you can just use D3DXGetImageInfoFromFile;

[code]
D3DXIMAGE_INFO ImageInfo;
D3DXGetImageInfoFromFile(L"Example.png", &ImageInfo);

Width = ImageInfo.Width;
Height = ImageInfo.Height;
[/code][/size]
[/quote]



Fantastic, now that's what I'm talking about! :D

Share this post


Link to post
Share on other sites
[quote name='ryan20fun' timestamp='1306327615' post='4815565']
what about using dds
[/quote]

Well it's kinda one OR the other.. as DXT compression isn't supported for non-power of two textures. So I don't know which will give the biggest benefit in terms of memory usage, but non-power of two will certainly retain quality better.

Share this post


Link to post
Share on other sites
the DX Docs say that dds can be easyaly converted to other formates or depths etc,
what you could try is to make it a power of 2 but only use certain parts of it, that way compression is used.

Share this post


Link to post
Share on other sites
[quote name='ryan20fun' timestamp='1306328208' post='4815574']
the DX Docs say that dds can be easyaly converted to other formates or depths etc,
what you could try is to make it a power of 2 but only use certain parts of it, that way compression is used.
[/quote]

As I said earlier, spritesheets (or multiple textures in one file) don't seem to provide us with much benefit (having tested various methods, packing techniques, etc.).

Share this post


Link to post
Share on other sites
DDS is supported for non-power-of-2; the constraint is that the dimensions must be multiples of 4 (as it compresses a 4x4 block of the source), which also imples that they must be at least 4.

Share this post


Link to post
Share on other sites
If you look at the [url="http://msdn.microsoft.com/en-us/library/bb172802%28v=vs.85%29.aspx"]documentation for D3DXCreateTextureFromFileEx[/url] you'll find:

[quote]Width in pixels. If this value is zero or D3DX_DEFAULT, the dimensions are taken from the file and rounded up to a power of two. If the device supports non-power of 2 textures and D3DX_DEFAULT_NONPOW2 is specified, the size will not be rounded.[/quote]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this