004:Direct 2D离屏渲染(Qt中实现)

news2024/11/18 13:33:31

简介:

    用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;
}

 绘制效果如下:

三、性能:待测试 

由于绘制的内容不同,暂时没对性能进行测试。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1270199.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

48、Flink DataStream API 编程指南(3)- 完整版

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

【element-plus使用】el-select自定义样式、下拉框选项过长等问题解决

1、自定义样式 <template><el-select v-model"value" style"width: 150px"><el-option label"选项一" value"option1"></el-option><el-option label"选项二" value"option2"><…

C++ 抽象类和接口 详解

目录 0 引言1 抽象类2 接口2.1 Java与C接口的区别 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;C专栏&#x1f4a5; 标题&#xff1a;C 抽象类和接口 详解❣️ 寄语&#xff1a;书到用时方恨少&#xff0c;事非经过不知难&#xff01;&#x1f…

springboot整合easy-es实现数据的增删改查

背景 目前公司的一个老项目&#xff0c;查询贼慢&#xff0c;需要想办法提升一下速度&#xff0c;于是就想到了ES&#xff0c;现在尝试一下将ES整合到项目中来提升检索效率。 ES是基于倒排索引实现的&#xff0c;倒排索引中一个表相当于一个索引&#xff0c;表中的每条记录都…

yolov1网络结构说明

文章目录 一. 网络结构二. 网络说明1. 网络的输入2. 网络的输出(1) 5 5表示:每个网格使用两个先验框进行预测。(2) “5”表示&#xff1a;每个先验框包含的预测信息的数量。(3) 20表示&#xff1a;20个分类预测值(4) 每个网格能预测几个目标&#xff1f; 一. 网络结构 论文下…

海外储能认证标准

北美认证 UL9540 代表一个封装完整的储能系统功能安全认证&#xff0c;关注机械测试&#xff0c;电器测试和环境测试 UL9540A 关注消防本身&#xff0c;UL9540A测试主要从电池储能系统安装参数&#xff0c;安装通风要求&#xff0c;消防设施&#xff0c;消防策略和应对措施…

一个小学数学题

如下面动图所示&#xff0c;问阴影部分的面积是不是不变的&#xff1f; 求解&#xff1a; 当弦BC和DE平行时&#xff0c;扇区 A B ⌢ \overset{\LARGE{\frown}}{AB} AB⌢不变&#xff0c;BC到DE的距离始终保持不变&#xff0c;假设两条线段之间的距离为H, 由三角形的面积公式&…

TZOJ 1370 数值统计

答案&#xff1a; #include <stdio.h> int main() {int n0,i0;int fcount 0; //负数计数器int zcount 0; //整数计数器int pcount 0; //小数计数器while (scanf("%d", &n) 1 && n ! 0) //多组输入&#xff0c;并且不为0{double…

LeetCode(37)矩阵置零【矩阵】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 73. 矩阵置零 1.题目 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]…

试试手气(Python)

题目描述 试试手气 我们知道一个骰子有 6 个面&#xff0c;分别刻了 1 到 6 个点。下面给你 6 个骰子的初始状态&#xff0c;即它们朝上一面的点数&#xff0c;让你一把抓起摇出另一套结果。假设你摇骰子的手段特别精妙&#xff0c;每次摇出的结果都满足以下两个条件&#xff…

Java多线程核心技术一-多线程基础其他内容

接上篇&#xff1a; Java多线程核心技术一-基础篇synchronzied同步方法 Java多线程核心技术一-基础篇synchronzied同步语句块 1 String常量池特性与同步问题 JVM具有String常量池的功能&#xff0c;如下示例&#xff1a; public class Test01 {public static void main(Str…

TZOJ 1367 计算两点间的距离

答案&#xff1a; #include <stdio.h> #include<math.h> //引用数学的库函数 int main() {double x1 0.0, y1 0.0, x2 0.0, y2 0.0; //由于输入的是实数&#xff0c;实数包括小数&#xff0c;所以不能 用int类型&#xff0c;只能用double类型while (sc…

elementui中table进行表单验证

<el-form :model"ruleForm" ref"ruleForm" class"demo-ruleForm"><el-table :data"ruleForm.tableDataShou" border style"width: 100%;"><el-table-column type"index" label"序号" wi…

Python - Real-ESRGAN 提升图像、视频清晰度 - 最高可达 4 K

目录 一.引言 二.Real-ESRGAN 理论 1.模型简介 2.经典退化模型 ◆ 退化过程全览 ◆ K - 高斯滤波 ◆ N - 噪声 ◆ ↓r - Resize ◆ jpeg - 压缩 3.高阶退化模型 4.环形和超调伪影 5.网络结构 ◆ ESRGAN 生成器 ◆ U-Net 鉴别器 三.Real-ESRGAN 实战 1.快速体验…

CNS0项目创建交货单增加销售办事处

1、业务需求 1.1、销售办事处介绍 销售办事处是指在企业中负责销售活动的区域性单位或部门。在SD模块中&#xff0c;可以表示企业的不同销售地点、销售办公室、分销中心或分公司。 销售办事处扮演着多种角色和职责&#xff0c;例如&#xff1a; 销售活动管理&#xff1a;销售…

福州大学《嵌入式系统综合设计》 实验十二:图像压缩标准JPEG编解码

一、实验目的 掌握基于算能平台的JPEG压缩编码方法以及开发环境&#xff0c;包括开发主机环境搭建&#xff0c;硬件嵌入式开发板的连接&#xff0c;云平台的配置&#xff0c;编码程序的编译、运行等。 二、实验内容 搭建实验开发环境&#xff0c;并编写静止图像jpeg格式编解…

Linux常用命令——badblocks命令

在线Linux命令查询工具 badblocks 查找磁盘中损坏的区块 补充说明 badblock命令用于查找磁盘中损坏的区块。 硬盘是一个损耗设备&#xff0c;当使用一段时间后可能会出现坏道等物理故障。电脑硬盘出现坏道后&#xff0c;如果不及时更换或进行技术处理&#xff0c;坏道就会越…

渗透测试考核(靶机1)

信息收集 主机发现 nbtscan -r 172.16.17.0/24 发现在局域网内&#xff0c;有两台主机名字比较可疑&#xff0c;177和134&#xff0c;猜测其为目标主机&#xff0c;其余的应该是局域网内的其他用户&#xff0c;因为其主机名字比较显眼&#xff0c;有姓名的拼音和笔记本电脑的…

AI搜索相关性在网站和APP上的应用

设定场景&#xff1a;您在寻找一件新衣服&#xff0c;所以在浏览最喜欢的网店。您跳到搜索栏上&#xff0c;输入您要找的东西。您期待出现什么结果&#xff1f; 高度准确、相关和即时的结果。 无论在什么网站上搜索&#xff0c;寻找什么&#xff0c;甚至在打错字或使用了错误的…

【算法刷题】Day9

文章目录 611. 有效三角形的个数![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/9d627e680e9144a2b67474a1d80aa030.png)题解&#xff1a;代码&#xff1a; LCR 179. 查找总价格为目标值的两个商品题解&#xff1a;代码&#xff1a; 611. 有效三角形的个数 原题链…