-
Is there examples of using blend2d with native Win32 programs? |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 2 replies
-
There are no official examples for raw Win32. However, the simplest approach would be using Blend2D with DIBSECTION - it would work well and it would be fast. |
Beta Was this translation helpful? Give feedback.
-
Here are some key codes, maybe helpful to the people who see this post. HDC hScreen = GetDC(NULL);
BITMAPINFO bmi = {};
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = w;
bmi.bmiHeader.biHeight = -h; // top-down
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
//HBITMAP bgHbitmap;
//char* bgPixels;
bgHbitmap = CreateDIBSection(hScreen, &bmi, DIB_RGB_COLORS, reinterpret_cast<void**>(&bgPixels), NULL, NULL);
ReleaseDC(NULL, hScreen); BLImage img(w, h, BL_FORMAT_PRGB32);
BLContext ctx(img);
BLPath path;
path.moveTo(0, 0);
path.lineTo(w, h);
ctx.setStrokeStyle(BLRgba32(0xFFFFFFFF));
ctx.strokePath(path);
ctx.end();
BLImageData data;
img.getData(&data);
unsigned int dataSize = w * h * 4;
char* tempData = (char*)(data.pixelData);
for (int x = 0; x < dataSize; x += 4)
{
bgPixels[x + 2] = tempData[x]; //red
bgPixels[x + 1] = tempData[x+1]; //green
bgPixels[x] = tempData[x + 2]; //blue
} case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdc_bmp = CreateCompatibleDC(hdc);
DeleteObject(SelectObject(hdc_bmp, mainWin->bgHbitmap));
BitBlt(hdc, 0, 0, mainWin->w, mainWin->h, hdc_bmp, 0, 0, SRCCOPY);
DeleteDC(hdc_bmp);
EndPaint(hwnd, &ps);
return 0;
} I will leave this post, maybe there will be a better way in the future |
Beta Was this translation helpful? Give feedback.
-
I think that you don't have to do any conversion when rendering to a DIBSECTION. Blend2D's XRGB32 and PRGB32 should be compatible. The pointer to pixel data returned by DIBSECTION can be then passed to BLImage::createFromData() - this way you can share the data of DIBSECTION and BLImage and render to it without having to do any copy. Additionally, for converting pixel data, use BLPixelConverter - it has been optimized and uses SIMD for most common conversions. |
Beta Was this translation helpful? Give feedback.
-
This is the key code for solution using Direct2D technology. unsigned int dataSize = w * h * 4;
auto bgPixels = new char[dataSize];
bgImage = new BLImage(); //BLImage* bgImage;
bgImage->createFromData(w, h, BL_FORMAT_PRGB32, bgPixels, w * 4, [](void* impl, void* externalData, void* userData) {
delete[] externalData;
}); BLContext ctx(*bgImage);
BLPath path;
path.moveTo(0, 0);
path.lineTo(w, h);
path.moveTo(w, 0);
path.lineTo(0, h);
ctx.setStrokeStyle(BLRgba32(0xFF6622FF));
ctx.setStrokeWidth(12.6);
ctx.strokePath(path);
ctx.end(); case WM_PAINT:
{
d2DCreateRes();
render->BeginDraw();
render->DrawBitmap(d2DImage, D2D1::RectF(0, 0, w, h));
auto result = render->EndDraw();
if (D2DERR_RECREATE_TARGET == result)
{
d2DImage->Release();
render->Release();
render = nullptr;
}
ValidateRect(hwnd, NULL);
return 0;
} // create factory before window created
// D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory);
// ID2D1Factory* factory;
// ID2D1HwndRenderTarget* render;
// ID2D1Bitmap* d2DImage;
void MainWin::d2DCreateRes()
{
if (render) return;
D2D1_SIZE_U size = D2D1::SizeU(w, h);
factory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties(hwnd, size), &render);
render->SetTransform(D2D1::Matrix3x2F::Identity());
D2D1_BITMAP_PROPERTIES bmpPorp;
bmpPorp.dpiX = 0;
bmpPorp.dpiY = 0;
bmpPorp.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
bmpPorp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
BLImageData imgData;
bgImage->getData(&imgData);
render->CreateBitmap(size, imgData.pixelData, imgData.stride, bmpPorp, &d2DImage);
} |
Beta Was this translation helpful? Give feedback.
-
I would try more formats - there must definitely be a matching one. Blend2D would be BGRA on little endian machines so stored as [B, G, R, A] in memory. |
Beta Was this translation helpful? Give feedback.
-
I think I made a mistake about the GDI solution. HDC hScreen = GetDC(NULL);
BITMAPINFO info = { sizeof(BITMAPINFOHEADER), w, 0 - h, 1, 32, BI_RGB, dataSize, 0, 0, 0, 0 };
unsigned int dataSize = w * h * 4;
auto boardPixels = new char[dataSize];
//HBITMAP bgHbitmap;
bgHbitmap = CreateDIBSection(hScreen, &info, DIB_RGB_COLORS, reinterpret_cast<void**>(&boardPixels), NULL, NULL);
ReleaseDC(NULL, hScreen); // BLImage* boardImage;
// BLContext* paintCtx;
boardImage = new BLImage();
boardImage->createFromData(w, h, BL_FORMAT_PRGB32, boardPixels, w * 4, [](void* impl, void* externalData, void* userData) {
delete[] externalData;
});
paintCtx = new BLContext(); case WM_PAINT:
{
paintCtx->begin(*boardImage);
//Here I draw my other two pictures on boardImage
paintCtx->blitImage(BLRect(0, 0, w, h), *bgImage);
paintCtx->blitImage(BLRect(0, 0, w, h), *canvasImage);
paintCtx->end();
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HDC hdcBmp = CreateCompatibleDC(hdc);
DeleteObject(SelectObject(hdcBmp, bgHbitmap));
BitBlt(hdc, 0, 0, w, h, hdcBmp, 0, 0, SRCCOPY);
DeleteDC(hdcBmp);
EndPaint(hwnd, &ps);
ValidateRect(hwnd, NULL);
return 0;
} This is my screen drawing program, so far it's just a Demo. |
Beta Was this translation helpful? Give feedback.
There are no official examples for raw Win32. However, the simplest approach would be using Blend2D with DIBSECTION - it would work well and it would be fast.