Windows 上的 SKIA 渲染(来自 HDC 的 SkCanvas)
SKIA Rendering on Windows(SkCanvas from HDC)
我正在尝试使用 SKIA 在 Windows 上绘图。
有没有办法从HDC启动SkCanvas?
Windows 上有几种方法 "to use" skia。 skia 文件夹中 skia\src\views\win 的 SkOSWindow_win.cpp 中描述了这些方法。
例如:
您可以将 OpenGL 视口附加到您的 window,因为它已在函数 SkOSWindow::attachGL
中完成
HDC dc = GetDC((HWND)fHWND);
if (NULL == fHGLRC) {
fHGLRC = SkCreateWGLContext(dc, msaaSampleCount,
kGLPreferCompatibilityProfile_SkWGLContextRequest);
if (NULL == fHGLRC) {
return false;
}
glClearStencil(0);
glClearColor(0, 0, 0, 0);
glStencilMask(0xffffffff);
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
}
if (wglMakeCurrent(dc, (HGLRC)fHGLRC)) {
// use DescribePixelFormat to get the stencil bit depth.
int pixelFormat = GetPixelFormat(dc);
PIXELFORMATDESCRIPTOR pfd;
DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd);
info->fStencilBits = pfd.cStencilBits;
// Get sample count if the MSAA WGL extension is present
SkWGLExtensions extensions;
if (extensions.hasExtension(dc, "WGL_ARB_multisample")) {
static const int kSampleCountAttr = SK_WGL_SAMPLES;
extensions.getPixelFormatAttribiv(dc,
pixelFormat,
0,
1,
&kSampleCountAttr,
&info->fSampleCount);
}
else {
info->fSampleCount = 0;
}
glViewport(0, 0,
SkScalarRoundToInt(this->width()),
SkScalarRoundToInt(this->height()));
return true;
}
您可以像在 SkOSWindow::doPaint 中所做的那样,通过执行 BitBlt 操作将 SkCanvas 的内容复制到 HDC
HDC hdc = (HDC)ctx;
const SkBitmap& bitmap = this->getBitmap();
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(bmi));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = bitmap.width();
bmi.bmiHeader.biHeight = -bitmap.height(); // top-down image
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
//
// Do the SetDIBitsToDevice.
//
// TODO(wjmaclean):
// Fix this call to handle SkBitmaps that have rowBytes != width,
// i.e. may have padding at the end of lines. The SkASSERT below
// may be ignored by builds, and the only obviously safe option
// seems to be to copy the bitmap to a temporary (contiguous)
// buffer before passing to SetDIBitsToDevice().
SkASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes());
bitmap.lockPixels();
int ret = SetDIBitsToDevice(hdc,
0, 0,
bitmap.width(), bitmap.height(),
0, 0,
0, bitmap.height(),
bitmap.getPixels(),
&bmi,
DIB_RGB_COLORS);
(void)ret; // we're ignoring potential failures for now.
bitmap.unlockPixels();
我正在尝试使用 SKIA 在 Windows 上绘图。
有没有办法从HDC启动SkCanvas?
Windows 上有几种方法 "to use" skia。 skia 文件夹中 skia\src\views\win 的 SkOSWindow_win.cpp 中描述了这些方法。
例如:
您可以将 OpenGL 视口附加到您的 window,因为它已在函数 SkOSWindow::attachGL
中完成HDC dc = GetDC((HWND)fHWND); if (NULL == fHGLRC) { fHGLRC = SkCreateWGLContext(dc, msaaSampleCount, kGLPreferCompatibilityProfile_SkWGLContextRequest); if (NULL == fHGLRC) { return false; } glClearStencil(0); glClearColor(0, 0, 0, 0); glStencilMask(0xffffffff); glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); } if (wglMakeCurrent(dc, (HGLRC)fHGLRC)) { // use DescribePixelFormat to get the stencil bit depth. int pixelFormat = GetPixelFormat(dc); PIXELFORMATDESCRIPTOR pfd; DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd); info->fStencilBits = pfd.cStencilBits; // Get sample count if the MSAA WGL extension is present SkWGLExtensions extensions; if (extensions.hasExtension(dc, "WGL_ARB_multisample")) { static const int kSampleCountAttr = SK_WGL_SAMPLES; extensions.getPixelFormatAttribiv(dc, pixelFormat, 0, 1, &kSampleCountAttr, &info->fSampleCount); } else { info->fSampleCount = 0; } glViewport(0, 0, SkScalarRoundToInt(this->width()), SkScalarRoundToInt(this->height())); return true; }
您可以像在 SkOSWindow::doPaint 中所做的那样,通过执行 BitBlt 操作将 SkCanvas 的内容复制到 HDC
HDC hdc = (HDC)ctx; const SkBitmap& bitmap = this->getBitmap(); BITMAPINFO bmi; memset(&bmi, 0, sizeof(bmi)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = bitmap.width(); bmi.bmiHeader.biHeight = -bitmap.height(); // top-down image bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biSizeImage = 0; // // Do the SetDIBitsToDevice. // // TODO(wjmaclean): // Fix this call to handle SkBitmaps that have rowBytes != width, // i.e. may have padding at the end of lines. The SkASSERT below // may be ignored by builds, and the only obviously safe option // seems to be to copy the bitmap to a temporary (contiguous) // buffer before passing to SetDIBitsToDevice(). SkASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes()); bitmap.lockPixels(); int ret = SetDIBitsToDevice(hdc, 0, 0, bitmap.width(), bitmap.height(), 0, 0, 0, bitmap.height(), bitmap.getPixels(), &bmi, DIB_RGB_COLORS); (void)ret; // we're ignoring potential failures for now. bitmap.unlockPixels();