D3DXCreateEffectFromFile problem

Started by
7 comments, last by MichaelWojcik 14 years, 7 months ago
Hi there, I am in the works of an asset viewer and am trying to create an effect with the D3DXCreateEffectFromFile function with DirectX 9. Heres the code of the call. // Create the FX from a .fx file. ID3DXBuffer* errors = 0; HRESULT hret; hret = D3DXCreateEffectFromFile(pD3DDevice, "NormalMap.fx", 0, 0, D3DXSHADER_DEBUG, 0, &m_pFX, &errors); if( errors ) MessageBox(0, (char*)errors->GetBufferPointer(), 0, 0); The call does not fill the error buffer and passes through but the value returned in hret is -2005529767. I am not quite sure off hand what this means. But this leaves the ID3DXEffect variable m_pFX uninitialized, there fore making it unusible. I am using visual studio 2008 on a side note. Any thought and help is greatly appreciated. Thanks!
Advertisement
There is a tool in the DirectX SDK called "DirectX Error Lookup" which you can use to find out what the error codes mean.

Most errors which don't fill the error buffer, at least in my experience, stem from when D3DXCreateEffectFromFile cannot actually find the file you passed in. You've passed only the name of the file - make sure it's in the current working directory, or alternatively, pass in the full path.
You can get a string describing the error code with DxGetErrorString(), or a description of the error with DxGetErrorDescription().

The error buffer is filled for compile errors, so you don't know yet if it will compile correctly.

Other return values are D3DERR_INVALIDCALL, D3DXERR_INVALIDDATA, E_OUTOFMEMORY for non-compile related errors.

My guess is that the path to NormalMap.fx is incomplete and can't be found.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Thanks guys for the info. Can you perhaps give me an example of how to specify a working directory? I thought it went something like
"..\\Effects\NormalMap.fx"

but this doesent work and same with specifiying the full path to the file such as when I do this

"C:\Documents and Settings\Michael Wojcik\My Documents\Programming\Something Engine\ModelViewer\Effects\NormalMap.fx".

I put the error code into the d3derror dialog app and it does indeed give me Name: D3DXERR_INVALIDDATA, so I too would think it would be the pathing, but Im not quite sure at the moment what is the matter with it.
Are you getting compiler warnings when you use "C:\Documents and Settings\Michael Wojcik\..." as the path? You really need to pay attention to compiler warnings. In this case, you'd get warnings about "D" and "M" (and others) not being valid escape characters. You should be using the following path:

"C:\\Documents and Settings\\Michael Wojcik\\My Documents\\Programming\\Something Engine\\ModelViewer\\Effects\\NormalMap.fx"

In addition, in most cases, the working directory is the same directory that the executable is running from (though it can be explicitly changed - e.g. if you use GetOpenFileName, it will typically change the working directory to whatever directory the file you opened was in. Using shortcuts, you can also change the working directory your program starts from).

So assuming your executable is in the "...\\Something Engine\\ModelViewer" directory, a proper relative path would be "Effects\\NormalMap.fx".
Thanks a ton. it seems that the full path works! :)

"C:\\Documents and Settings\\Michael Wojcik\\My Documents\\Programming\\Something Engine\\ModelViewer\\Effects\\NormalMap.fx"

But oddly the "Effects\\NormalMap.fx" seems to not be working, and I tried this one recently too. Perhaps the shortcuts you mentioned might assist this problem. How would I go about that?

Also I do use MFC's CFileDialog to open a open dialog, but only for loading meshes. The mesh is then stored into an object class which also houses its effect. Could this be messing with the working directory?
Quote:Original post by MichaelWojcik
Also I do use MFC's CFileDialog to open a open dialog, but only for loading meshes. The mesh is then stored into an object class which also houses its effect. Could this be messing with the working directory?
Yes, CFileDialog is just a wrapper around GetOpenFileName, and it will change the working directory to whatever directory the file you opened was in.

As I mentioned in this recent thread, the way I usually work is that I save off the working directory (via. GetCurrentDirectory) when my program starts up, and combine that directory with whatever relative path names I want. That way, my code is unaffected if anything changes the working directory in the meantime.
In general, you have to be careful with MFC. When you launch the app from the IDE (Visual Studio), the working directory is set to the project directory. If you launch the app from outside VS, the working directory is set to the executable directory (either Debug or Release).

The best bet is to determine the project directory at the start of the app. The following code from an old MFC project looks funny but it works.
char projPath[MAX_PATH];GetCurrentDirectory(MAX_PATH,projPath);int pos = (int)strlen(projPath);char *projName = "ModelViewer";int len = (int)strlen(projName);while( true ) { // work backwards until project directory found	// find first '\' from end	while( projPath[pos] != '\\' && pos > 0 ) pos--;	if( pos==0 ) break;	pos++;	if( strnicmp(&projPath[pos],projName,len) == 0 ) { // found it		projPath[pos+len] = 0;		strcat(projPath,"\\");		break;	} else {		pos--;		pos--;	}}

Then, whenever you want to specify a filename, append it to "projPath" and you'll always have a full path to the file.
E.g.
char fxPath[MAX_PATH];strcat(strcpy(fxPath,projPath),"Effect\\something.fx");D3DXCreateEffectFromFile(..., fxPath, ...);

Yeah, the old string functions are now deprecated for security reasons, but they work.

EDIT: simultaneous posts.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Works perfectly. Thanks guys!

This topic is closed to new replies.

Advertisement