Sign in to follow this  
yangyq

problem of d2d and wic

Recommended Posts

yangyq    100
I create a IWICBitmap, and call CreateWicBitmapRenderTarget to create a ID2D1RenderTarget. then call ID2D1RenderTarget::DrawLine to draw a line. but can't get the expected result. the following is my code: #include <windows.h> #include <D3D11.h> #include <D3D10_1.h> #include <D2D1.h> #include <DXErr.h> #include <DXGI.h> #include <wincodec.h> #include <wincodecsdk.h> // Libs #pragma comment (lib, "D3D11.lib") #pragma comment (lib, "D3D10_1.lib") #pragma comment (lib, "D2D1.lib") #pragma comment (lib, "DXErr.lib") #pragma comment (lib, "DXGI.lib") #pragma comment (lib, "windowscodecs.lib") LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // Main int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { CoInitialize(NULL); // Register windowclass WNDCLASSEX wc; ZeroMemory(&wc, sizeof(wc)); wc.cbSize = sizeof(wc); wc.lpszClassName = TEXT("MyClass"); wc.hInstance = hInstance; wc.lpfnWndProc = WndProc; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wc); // Create window HWND hWnd = CreateWindow( wc.lpszClassName, TEXT("D3D11 with Direct2D"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); // Create D3D11 device and swapchain DXGI_SWAP_CHAIN_DESC scd; ID3D11Device *pDevice11; IDXGISwapChain *pSwapChain; ID3D11DeviceContext *pImmediateContext; ZeroMemory(&scd, sizeof(scd)); scd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; scd.SampleDesc.Count = 1; scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scd.BufferCount = 1; scd.OutputWindow = hWnd; scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; scd.Windowed = TRUE; HRESULT hr = D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG | D3D11_CREATE_DEVICE_BGRA_SUPPORT | D3D11_CREATE_DEVICE_SINGLETHREADED, NULL, 0, D3D11_SDK_VERSION, &scd, &pSwapChain, &pDevice11, NULL, &pImmediateContext ); if(FAILED(hr)) { return 0; } // Get the D3D11 back-buffer ID3D11Texture2D *pBackBuffer11; D3D11_TEXTURE2D_DESC backBufferDesc; hr = pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pBackBuffer11)); if(FAILED(hr)) { return 0; } pBackBuffer11->GetDesc(&backBufferDesc); // Create D2D factory ID2D1Factory *pD2DFactory; hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), (void**)&pD2DFactory); if(FAILED(hr)) { return 0; } IWICImagingFactory* pWICImgFactory = NULL; hr = CoCreateInstance( CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, (void**)&pWICImgFactory); IWICBitmap* pWICBmp = NULL; if(FAILED(pWICImgFactory->CreateBitmap( backBufferDesc.Width, backBufferDesc.Height, GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &pWICBmp))) { return false; } D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties( D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED), 120, 120 ); // Create a Direct2D render target which can draw into the surface in the swap chain ID2D1RenderTarget *pD2DRenderTarget; hr = pD2DFactory->CreateWicBitmapRenderTarget( pWICBmp, &props, &pD2DRenderTarget ); if(FAILED(hr)) { return false; } pD2DFactory->Release(); // Create a solid color brush to draw something with ID2D1SolidColorBrush *pBrush; hr = pD2DRenderTarget->CreateSolidColorBrush(D2D1::ColorF(0.0f, 0.0f, 1.0f, 1.0f), &pBrush); if(FAILED(hr)) { return 0; } // Main loop float angle = 0.0f; ShowWindow(hWnd, nCmdShow); while(true) { MSG msg; if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) { if(msg.message == WM_QUIT) break; else { TranslateMessage(&msg); DispatchMessage(&msg); } } else { pD2DRenderTarget->BeginDraw(); D2D1_COLOR_F brush_color = {1.0f, 1.0f, 1.0f, 1.0f}; pD2DRenderTarget->Clear(&brush_color); D2D1_POINT_2F start = {50.0f, 0.0f}; D2D1_POINT_2F end = {backBufferDesc.Width, backBufferDesc.Height}; pD2DRenderTarget->DrawLine(start, end, pBrush, (float)1); hr = pD2DRenderTarget->EndDraw(); if(FAILED(hr)) { return false; } WICRect rect = {0, 0, backBufferDesc.Width, backBufferDesc.Height}; IWICBitmapLock *pILock = NULL; hr = pWICBmp->Lock( &rect, WICBitmapLockRead, &pILock ); if(FAILED(hr)) { return false; } UINT cbBufferSize = 0; BYTE *pv = NULL; hr = pILock->GetDataPointer(&cbBufferSize, &pv); if(FAILED(hr)) { pILock->Release(); return false; } pImmediateContext->UpdateSubresource( pBackBuffer11, 0, 0, pv, 0, 0 ); pILock->Release(); // Present to screen pSwapChain->Present(1, 0); } } // Release pSwapChain->SetFullscreenState(FALSE, NULL); pImmediateContext->ClearState(); pBrush->Release(); pD2DRenderTarget->Release(); pBackBuffer11->Release(); pImmediateContext->Flush(); pImmediateContext->Release(); pSwapChain->Release(); pDevice11->Release(); UnregisterClass(wc.lpszClassName, hInstance); CoUninitialize(); return 0; } // Window procedure LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { // Window destroyed. case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd, msg, wParam, lParam); }

Share this post


Link to post
Share on other sites
treckle    100
I think you need to specify the row and depth pitch of the source bitmap in your call to UpdateSubresource.

I changed the code just before your Present and got a blue diagonal line to display:


UINT rowPitch = backBufferDesc.Width * 4;
UINT depthPitch = rowPitch * backBufferDesc.Height;

pImmediateContext->UpdateSubresource( pBackBuffer11, 0, 0, pv, rowPitch, depthPitch );

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this