Yesterday I put some code that calls a D3DX function in a published program that I maintain. D3DX was a bundle of helper functions for Direct3D 9 which Microsoft deprecated in 2012. I’m writing this in 2018. The function was this one:
I thought to myself, “It’s deprecated, but Microsoft is so fanatically committed to backward compatibility that I can probably still use it.”
Microsoft’s documentation says the required library is D3dx9.lib.
The next day a bunch of people reported that the new build wouldn’t run because the operating system couldn’t find d3dx9_43.dll. Apparently this happened only on laptops running Windows 10. There was no problem on desktop machines running Windows 10 or on any machine running an earlier version of Windows.
So I wrote a replacement for D3DXCreateTextureFromResource. My new code’s not as general-purpose as the D3DX function because it makes assumptions about the pixel format, but it does what I need it to do.
//-------------------------------
// CREATE TEXTURE FROM RESOURCE
// Assumes D3DFMT_A8R8G8B8 /
// PixelFormat32bppARGB
// Returns 0 on failure
//-------------------------------
#include <d3d9.h>
#include <gdiplus.h>
using namespace Gdiplus;
IDirect3DTexture9 *
create_texture_from_resource (
IDirect3DDevice9 * pDev,
HMODULE hModule,
unsigned uResource )
{
auto pBm =
Gdiplus::Bitmap::FromResource (
hModule,
MAKEINTRESOURCE(uResource) );
if ( Status::Ok !=
pBm->GetLastStatus() )
return 0;
UINT uDimY = pBm->GetHeight();
UINT uDimX = pBm->GetWidth();
IDirect3DTexture9 * pTex = 0;
HRESULT hr =
pDev->CreateTexture (
uDimX,
uDimY,
1,
0,
D3DFMT_A8R8G8B8,
D3DPOOL_MANAGED,
&pTex,
NULL );
if ( FAILED(hr) )
return 0;
//----------------------
// SOURCE POINTER
//----------------------
BitmapData bd;
Rect rect ({0,0,(int)uDimX,
(int)uDimY});
if ( Status::Ok !=
pBm->LockBits (
&rect,
ImageLockModeRead,
PixelFormat32bppARGB,
&bd) )
return 0;
unsigned char * pSrcPixels =
(unsigned char*) bd.Scan0;
//---------------------------
// DEST POINTER
//---------------------------
D3DLOCKED_RECT lr;
if ( D3D_OK !=
pTex->LockRect (
0, &lr, 0, 0) )
{
pTex->Release();
delete pBm;
return 0;
}
unsigned char * pDestPixels =
(unsigned char*)lr.pBits;
//--------------------------------
// COPY
// By row in case strides differ.
//--------------------------------
for ( size_t y = 0; y < uDimY; y++ )
{
memcpy ( pDestPixels,
pSrcPixels, uDimX * sizeof(DWORD) );
pSrcPixels += bd.Stride;
pDestPixels += lr.Pitch;
}
pBm->UnlockBits ( &bd );
delete pBm;
pTex->UnlockRect(0);
return pTex;
}
This page was first published on February 25, 2018 and last revised on June 1, 2021.