Power of two sprites...?

Started by
12 comments, last by Adam_42 12 years, 11 months ago
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!
Advertisement
here is what i used to load my texture with (non power of two / does not matter)


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 );


did that help ?

Never say Never, Because Never comes too soon. - ryan20fun

Disclaimer: Each post of mine is intended as an attempt of helping and/or bringing some meaningfull insight to the topic at hand. Due to my nature, my good intentions will not always be plainly visible. I apologise in advance and assure you I mean no harm and do not intend to insult anyone.


here is what i used to load my texture with (non power of two / does not matter)


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 );


did that help ?


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
I'm now using the following settings:


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



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

I'm now using the following settings:


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



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


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


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;


does that make sense ?

Never say Never, Because Never comes too soon. - ryan20fun

Disclaimer: Each post of mine is intended as an attempt of helping and/or bringing some meaningfull insight to the topic at hand. Due to my nature, my good intentions will not always be plainly visible. I apologise in advance and assure you I mean no harm and do not intend to insult anyone.

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.
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;


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

Width = ImageInfo.Width;
Height = ImageInfo.Height;
TGUI, a C++ GUI for SFML
texus.me

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;


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

Width = ImageInfo.Width;
Height = ImageInfo.Height;





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

what about using dds

Never say Never, Because Never comes too soon. - ryan20fun

Disclaimer: Each post of mine is intended as an attempt of helping and/or bringing some meaningfull insight to the topic at hand. Due to my nature, my good intentions will not always be plainly visible. I apologise in advance and assure you I mean no harm and do not intend to insult anyone.


what about using dds


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.

This topic is closed to new replies.

Advertisement