我无法使其在纯汇编中正常工作,所以我尝试使C代码绘制到屏幕上,但是C代码也不会这样做,而且我也不知道为什么,也没有给出错误代码。我试图通过GDI DC使用Direct2D直接绘制在屏幕上。
我的C代码,很抱歉,如果它有点混乱,应该是暂时的,可以快速修复
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
#include <d2d1.h>
#pragma comment(lib, "d2d1.lib")
extern "C" ID2D1Bitmap* mybitmapcreate(ID2D1DCRenderTarget*);
float left = 5;
float top = 10;
float Bottom = 10;
float Right = 30;
ID2D1Bitmap* picbitmap;
D2D1_RECT_F myrect = D2D1::RectF(left, top, Bottom, Right);
ID2D1DCRenderTarget* pow;
ID2D1Bitmap* mybitmap;
ID2D1Factory *l;
REFIID x = __uuidof(ID2D1Factory);
struct D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(
DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE),
0,
0,
D2D1_RENDER_TARGET_USAGE_NONE,
D2D1_FEATURE_LEVEL_DEFAULT
);
struct D2D1_BITMAP_PROPERTIES bitmapprops = D2D1::BitmapProperties(
D2D1::PixelFormat(DXGI_FORMAT_R8G8B8A8_UINT, D2D1_ALPHA_MODE_UNKNOWN), 96.0, 96.0
);
int main()
{
/*
long bufferend;
FILE* mybitmapfile;
char* mybitmaparray;
//size_t result;
mybitmapfile = fopen("bitmap.bin", "rb");
if (mybitmapfile == NULL) { fputs("File error", stderr); exit(1); }
fseek(mybitmapfile, 0, SEEK_END);
//bufferend = ftell(mybitmapfile);
bufferend = 1204097;
rewind(mybitmapfile);
mybitmaparray = (char*) malloc(sizeof(char)*bufferend);
if (mybitmaparray == NULL) { fputs("Memory error", stderr); exit(2); }
fread(mybitmaparray, 1, bufferend, mybitmapfile);
fclose(mybitmapfile);
*/
HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &l);
l->CreateDCRenderTarget(&props, &pow);
picbitmap = mybitmapcreate(pow);
pow->BeginDraw();
while (true) {
pow->DrawBitmap(picbitmap, myrect, 1.0F, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, myrect);
};
pow->EndDraw();
return 0;
}
这是mybitmapcreate,它的返回值是位图。
includelib user32.lib
includelib D2D1.lib
include externals.asm
include wincons.asm
include vtable.asm
.data
include variables.asm
include pic.asm
include riid.asm
include structures.asm
.code
public mybitmapcreate
bitmapcreate proc frame
mybitmapcreate::
DB 48h
push rbx
.pushreg rbx
push r13
.pushreg r13
push rbp
.pushreg rbp
sub rsp, 80
.allocstack 80
lea rbp, [rsp + 80]
.setframe rbp, 80
.endprolog
mov ID2D1DCRenderTarget, rcx
call __imp_GetDesktopWindow
mov rcx, 0
mov rbx, rax
getdcfail:
call __imp_GetDC
cmp rax, 0
je getdcfail
mov rcx, rbx
lea rdx, ScreenSize
mov screendc, rax
call __imp_GetWindowRect
mov rcx, ID2D1DCRenderTarget
mov rbx, [rcx]
mov rdx, ScreenDC
lea r8, ScreenSize
call ID2D1DCRenderTarget_BindDC
mov rcx, ID2D1DCRenderTarget
mov rbx, [rcx]
mov rdx, 000000199000002E0h
lea r8, pic1colorbytes
mov r9, 2944
lea rax, pic1properties
mov qword ptr [rsp + 20h], rax
lea rax, ID2D1Bitmap1
mov qword ptr [rsp + 28h], rax
call ID2D1DCRenderTarget_CreateBitmap
mov rax, ID2D1Bitmap1
mov rsp, rbp
pop rbp
pop r13
pop rbx
ret
bitmapcreate endp
end
这是我的vtable
;ID2D1RenderTargetVtbl
ID2D1RenderTarget_QueryInterface textequ <qword ptr [rbx+0]>
ID2D1RenderTarget_AddRef textequ <qword ptr [rbx+8]>
ID2D1RenderTarget_Release textequ <qword ptr [rbx+16]>
ID2D1RenderTarget_GetFactory textequ <qword ptr [rbx+24]>
ID2D1RenderTarget_CreateBitmap textequ <qword ptr [rbx+32]>
ID2D1RenderTarget_CreateBitmapFromWicBitmap textequ <qword ptr [rbx+40]>
ID2D1RenderTarget_CreateSharedBitmap textequ <qword ptr [rbx+48]>
ID2D1RenderTarget_CreateBitmapBrush textequ <qword ptr [rbx+56]>
ID2D1RenderTarget_CreateSolidColorBrush textequ <qword ptr [rbx+64]>
ID2D1RenderTarget_CreateGradientStopCollection textequ <qword ptr [rbx+72]>
ID2D1RenderTarget_CreateLinearGradientBrush textequ <qword ptr [rbx+80]>
ID2D1RenderTarget_CreateRadialGradientBrush textequ <qword ptr [rbx+88]>
ID2D1RenderTarget_CreateCompatibleRenderTarget textequ <qword ptr [rbx+96]>
ID2D1RenderTarget_CreateLayer textequ <qword ptr [rbx+104]>
ID2D1RenderTarget_CreateMesh textequ <qword ptr [rbx+112]>
ID2D1RenderTarget_DrawLine textequ <qword ptr [rbx+120]>
ID2D1RenderTarget_DrawRectangle textequ <qword ptr [rbx+128]>
ID2D1RenderTarget_FillRectangle textequ <qword ptr [rbx+136]>
ID2D1RenderTarget_DrawRoundedRectangle textequ <qword ptr [rbx+144]>
ID2D1RenderTarget_FillRoundedRectangle textequ <qword ptr [rbx+152]>
ID2D1RenderTarget_DrawEllipse textequ <qword ptr [rbx+160]>
ID2D1RenderTarget_FillEllipse textequ <qword ptr [rbx+168]>
ID2D1RenderTarget_DrawGeometry textequ <qword ptr [rbx+176]>
ID2D1RenderTarget_FillGeometry textequ <qword ptr [rbx+184]>
ID2D1RenderTarget_FillMesh textequ <qword ptr [rbx+192]>
ID2D1RenderTarget_FillOpacityMask textequ <qword ptr [rbx+200]>
ID2D1RenderTarget_DrawBitmap textequ <qword ptr [rbx+208]>
ID2D1RenderTarget_DrawText textequ <qword ptr [rbx+216]>
ID2D1RenderTarget_DrawTextLayout textequ <qword ptr [rbx+224]>
ID2D1RenderTarget_DrawGlyphRun textequ <qword ptr [rbx+232]>
ID2D1RenderTarget_SetTransform textequ <qword ptr [rbx+240]>
ID2D1RenderTarget_GetTransform textequ <qword ptr [rbx+248]>
ID2D1RenderTarget_SetAntialiasMode textequ <qword ptr [rbx+256]>
ID2D1RenderTarget_GetAntialiasMode textequ <qword ptr [rbx+264]>
ID2D1RenderTarget_SetTextAntialiasMode textequ <qword ptr [rbx+272]>
ID2D1RenderTarget_GetTextAntialiasMode textequ <qword ptr [rbx+280]>
ID2D1RenderTarget_SetTextRenderingParams textequ <qword ptr [rbx+288]>
ID2D1RenderTarget_GetTextRenderingParams textequ <qword ptr [rbx+296]>
ID2D1RenderTarget_SetTags textequ <qword ptr [rbx+304]>
ID2D1RenderTarget_GetTags textequ <qword ptr [rbx+312]>
ID2D1RenderTarget_PushLayer textequ <qword ptr [rbx+320]>
ID2D1RenderTarget_PopLayer textequ <qword ptr [rbx+328]>
ID2D1RenderTarget_Flush textequ <qword ptr [rbx+336]>
ID2D1RenderTarget_SaveDrawingState textequ <qword ptr [rbx+344]>
ID2D1RenderTarget_RestoreDrawingState textequ <qword ptr [rbx+352]>
ID2D1RenderTarget_PushAxisAlignedClip textequ <qword ptr [rbx+360]>
ID2D1RenderTarget_PopAxisAlignedClip textequ <qword ptr [rbx+368]>
ID2D1RenderTarget_Clear textequ <qword ptr [rbx+376]>
ID2D1RenderTarget_BeginDraw textequ <qword ptr [rbx+384]>
ID2D1RenderTarget_EndDraw textequ <qword ptr [rbx+392]>
ID2D1RenderTarget_GetPixelFormat textequ <qword ptr [rbx+400]>
ID2D1RenderTarget_SetDpi textequ <qword ptr [rbx+408]>
ID2D1RenderTarget_GetDpi textequ <qword ptr [rbx+416]>
ID2D1RenderTarget_GetSize textequ <qword ptr [rbx+424]>
ID2D1RenderTarget_GetPixelSize textequ <qword ptr [rbx+432]>
ID2D1RenderTarget_GetMaximumBitmapSize textequ <qword ptr [rbx+440]>
ID2D1RenderTarget_IsSupported textequ <qword ptr [rbx+448]>
;ID2D1Factory
ID2D1Factory_QueryInterface textequ <qword ptr [rbx+0]>
ID2D1Factory_AddRef textequ <qword ptr [rbx+8]>
ID2D1Factory_Release textequ <qword ptr [rbx+16]>
ID2D1Factory_ReloadSystemMetrics textequ <qword ptr [rbx+24]>
ID2D1Factory_GetDesktopDpi textequ <qword ptr [rbx+32]>
ID2D1Factory_CreateRectangleGeometry textequ <qword ptr [rbx+40]>
ID2D1Factory_CreateRoundedRectangleGeometry textequ <qword ptr [rbx+48]>
ID2D1Factory_CreateEllipseGeometry textequ <qword ptr [rbx+56]>
ID2D1Factory_CreateGeometryGroup textequ <qword ptr [rbx+64]>
ID2D1Factory_CreateTransformedGeometry textequ <qword ptr [rbx+72]>
ID2D1Factory_CreatePathGeometry textequ <qword ptr [rbx+80]>
ID2D1Factory_CreateStrokeStyle textequ <qword ptr [rbx+88]>
ID2D1Factory_CreateDrawingStateBlock textequ <qword ptr [rbx+96]>
ID2D1Factory_CreateWicBitmapRenderTarget textequ <qword ptr [rbx+104]>
ID2D1Factory_CreateHwndRenderTarget textequ <qword ptr [rbx+112]>
ID2D1Factory_CreateDxgiSurfaceRenderTarget textequ <qword ptr [rbx+120]>
ID2D1Factory_CreateDCRenderTarget textequ <qword ptr [rbx+128]>
;dcrendertarget
ID2D1DCRenderTarget_QueryInterface textequ <qword ptr [rbx+0]>
ID2D1DCRenderTarget_AddRef textequ <qword ptr [rbx+8]>
ID2D1DCRenderTarget_Release textequ <qword ptr [rbx+16]>
ID2D1DCRenderTarget_GetFactory textequ <qword ptr [rbx+24]>
ID2D1DCRenderTarget_CreateBitmap textequ <qword ptr [rbx+32]>
ID2D1DCRenderTarget_CreateBitmapFromWicBitmap textequ <qword ptr [rbx+40]>
ID2D1DCRenderTarget_CreateSharedBitmap textequ <qword ptr [rbx+48]>
ID2D1DCRenderTarget_CreateBitmapBrush textequ <qword ptr [rbx+56]>
ID2D1DCRenderTarget_CreateSolidColorBrush textequ <qword ptr [rbx+64]>
ID2D1DCRenderTarget_CreateGradientStopCollection textequ <qword ptr [rbx+72]>
ID2D1DCRenderTarget_CreateLinearGradientBrush textequ <qword ptr [rbx+80]>
ID2D1DCRenderTarget_CreateRadialGradientBrush textequ <qword ptr [rbx+88]>
ID2D1DCRenderTarget_CreateCompatibleRenderTarget textequ <qword ptr [rbx+96]>
ID2D1DCRenderTarget_CreateLayer textequ <qword ptr [rbx+104]>
ID2D1DCRenderTarget_CreateMesh textequ <qword ptr [rbx+112]>
ID2D1DCRenderTarget_DrawLine textequ <qword ptr [rbx+120]>
ID2D1DCRenderTarget_DrawRectangle textequ <qword ptr [rbx+128]>
ID2D1DCRenderTarget_FillRectangle textequ <qword ptr [rbx+136]>
ID2D1DCRenderTarget_DrawRoundedRectangle textequ <qword ptr [rbx+144]>
ID2D1DCRenderTarget_FillRoundedRectangle textequ <qword ptr [rbx+152]>
ID2D1DCRenderTarget_DrawEllipse textequ <qword ptr [rbx+160]>
ID2D1DCRenderTarget_FillEllipse textequ <qword ptr [rbx+168]>
ID2D1DCRenderTarget_DrawGeometry textequ <qword ptr [rbx+176]>
ID2D1DCRenderTarget_FillGeometry textequ <qword ptr [rbx+184]>
ID2D1DCRenderTarget_FillMesh textequ <qword ptr [rbx+192]>
ID2D1DCRenderTarget_FillOpacityMask textequ <qword ptr [rbx+200]>
ID2D1DCRenderTarget_DrawBitmap textequ <qword ptr [rbx+208]>
ID2D1DCRenderTarget_DrawText textequ <qword ptr [rbx+216]>
ID2D1DCRenderTarget_DrawTextLayout textequ <qword ptr [rbx+224]>
ID2D1DCRenderTarget_DrawGlyphRun textequ <qword ptr [rbx+232]>
ID2D1DCRenderTarget_SetTransform textequ <qword ptr [rbx+240]>
ID2D1DCRenderTarget_GetTransform textequ <qword ptr [rbx+248]>
ID2D1DCRenderTarget_SetAntialiasMode textequ <qword ptr [rbx+256]>
ID2D1DCRenderTarget_GetAntialiasMode textequ <qword ptr [rbx+264]>
ID2D1DCRenderTarget_SetTextAntialiasMode textequ <qword ptr [rbx+272]>
ID2D1DCRenderTarget_GetTextAntialiasMode textequ <qword ptr [rbx+280]>
ID2D1DCRenderTarget_SetTextRenderingParams textequ <qword ptr [rbx+288]>
ID2D1DCRenderTarget_GetTextRenderingParams textequ <qword ptr [rbx+296]>
ID2D1DCRenderTarget_SetTags textequ <qword ptr [rbx+304]>
ID2D1DCRenderTarget_GetTags textequ <qword ptr [rbx+312]>
ID2D1DCRenderTarget_PushLayer textequ <qword ptr [rbx+320]>
ID2D1DCRenderTarget_PopLayer textequ <qword ptr [rbx+328]>
ID2D1DCRenderTarget_Flush textequ <qword ptr [rbx+336]>
ID2D1DCRenderTarget_SaveDrawingState textequ <qword ptr [rbx+344]>
ID2D1DCRenderTarget_RestoreDrawingState textequ <qword ptr [rbx+352]>
ID2D1DCRenderTarget_PushAxisAlignedClip textequ <qword ptr [rbx+360]>
ID2D1DCRenderTarget_PopAxisAlignedClip textequ <qword ptr [rbx+368]>
ID2D1DCRenderTarget_Clear textequ <qword ptr [rbx+376]>
ID2D1DCRenderTarget_BeginDraw textequ <qword ptr [rbx+384]>
ID2D1DCRenderTarget_EndDraw textequ <qword ptr [rbx+392]>
ID2D1DCRenderTarget_GetPixelFormat textequ <qword ptr [rbx+400]>
ID2D1DCRenderTarget_SetDpi textequ <qword ptr [rbx+408]>
ID2D1DCRenderTarget_GetDpi textequ <qword ptr [rbx+416]>
ID2D1DCRenderTarget_GetSize textequ <qword ptr [rbx+424]>
ID2D1DCRenderTarget_GetPixelSize textequ <qword ptr [rbx+432]>
ID2D1DCRenderTarget_GetMaximumBitmapSize textequ <qword ptr [rbx+440]>
ID2D1DCRenderTarget_IsSupported textequ <qword ptr [rbx+448]>
ID2D1DCRenderTarget_BindDC textequ <qword ptr [rbx+456]>
您缺少一些必要条件:
需要win32窗口
需要初始化IWICImagingFactory接口
需要使用BindDC方法将其与GDI
DC关联。
修改后的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
#include <d2d1.h>
#include <wincodec.h>
#pragma comment(lib, "d2d1.lib")
#pragma comment(lib, "Windowscodecs.lib")
#define SAFE_RELEASE(P) if(P){P->Release() ; P = NULL ;}
extern "C" ID2D1Bitmap* mybitmapcreate(ID2D1DCRenderTarget*);
float left = 5;
float top = 10;
float Bottom = 10;
float Right = 30;
ID2D1Bitmap *pBitmap = NULL;
IWICImagingFactory *pIWICFactory = NULL;
void initize();
void draw();
D2D1_RECT_F myrect = D2D1::RectF(left, top, Bottom, Right);
ID2D1DCRenderTarget* pow;
ID2D1Bitmap* mybitmap;
ID2D1Factory *l;
REFIID x = __uuidof(ID2D1Factory);
HRESULT LoadBitmapFromFile(
ID2D1RenderTarget *pRenderTarget,
IWICImagingFactory *pIWICFactory,
PCWSTR uri,
UINT destinationWidth,
UINT destinationHeight
)
{
HRESULT hr = S_OK;
IWICBitmapDecoder *pDecoder = NULL;
IWICBitmapFrameDecode *pSource = NULL;
IWICStream *pStream = NULL;
IWICFormatConverter *pConverter = NULL;
IWICBitmapScaler *pScaler = NULL;
hr = pIWICFactory->CreateDecoderFromFilename(
uri,
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
if (SUCCEEDED(hr))
{
// Create the initial frame.
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
hr = pIWICFactory->CreateFormatConverter(&pConverter);
}
// If a new width or height was specified, create an
// IWICBitmapScaler and use it to resize the image.
if (destinationWidth != 0 || destinationHeight != 0)
{
UINT originalWidth, originalHeight;
hr = pSource->GetSize(&originalWidth, &originalHeight);
if (SUCCEEDED(hr))
{
if (destinationWidth == 0)
{
FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight);
destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
}
else if (destinationHeight == 0)
{
FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth);
destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
}
hr = pIWICFactory->CreateBitmapScaler(&pScaler);
if (SUCCEEDED(hr))
{
hr = pScaler->Initialize(
pSource,
destinationWidth,
destinationHeight,
WICBitmapInterpolationModeCubic
);
}
if (SUCCEEDED(hr))
{
hr = pConverter->Initialize(
pScaler,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
}
}
if (SUCCEEDED(hr))
{
// Create a Direct2D bitmap from the WIC bitmap.
hr = pRenderTarget->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
}
SAFE_RELEASE(pDecoder);
SAFE_RELEASE(pSource);
SAFE_RELEASE(pStream);
SAFE_RELEASE(pConverter);
SAFE_RELEASE(pScaler);
return TRUE;
}
LRESULT CALLBACK WndProcFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
RECT rc;
switch (message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
GetClientRect(hwnd, &rc);
pow->BindDC(ps.hdc, &rc);
draw();
EndPaint(hwnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
int main(int argc, char* argv[])
{
WNDCLASS wc{};
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProcFunc;
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = L"Class_Name";
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
RegisterClass(&wc);
HWND hWnd = CreateWindow(L"Class_Name", L"Test", WS_OVERLAPPEDWINDOW, 100, 100, 1000, 500, NULL, NULL, GetModuleHandle(NULL), NULL);
initize();
ShowWindow(hWnd, 1);
UpdateWindow(hWnd);
MSG Msg;
while (GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return 0;
}
void initize()
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, reinterpret_cast<void **>(&pIWICFactory));
// Create a Direct2D render target.
D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(
DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE),
0,
0,
D2D1_RENDER_TARGET_USAGE_NONE,
D2D1_FEATURE_LEVEL_DEFAULT
);
HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &l);
l->CreateDCRenderTarget(&props, &pow);
}
void draw()
{
LoadBitmapFromFile(pow, pIWICFactory, L"Path\\test.bmp", 650, 400);
pow->BeginDraw();
pow->Clear(D2D1::ColorF(D2D1::ColorF::White));
D2D1_SIZE_F size = pBitmap->GetSize();
D2D1_POINT_2F upperLeftCorner = D2D1::Point2F(0.f, 0.f);
// Draw bitmap
pow->DrawBitmap(
pBitmap,
D2D1::RectF(
upperLeftCorner.x,
upperLeftCorner.y,
upperLeftCorner.x + size.width,
upperLeftCorner.y + size.height)
);
pow->EndDraw();
}
代码中可能有一些冗余,您可以自由地添加和删除。
调试: