Martin Heller
Contributing Writer

Loading a Direct3D mesh from a resource

analysis
Jul 3, 20083 mins

Why is it that trivial things become hard so often, especially when you're doing API-level C++ programming? Here's an example: I needed to convert a Windows Direct3D benchmark from loading its textures and meshes from files to loading them from resources, to simplify the installation of the benchmark as an ActiveX control. This should have been trivial: just change the D3DXCreateTextureFromFile calls to D3DXCrea

Why is it that trivial things become hard so often, especially when you’re doing API-level C++ programming? Here’s an example:

I needed to convert a Windows Direct3D benchmark from loading its textures and meshes from files to loading them from resources, to simplify the installation of the benchmark as an ActiveX control. This should have been trivial: just change the D3DXCreateTextureFromFile calls to D3DXCreateTextureFromResource calls and the D3DXLoadMeshFromX calls to D3DXLoadMeshFromXResource calls, and Bob’s your Uncle.

Not so fast.

The textures loaded fine from resources once I plugged g_HInstance in as the hSrcModule and MAKEINTRESOURCEA(iResourceID) as the pSrcResource in the following prototype:

<b>HRESULT </b><b>D3DXCreateTextureFromResource(</b>
  <b>LPDIRECT3DDEVICE9</b> <i>pDevice</i><b>,</b>
  <b>HMODULE</b> <i>hSrcModule</i><b>,</b>
  <b>LPCTSTR</b> <i>pSrcResource</i><b>,</b>
  <b>LPDIRECT3DTEXTURE9 *</b> <i>ppTexture</i>
<b>)</b>;

So the actual code became something like:

D3DXCreateTextureFromResourceA(eng->getD3DDevice(), g_hInstance, MAKEINTRESOURCEA(texNum), &texture );

This worked without a hitch. On the other hand, loading a mesh gave me fits. The prototype is:

<b>HRESULT </b><b>D3DXLoadMeshFromXResource(</b>
  <b>HMODULE</b> <i>Module</i><b>,</b>
  <b>LPCSTR</b> <i>Name</i><b>,</b>
  <b>LPCSTR</b> <i>Type</i><b>,</b>
  <b>DWORD</b> <i>Options</i><b>,</b>
  <b>LPDIRECT3DDEVICE9</b> <i>pD3DDevice</i><b>,</b>
  <b>LPD3DXBUFFER *</b> <i>ppAdjacency</i><b>,</b>
  <b>LPD3DXBUFFER *</b> <i>ppMaterials</i><b>,</b>
  <b>LPD3DXBUFFER *</b> <i>ppEffectInstances</i><b>,</b>
  <b>DWORD *</b> <i>pNumMaterials</i><b>,</b>
  <b>LPD3DXMESH *</b> <i>ppMesh</i>
<b>)</b>;

I tried “X” for the Type, but the mesh didn’t load. What to do?

The documentation for the March 2008 DirectX SDK has the promising explanation of the second through fourth parameters:

See Find Resource to find out more about the Module, Name and Type parameters.

While that link works today, when I was trying to solve the problem it brought up an error page in Japanese. Go figure. If you follow the Resource Types link in the Find Resource page, you’ll get to a table of standard resource types (which I also couldn’t find when I actually had the problem): the one we want is RT_RCDATA, since meshes aren’t covered by any of the other standard resource types. (At the time, it took a Google Code search to find this.)

In fact, using that value didn’t work for me: RT_RCDATA is not really the enum value you’d expect, but is actually a macro that resolves to the highly intuitive MAKEINTRESOURCE(10). My ActiveX control was compiled for Unicode, so MAKEINTRESOURCE resolved to MAKEINTRESOURCEW, which returns a pointer to a wide character string. Unfortunately, D3DXLoadMeshFromXResource has a LPCSTR for the Type parameter, not a LPTSTR, so it needs an ANSI string, not a Unicode string. What I really needed there was MAKEINTRESOURCEA(10). The final call looked something like:

D3DXLoadMeshFromXResource(g_hInstance, MAKEINTRESOURCEA(meshNum), MAKEINTRESOURCEA(10), usageFlag, d3dDevice, NULL, NULL, NULL, &dwNumber, &pMesh );

And that worked. Whew!

Martin Heller

Martin Heller is a contributing writer at InfoWorld. Formerly a web and Windows programming consultant, he developed databases, software, and websites from his office in Andover, Massachusetts, from 1986 to 2010. From 2010 to August of 2012, Martin was vice president of technology and education at Alpha Software. From March 2013 to January 2014, he was chairman of Tubifi, maker of a cloud-based video editor, having previously served as CEO.

Martin is the author or co-author of nearly a dozen PC software packages and half a dozen Web applications. He is also the author of several books on Windows programming. As a consultant, Martin has worked with companies of all sizes to design, develop, improve, and/or debug Windows, web, and database applications, and has performed strategic business consulting for high-tech corporations ranging from tiny to Fortune 100 and from local to multinational.

Martin’s specialties include programming languages C++, Python, C#, JavaScript, and SQL, and databases PostgreSQL, MySQL, Microsoft SQL Server, Oracle Database, Google Cloud Spanner, CockroachDB, MongoDB, Cassandra, and Couchbase. He writes about software development, data management, analytics, AI, and machine learning, contributing technology analyses, explainers, how-to articles, and hands-on reviews of software development tools, data platforms, AI models, machine learning libraries, and much more.

More from this author