简介:
用QT开发图像显示的小程序,需要一些标注工具,由于用的是opengl渲染,所以就在内存中进行绘制,然后纹理贴图贴出去,发现Qt绘制的效果太差,且速度一般,于是就想着用direct2d来绘制需要的纹理图像。
一、QT:QPainter绘制到QImage
下图是QT直接在QImage对象上绘制的效果,其中QImage长和宽分别为:564 - 466。在打开反走样的设置下,线段和椭圆中的锯齿非常明显,字体绘制的也非常丑陋。
QT绘制代码:
void YGLayerScreen::UpdateQImage(){if (m_QImage.isNull())return;QFont m_Font;m_Font.setPixelSize(36);m_Font.setStyleStrategy(QFont::PreferAntialias);QPainter painter;if (!painter.begin(&m_QImage))return;painter.setPen(QPen(Qt::red, 1));painter.setFont(m_Font);painter.setRenderHints(QPainter::TextAntialiasing|QPainter::Antialiasing | QPainter::SmoothPixmapTransform);painter.drawEllipse(QPoint(m_TextureCol/2, m_TextureRow/2),100,200);painter.drawLine(10, 10, m_TextureCol / 2, 30);painter.drawText(QPoint(50, 50), QString::fromLocal8Bit("你好123TEXTtext"));painter.end();}
二、Direct2D绘制
QT中Direct2D的配置(非常简单),添加头文件和对应的Lib文件即可,如下:
#include <wrl.h>
#include <windows.h>
#include <d2d1.h>
#include <dwrite.h>
#include <wincodec.h>
#pragma comment(lib, "d2d1.lib")
#pragma comment(lib, "Dwrite.lib")
#pragma comment(lib, "windowscodecs.lib")
在窗口中随机绘制100个圆形和一个字符串和椭圆,代码如下:
void QtOpenGL::TestDirect2D()
{/* 统计运行时间 */LARGE_INTEGER start_counter, end_counter, counters, nFreq;QueryPerformanceFrequency(&nFreq);QueryPerformanceCounter(&start_counter);/* 离屏渲染图像的宽高 */UINT uiWidth = 512;// 1920;UINT uiHeight = 512;// 1080;/* IWIC 相关变量 */IWICBitmap *pBitmap = NULL;IWICImagingFactory* pImageFactory = NULL;/* IDWrite 相关变量 */IDWriteTextFormat *pTextFormat = NULL;IDWriteFactory* pDWriterFactory = NULL; /* use the DrawText method */static const WCHAR msc_fontName[] = L"Verdana";static const FLOAT msc_fontSize = 50;HRESULT hr = CoCreateInstance(CLSID_WICImagingFactory,NULL,CLSCTX_INPROC_SERVER,IID_IWICImagingFactory,(LPVOID*)&pImageFactory);if (SUCCEEDED(hr)) {//WICPixelFormatGUID formatGUID = GUID_WICPixelFormat32bppBGRA;hr = pImageFactory->CreateBitmap(uiWidth, uiHeight,GUID_WICPixelFormat32bppPBGRA,WICBitmapCacheOnLoad, &pBitmap);if (SUCCEEDED(hr)) {int a = 0;}}/* */hr = DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED,__uuidof(pDWriterFactory),reinterpret_cast<IUnknown **>(&pDWriterFactory));// Create a DirectWrite text format object.hr = pDWriterFactory->CreateTextFormat(msc_fontName, NULL,DWRITE_FONT_WEIGHT_NORMAL,DWRITE_FONT_STYLE_NORMAL,DWRITE_FONT_STRETCH_NORMAL,msc_fontSize,L"", //locale&pTextFormat);pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);ID2D1Factory *m_pD2DFactory = NULL;//ID2D1DCRenderTarget *m_pRenderTarget = NULL;hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory);if (SUCCEEDED(hr)){// Create a DC render target.D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM,D2D1_ALPHA_MODE_PREMULTIPLIED),0,0,D2D1_RENDER_TARGET_USAGE_NONE,D2D1_FEATURE_LEVEL_DEFAULT);ID2D1RenderTarget* m_Target = NULL;hr = m_pD2DFactory->CreateWicBitmapRenderTarget(pBitmap, &props, &m_Target);D2D1_SIZE_F rtSize = m_Target->GetSize();// Draw a grid background.int width = static_cast<int>(rtSize.width);int height = static_cast<int>(rtSize.height);ID2D1SolidColorBrush* pBlackBrush = NULL;hr = m_Target->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Red),//颜色&pBlackBrush//接收画刷);static const WCHAR sc_txt[] = L"你好!Direct 2D!";if (SUCCEEDED(hr)){m_Target->BeginDraw();m_Target->Clear(D2D1::ColorF(0.26f, 0.56f, 0.87f));m_Target->DrawEllipse(D2D1::Ellipse(D2D1::Point2F(150, 55), 50, 30), pBlackBrush);m_Target->DrawTextW(sc_txt, ARRAYSIZE(sc_txt) - 1,pTextFormat,D2D1::RectF(0, 0, uiWidth/2, uiHeight/2),pBlackBrush);for (int i = 0; i < 100; ++i){FLOAT left = rand() % width;FLOAT top = rand() % height;FLOAT radius = rand() % 200;pBlackBrush->SetColor(D2D1::ColorF(rand() % 100 / 100.f, rand() % 100 / 100.f, rand() % 100 / 100.f, 100));//CD2DEllipse ellipse(CD2DRectF(left, top, left + radius, top + radius));//CD2DSolidColorBrush brush(pRenderTarget, D2D1::ColorF(rand() % 100 / 100.f, rand() % 100 / 100.f, rand() % 100 / 100.f, 100));m_Target->DrawEllipse(D2D1::Ellipse(D2D1::Point2F(left, top), radius, radius), pBlackBrush);//pRenderTarget->FillEllipse(ellipse, &brush);}m_Target->EndDraw();}IWICBitmapLock *pLock = NULL;WICRect rcLock = { 0, 0, uiWidth, uiHeight };hr = pBitmap->Lock(&rcLock, WICBitmapLockWrite, &pLock);if (SUCCEEDED(hr)){UINT cbBufferSize = 0;UINT cbStride = 0;BYTE *pv = NULL;hr = pLock->GetStride(&cbStride);if (SUCCEEDED(hr)){hr = pLock->GetDataPointer(&cbBufferSize, &pv);FILE* pFile = fopen("bmp512.raw", "wb+");fwrite(pv, 1, cbBufferSize, pFile);fclose(pFile);}// Clear the image data//ZeroMemory(pv, cbBufferSize);// Release the bitmap lock.pLock->Release();}}if (pBitmap) {pBitmap->Release();}if (pImageFactory) {pImageFactory->Release();}QueryPerformanceCounter(&end_counter);counters.QuadPart = end_counter.QuadPart - start_counter.QuadPart;LONGLONG fps = nFreq.QuadPart / counters.QuadPart;LONGLONG elapsed = counters.QuadPart * 1000 / nFreq.QuadPart;qDebug() << "FPS :" << fps << "ms";qDebug() << "TIMES :" << elapsed << "ms";start_counter = end_counter;
}
绘制效果如下:
三、性能:待测试
由于绘制的内容不同,暂时没对性能进行测试。