Direct2D drawing quality is inconsistent

HoWe Yu 41 Reputation points
2024-06-17T03:24:16.3466667+00:00

This is the result drawn in the window(HwndRenderTarget)

01

This is the result of drawing in WicBitmapRenderTarget

02

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,493 questions
C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,608 questions
{count} votes

Accepted answer
  1. Castorix31 82,751 Reputation points
    2024-06-18T08:41:02.99+00:00

    See MSDN :"Note that WIC bitmap render targets do not support hardware rendering."

    You use D2D1_RENDER_TARGET_TYPE_HARDWARE in first sample and D2D1_RENDER_TARGET_TYPE_SOFTWARE in second sample

    If you force D2D1_RENDER_TARGET_TYPE_SOFTWARE in first sample, you will get the same result as with WIC

    (and you use old Direct2D code, use Direct2D device context method instead...)

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. HoWe Yu 41 Reputation points
    2024-06-17T13:10:39.9366667+00:00
    #include <d2d1.h>
    #include <wincodec.h>
    
    #pragma comment(lib, "d2d1.lib")
    #pragma comment(lib, "windowscodecs.lib")
    
    using D2D1::ColorF;
    using D2D1::Point2F;
    
    int main()
    {
    	ID2D1Factory* factory;
    	D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory);
    
    	ID2D1DCRenderTarget* renderTarget;
    	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
    	);
    	factory->CreateDCRenderTarget(&props, &renderTarget);
    
    	HDC hdc = GetDC(NULL);
    	RECT rect{ 0, 0, 120, 40 };
    	renderTarget->BindDC(hdc, &rect);
    
    	ID2D1SolidColorBrush* brush = nullptr;
    	renderTarget->CreateSolidColorBrush(ColorF(ColorF::Black), &brush);
    
    	renderTarget->BeginDraw();
    	renderTarget->Clear(ColorF(ColorF::White));
    	renderTarget->DrawLine(Point2F(20, 20.5), Point2F(100, 21.5), brush);
    	// Insert breakpoint here to view the drawing results
    	renderTarget->EndDraw();
    
    	if (renderTarget) renderTarget->Release();
    	if (factory) factory->Release();
    
    	return 0;
    }
    
    
    #include <d2d1.h>
    #include <wincodec.h>
    
    #pragma comment(lib, "d2d1.lib")
    #pragma comment(lib, "windowscodecs.lib")
    
    using D2D1::ColorF;
    using D2D1::Point2F;
    
    int main()
    {
        CoInitialize(nullptr);
    
        IWICImagingFactory* wicFactory = nullptr;
        ID2D1Factory* d2dFactory = nullptr;
    
        IWICBitmap* wicBitmap = nullptr;
        ID2D1RenderTarget* renderTarget = nullptr;
        ID2D1SolidColorBrush* brush = nullptr;
    
        IWICBitmapEncoder* encoder = nullptr;
        IWICBitmapFrameEncode* frameEncode = nullptr;
        IWICStream* stream = nullptr;
    
        CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (void**)&wicFactory);
        D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &d2dFactory);
    
        wicFactory->CreateBitmap(120, 40, GUID_WICPixelFormat32bppBGR, WICBitmapCacheOnLoad, &wicBitmap);
        d2dFactory->CreateWicBitmapRenderTarget(wicBitmap, D2D1::RenderTargetProperties(), &renderTarget);
        renderTarget->CreateSolidColorBrush(ColorF(ColorF::Black), &brush);
    
        renderTarget->BeginDraw();
        renderTarget->Clear(ColorF(ColorF::White));
        renderTarget->DrawLine(Point2F(20, 20.5), Point2F(100, 21.5), brush);
        renderTarget->EndDraw();
    
        wicFactory->CreateStream(&stream);
        const WCHAR filename[] = L"output.png";
        stream->InitializeFromFilename(filename, GENERIC_WRITE);
    
        wicFactory->CreateEncoder(GUID_ContainerFormatPng, NULL, &encoder);
        encoder->Initialize(stream, WICBitmapEncoderNoCache);
        encoder->CreateNewFrame(&frameEncode, NULL);
    
        frameEncode->Initialize(NULL);
        frameEncode->SetSize(120, 40);
        WICPixelFormatGUID format = GUID_WICPixelFormatDontCare;
        frameEncode->SetPixelFormat(&format);
        frameEncode->WriteSource(wicBitmap, NULL);
        frameEncode->Commit();
    
        encoder->Commit();
    
        return 0;
    }