c++ - 将 gdi+ 位图复制到 directx 纹理中

标签 c++ directx gdi+

我目前正在尝试将 gdi+ 位图复制到 directx 纹理中。

由于 Win XP 的限制,我正在使用 DirectX9。以下是我的代码尝试:

#include <gdiplus.h>
#pragma comment(lib, "Gdiplus.lib")

void attemptCopy()
{
static IDirect3DTexture9* mTexture;
Gdiplus::GdiplusStartupInput m_gdiplusStartupInput;
ULONG_PTR m_gdiplusToken;

Gdiplus::GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);

HDC hdc;
PAINTSTRUCT  ps;
UINT mWidth = 1024;
UINT mHeight = 1024;

//hdc = BeginPaint(g_engine->getWindowHandle(), &ps);
using namespace Gdiplus;

Bitmap bitmap(1024, 1024, PixelFormat32bppARGB);
Graphics graphics(&bitmap);

Color transparent = Color(0, 255, 255, 255);
graphics.Clear(transparent);

graphics.SetSmoothingMode(SmoothingModeAntiAlias);
graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);
graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);

FontFamily fontFamily(L"Arial");
StringFormat strformat;
wchar_t pszbuf[] = L"Text Designer";

GraphicsPath path;
path.AddString(pszbuf, wcslen(pszbuf), &fontFamily, 
    FontStyleRegular, 48, Gdiplus::Point(10,10), &strformat );
Pen pen(Color(234,137,6), 6);
graphics.DrawPath(&pen, &path);
SolidBrush brush(Color(128,0,255));
graphics.FillPath(&brush, &path);

//save bitmap for comparison
CLSID pngClsid;
GetEncoderClsid(L"image/png", &pngClsid);
bitmap.Save(L"test_bit.png", &pngClsid, NULL);

D3DXCreateTexture(
    g_engine->getDevice(),
    mWidth,
    mHeight,
    1,
    0,
    //D3DFMT_A8L8,
    D3DFMT_A8R8G8B8,
    D3DPOOL_MANAGED,
    &mTexture);

D3DLOCKED_RECT lockedRect;
mTexture->LockRect(0, &lockedRect,0, 0);   

unsigned char* TexData = (unsigned char*)lockedRect.pBits;

memcpy(TexData, &bitmap, sizeof(bitmap) );

mTexture->UnlockRect(0);

D3DXSaveTextureToFileA("test.png",D3DXIFF_PNG, mTexture, 0);

//EndPaint(g_engine->getWindowHandle(), &ps);
Gdiplus::GdiplusShutdown(m_gdiplusToken);
}

基本上我正在尝试将 gdiplus 位图的 memcpy 转换为 directx 纹理。 结果如下:

  1. test.png(保存的directx贴图) http://i1280.photobucket.com/albums/a500/daegon123/test_zps09f12c7f.png

  2. test_bit.png(对比保存的位图) http://i1280.photobucket.com/albums/a500/daegon123/test_bit_zpse8be6cd7.png

test_bit.png 返回正确的图像,而 directx 纹理保持空白。因此,我似乎只是在复制过程中做错了一些事情。

关于如何完成这项工作有什么想法吗?

最佳答案

问题在这里:

memcpy(TexData, &bitmap, sizeof(bitmap) );   // this is not correct

您正在复制 Bitmap 类本身,但您应该复制它环绕的像素。所以你需要 lock the bitmap pixels访问底层数据。

像这样:

BitmapData bitmapData;
bitmap.LockBits(&Rect(0,0,mWidth,mHeight), ImageLockModeRead, 
    PixelFormat32bppARGB, &bitmapData);
unsigned char *pSourcePixels = (unsigned char*)bitmapData.Scan0;

然后你必须逐行复制像素以防步长不同:

// get destination pointer and copy pixels
unsigned char *pDestPixels = (unsigned char*)lockedRect.pBits;
for (int y = 0; y < mHeight; ++y)
{
    // copy a row
    memcpy(pDestPixels, pSourcePixels, mWidth * 4);   // 4 bytes per pixel

    // advance row pointers
    pSourcePixels += bitmapData.Stride;
    pDestPixels += lockedRect.Pitch;
}

请注意,您需要确保底层像素格式是等效的 - 我假设两者相同,但如果您需要重新排序,您可能需要修改上面的代码,例如BGRA 转 ARGB 等

关于c++ - 将 gdi+ 位图复制到 directx 纹理中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16493702/

相关文章:

c++ - 在 xcode ".mm"文件中设置一个 c++ 类 nil。

c++ - 将 SpriteBatch 与 Direct3D 和 XAML 结合使用

visual-studio-2005 - 在 VS2005 中使用 Windows 7 和 DirectX SDK

c# - 如何将其他命名空间导入 Visual C#?

c++ - 如何释放 Gdiplus::Bitmap::FromFile 分配的内存

ASP.NET 创建缩略图服务器端

c++ - 嵌入Python 3.3 : How do I access _PyParser_Grammar?

C++ 指针类型的模板函数重载

c++ - 我如何从 HBITMAP 获取字节数组

c# - 使用 Graphics.FillPath 奇怪地绘制 GraphicsPath