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.