Texture manager is fail

Started by
17 comments, last by dmatter 15 years, 11 months ago
I tried to write a texture manager that stopped textures being loaded more than once, but I've hit a slight snag. The textures don't load at all, they get returned as NULL even though if the file doesn't exist, a "missing.dds" texture gets set. here is the code that loads the textures:
LPDIRECT3DTEXTURE9 RenderSystem::getTexture(std::string filename)
{
	std::ofstream outF("error.txt",std::ios_base::app);
	std::vector<std::pair<std::string,LPDIRECT3DTEXTURE9>>::iterator texIt;
	
	for(texIt = mTextures.begin(); texIt != mTextures.end(); texIt++)
	{
		outF << (*texIt).first << " : "<< filename << "\n";
		if((*texIt).first == filename)
		{
			return (*texIt).second;
		}
	}
	
	outF << filename.c_str() << "\n";

	
	//Texture isn't loaded yet, try to load it..
	LPDIRECT3DTEXTURE9 nNewTx=0;
	
	std::ifstream mFile(filename.c_str());
	
	if(mFile.is_open())
	{
		mFile.close();
		D3DXCreateTextureFromFile(d3ddev,filename.c_str(),&nNewTx);
		outF << "RenderManager: Texture Found!" << "\n";
		mTextures.push_back(std::pair<std::string,LPDIRECT3DTEXTURE9>(filename,nNewTx));	
	}
	else
	{
		D3DXCreateTextureFromFile(d3ddev,"missing.dds",&nNewTx);
		outF << "OSHI-" << "\n";
		mFile.close();
	}
	outF.close();
	return nNewTx;
}
this of course, outputs to a file:
Quote:sprite.dds RenderManager: Texture Found! sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds sprite.dds : sprite.dds
Now, even though it "finds" the texture, the instance of the texture that is returned is NULL, and instead of being greeted by some sprites (which is what happens when i load the file per sprite) I just get a blank screen :(
Advertisement
Are you sure that it loads "missing.dds" successfully? You never check the return value of D3DXCreateTextureFromFile().

Step over the code with the debugger to see exactly what's going on.

BTW, there is no need to call close() on the files; their destructors will take care of that.
Ok, after checking the Result of the call, It doesn't load the texture. but it doesn't return any of the errors here: http://msdn2.microsoft.com/en-us/library/bb172801(VS.85).aspx either. What :(
How are you checking for errors? The correct way is to use the FAILED and SUCCEEDED macros. Example:

if ( FAILED(D3DXCreateTextureFromFile(...)) ) { ... }


Doing something like this:

if ( D3DXCreateTextureFromFile(...) != D3D_OK ) { ... }


is wrong (don't remember why though).
Use the debug runtimes, they will give you more information as to why exactly function calls are failing.
Ok, Now i'm doing this..
	if(mFile.is_open())	{		mFile.close();		HRESULT hr;		hr = D3DXCreateTextureFromFile(d3ddev,filename.c_str(),&nNewTx);		if(FAILED(hr))		{ 			char buf[2048];			sprintf(buf, "Error: %s error description: %s\n",DXGetErrorString(hr),DXGetErrorDescription(hr));			outF << buf << "\n";			return NULL; 		}		outF << "RenderManager: Texture Found!" << "\n";		mTextures.push_back(std::pair<std::string,LPDIRECT3DTEXTURE9>(filename,nNewTx));		}	else	{		HRESULT hr;		hr = D3DXCreateTextureFromFile(d3ddev,"missing.dds",&nNewTx);		if(FAILED(hr))		{ 			char buf[2048];			sprintf(buf, "Error: %s error description: %s\n",DXGetErrorString(hr),DXGetErrorDescription(hr));			outF << buf << "\n";			return NULL; 		}	}


and I'm getting this:
Quote:sprite.dds
Error: D3DERR_INVALIDCALL error description: Invalid call




[Edited by - danharibo on April 24, 2008 2:10:32 PM]
First, don't post the same line a 100 times. Posting it once and saying it repeats is enough. Please edit your two posts and fix this.

Second, like MJP said, use the Debug Runtimes and see if you get any errors.

Third, that error might mean that it is unable to locate the texture. Make sure you are using the correct path.
Quote:Original post by Gage64
First, don't post the same line a 100 times. Posting it once and saying it repeats is enough. Please edit your two posts and fix this.

Second, like MJP said, use the Debug Runtimes and see if you get any errors.

Third, that error might mean that it is unable to locate the texture. Make sure you are using the correct path.


Ok, Sorry :x

I'm running the debug runtimes, and I'm getting this now:
Quote:D3DX: pTexture pointer is invalid


And It can locate the file, as when I load the texture per Sprite, it works.
Do you get the same behavior if you use a different filetype? "sprite.png" for example? Is there a particular reason you're storing your textures in a vector of pairs? Wouldn't a key-value container be better?

Just reviewing my own texture pool code, the only time D3DXCreateTextureFromFileEx fails on me is when it cant find the texture in the folder it's looking in.
Quote:Original post by Gage64
if ( D3DXCreateTextureFromFile(...) != D3D_OK ) { ... }

is wrong (don't remember why though).
Because a "failed" return value is a value with the high bit set, there's 2 billion possible "success" values, and 2 billion possible "failure" values. Checking against D3D_OK is only checking one of the 2 billion possible values. It's less of an issue with D3D, since I think it almost always returns D3D_OK, but there are some calls that can return e.g. S_FALSE, which is a success code, but isn't the same as D3D_OK (It usually means that the call succeeded, but there's something that might cause problems - E.g. SetTexture(0, NULL) might return S_FALSE because it succeeded, but the texture passed was NULL (Hypothetically)).


Quote:Original post by danharibo
I'm running the debug runtimes, and I'm getting this now:
Quote:D3DX: pTexture pointer is invalid


And It can locate the file, as when I load the texture per Sprite, it works.
Where is that error coming from? What function (The line before or after it in the debug output will tell you)?

Also, I wouldn't bother checking if the file exists, why not just set the missing.dds file if the original file can't be loaded?
And what Gage64 said - a std::map would be much better suited for this, that's exactly what it's for after all...

This topic is closed to new replies.

Advertisement