Jump to content
  • Advertisement
Sign in to follow this  
utilae

Getting incorrect width and height from texture.

This topic is 4230 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I am using C++ and Direct3D9. I am trying to load a texture, everything works properly, ie displays properly, etc, but this data that I get from the texture is incorect. For example, when I load a bunch of textures and log it, I can see that the texture heights and widths are incorrect. They all seem to be too high by 32 pixels, eg height=128, width=128, when they are actually 96x96. The textures are being loaded from file, and the files are .tga files of the format A8R8G8B8. What is going on? Code below:
//Load texture from file
void CTextureManager::LoadTexture(const string &sFilename)
{	
	//find texture if it already exists
	int nTextureIndex=BinarySearch(m_lstMainTextureList,sFilename);
	if(nTextureIndex!=-1)
	{
		//texture already loaded, so return
		g_Log<<"LoadTexture("<<sFilename<<") ALREADY LOADED"<<endl;
		return;
	}

	//texture is not already loaded, so now a texture can be loaded
	LOADEDTEXTURE newTexture;
	
	//load texture
	HRESULT hr=D3DXCreateTextureFromFileEx(g_pD3DDevice9,sFilename.c_str(),D3DX_DEFAULT,D3DX_DEFAULT,D3DX_DEFAULT,0,D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,D3DX_DEFAULT,D3DX_DEFAULT,0,0,0,&newTexture.m_texture);
	g_Log<<"LoadTexture("<<sFilename<<") Create Texture: "<<DXGetErrorString9(hr)<<endl;

	D3DSURFACE_DESC surfaceDesc;
	hr=newTexture.m_texture->GetLevelDesc(0,&surfaceDesc);
	g_Log<<"LoadTexture("<<sFilename<<") Get Texture Description: "<<DXGetErrorString9(hr)<<endl;

	//store textures filename, height and width
	newTexture.m_sName=sFilename;
	newTexture.m_nHeight=surfaceDesc.Height;
	newTexture.m_nWidth=surfaceDesc.Width;
	newTexture.m_nArea=surfaceDesc.Height*surfaceDesc.Width;

	g_Log<<"Texture - "<<sFilename<<":"<<endl;
	g_Log<<"  newTexture.m_nHeight"<<newTexture.m_nHeight<<endl;
	g_Log<<"  newTexture.m_nWidth"<<newTexture.m_nWidth<<endl;

	//put texture into list and sort list
	m_lstMainTextureList.push_back(newTexture);
	sort(m_lstMainTextureList.begin(),m_lstMainTextureList.end(),SortByNameAscending<LOADEDTEXTURE>());
}



[Edited by - utilae on May 15, 2007 4:04:54 AM]

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by utilae
For example, when I load a bunch of textures and log it, I can see that the texture heights and widths are incorrect. They all seem to be too high by 32 pixels, eg height=64, width=64, when they are actually 32x32.

This may be stupid, but are you sure your files are actually 32x32 and not like 36x36 or something? The first thing that comes to mind is that your textures are being rounded up to the nearest size power of 2 at load time. At least, that is the most common problem when this type of question is asked (which is often!) If they really are being rounded up, then I'll let somebody else give you some actual advice. ;)

Share this post


Link to post
Share on other sites
Just as a side note: you should probably try to avoid loading 'a bunch of textures' that are that small. I used to do this myself, and let me tell you, you will get monstrous performance gains if you combine them into one texture and use texture coordinates to atlas the proper region.

Not only do you gain the ability to batch many more polys together but you also save resources AND the single image will load much faster than the multiple small images.

Share this post


Link to post
Share on other sites
The textures loaded from images that are not power of 2 usually get rounded up like masterworks said.For images of 32x32 no rounding is necessary so its strange that you get 64.Try loading the textures with the D3DX_DEFAULT_NONPOW2 flag and see if you get different results.

Share this post


Link to post
Share on other sites
Quote:
Original post by MasterWorks
Just as a side note: you should probably try to avoid loading 'a bunch of textures' that are that small. I used to do this myself, and let me tell you, you will get monstrous performance gains if you combine them into one texture and use texture coordinates to atlas the proper region.

Not only do you gain the ability to batch many more polys together but you also save resources AND the single image will load much faster than the multiple small images.

What I am doing is loading each individual texture (its easier to have them seperate to change graphics in photoshop etc). Then I merge a bunch of them into one texture. I use the merged texture during rendering.

Quote:
Original post by MasterWorks
This may be stupid, but are you sure your files are actually 32x32 and not like 36x36 or something? The first thing that comes to mind is that your textures are being rounded up to the nearest size power of 2 at load time. At least, that is the most common problem when this type of question is asked (which is often!) If they really are being rounded up, then I'll let somebody else give you some actual advice. ;)

Yeah, sorry I just realised this myself 5 minutes after posting this. I changed my example to suit. So basically I had a texture 96x96, and it was enlarged to 128x128, a power of 2 texture.



Ok, now I have thought of a new problem. If I have a texture that is not square, eg a rectangle 32x64, the sides are power of 2, but I guess both sides have to be the same, or can they be different as long as they are power of 2?

I am currently testing a bin packing type function, so I kind of need rectangles.

I guess it doesn't matter for me. My graphics card supports textures that are not square, eg 32x64

[Edited by - utilae on May 15, 2007 5:11:55 AM]

Share this post


Link to post
Share on other sites
Quote:
If I have a texture that is not square, eg a rectangle 32x64, the sides are power of 2, but I guess both sides have to be the same, or can they be different as long as they are power of 2?

I am currently testing a bin packing type function, so I kind of need rectangles.

I guess it doesn't matter for me. My graphics card supports textures that are not square, eg 32x64

The textures need not be square.
And be sure that your target audience will also have hardware that supports D3DX_DEFAULT_NONPOW2; you know what they say about assumption.

Admiral

Share this post


Link to post
Share on other sites
Quote:
Original post by TheAdmiral
Quote:
If I have a texture that is not square, eg a rectangle 32x64, the sides are power of 2, but I guess both sides have to be the same, or can they be different as long as they are power of 2?

I am currently testing a bin packing type function, so I kind of need rectangles.

I guess it doesn't matter for me. My graphics card supports textures that are not square, eg 32x64

The textures need not be square.
And be sure that your target audience will also have hardware that supports D3DX_DEFAULT_NONPOW2; you know what they say about assumption.

Admiral
<Nitpick>
The textures can only be non-square if the D3DPTEXTURECAPS_SQUAREONLY cap isn't present. Which it is for most cards, but not all.
</Nitpick>

Also note that there are some fairly major limitations to using non-power-of-2 textures. Overall it's best to use power-of-2 textures unless you absolutely can't.

Share this post


Link to post
Share on other sites
As long as your final texture used for rendering is a power of 2, you should be safe. You can load any size texture you want into system memory (assuming enough memory is available), manipulate, create an atlas as mentioned earlier, and whatever else you need to do.

However, what I can't tell you is if Microsoft's D3DXCreateTextureFromFile routines are smart enough to always allow non-pow-2 textures in system memory on devices that don't support non-pow-2. You may have to write these routines yourself. It would be worth it if you find that this is a bottleneck.

Share this post


Link to post
Share on other sites
Quote:
Original post by Supernat02
However, what I can't tell you is if Microsoft's D3DXCreateTextureFromFile routines are smart enough to always allow non-pow-2 textures in system memory on devices that don't support non-pow-2. You may have to write these routines yourself. It would be worth it if you find that this is a bottleneck.

You can use D3DX_DEFAULT_NONPOW2 to force said functions to use a non-power-of-two size. If they can't, they'll fail when you use that flag.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!