Reputation: 106
I couldn't get it to work in pure assembly so i tried making C code to draw to the screen but the C code won't do it either and i don't know why and nothing is giving error codes. Im trying to draw directly onto the screen with Direct2D through a GDI DC.
My C code, sorry if its a little messy it was supposed to be temporary for a quick fix
#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;
}
This is mybitmapcreate, its return value is the bitmap.
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
This is my 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]>
Upvotes: 0
Views: 1318
Reputation: 6289
You lack some necessary conditions:
need a win32 window
refer: Creating a Window
need to initialize IWICImagingFactory interface
need to use BindDC method to associate it with a GDI
DC.
Modified code:
#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();
}
There may be some redundancy in the code, you can freely add and delete.
Debug:
Upvotes: 3