2013-05-11 56 views
1

我正在尝试将gdi +位图复制到directx纹理中。将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纹理保持空白。因此,我似乎只是在复制过程中做了一些不正确的事情。

有关如何完成此任务的任何想法?

回答

3

的问题是在这里:

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等

+0

谢谢,工作很棒! – dk123 2013-05-11 07:30:05