OpenGL绘制文本

一:QPainter绘制

在 OpenGL 渲染的窗口中(如 QOpenGLWidget),通过 QPainter 直接绘制文本。Qt 会自动将 2D 内容(文本、图形)与 OpenGL 内容合成。在paintGL()里面绘制,如果有其他纹理,在绘制纹理后解绑资源,再绘制文本。

    m_program.bind();// 绑定纹理m_texture->bind(0);m_program.setUniformValue("texture1", 0);// 绘制矩形glBindVertexArray(VAO[0]);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);// 解绑VAOglBindVertexArray(0);m_program.release();// ----------------- 绘制文字 -----------------QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);painter.setPen(Qt::yellow);painter.setFont(QFont("Arial", 16, QFont::Bold));// 带背景的文字QString text =  QString("%1:%2x%3").arg("宽高").arg(width()).arg(height());QRect textRect = painter.fontMetrics().boundingRect(text);textRect.moveTo(5, 5);painter.fillRect(textRect.adjusted(-1, -1, 1, 1), QColor(0, 0, 0, 128));painter.drawText(textRect, Qt::AlignLeft, text);painter.end();

二:生成文本纹理并渲染四边形(高性能,适合动态文本)

将文本预渲染为纹理,通过 OpenGL 四边形显示,适合高频更新或大量文本。

步骤 1:创建文本纹理
QImage MyGLWidget::createTextTexture(const QString& text, int width, int height) {QImage image(width, height, QImage::Format_ARGB32);image.fill(Qt::transparent);QPainter painter(&image);painter.setPen(Qt::white);painter.setFont(QFont("Arial", 24));painter.drawText(image.rect(), Qt::AlignCenter, text);painter.end();// OpenGL 纹理坐标系原点在左下角,需垂直翻转图像return image.mirrored(false, true);
}
步骤 2:绑定纹理并渲染四边形
QImage MyGLWidget::createTextTexture(const QString& text, int width, int height) {QImage image(width, height, QImage::Format_ARGB32);image.fill(Qt::transparent);QPainter painter(&image);painter.setPen(Qt::white);painter.setFont(QFont("Arial", 24));painter.drawText(image.rect(), Qt::AlignCenter, text);painter.end();// OpenGL 纹理坐标系原点在左下角,需垂直翻转图像return image.mirrored(false, true);
}

优化技巧‌:

  • 使用 ‌纹理缓存‌ 存储常用文本,避免重复生成。
  • 动态更新纹理时,使用 glTexSubImage2D 局部更新数据。

三、使用 FreeType 库 + OpenGL(灵活但复杂) 

通过 FreeType 加载字体文件生成字形纹理图集,实现高度定制的文本渲染(如游戏引擎风格)。

步骤 1:集成 FreeType 库

在 .pro 文件中添加依赖:

LIBS += -lfreetype

步骤 2:加载字体并生成字形 
#include <ft2build.h>
#include FT_FREETYPE_Hstruct Character {GLuint textureID;glm::ivec2 size;glm::ivec2 bearing;GLuint advance;
};std::map<GLchar, Character> characters;void loadFont(const char* fontPath) {FT_Library ft;FT_Init_FreeType(&ft);FT_Face face;FT_New_Face(ft, fontPath, 0, &face);FT_Set_Pixel_Sizes(face, 0, 48);glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // 禁用字节对齐限制for (GLubyte c = 0; c < 128; c++) {FT_Load_Char(face, c, FT_LOAD_RENDER);GLuint texture;glGenTextures(1, &texture);glBindTexture(GL_TEXTURE_2D, texture);glTexImage2D(GL_TEXTURE_2D, 0, GL_RED,face->glyph->bitmap.width,face->glyph->bitmap.rows,0, GL_RED, GL_UNSIGNED_BYTE,face->glyph->bitmap.buffer);// 设置纹理参数glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);Character character = {texture,glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),static_cast<GLuint>(face->glyph->advance.x)};characters.insert(std::make_pair(c, character));}FT_Done_Face(face);FT_Done_FreeType(ft);
}
步骤 3:渲染文本 
void renderText(QOpenGLShaderProgram& program, const std::string& text, GLfloat x, GLfloat y, GLfloat scale) {program.bind();glActiveTexture(GL_TEXTURE0);for (auto c = text.begin(); c != text.end(); c++) {Character ch = characters[*c];GLfloat xpos = x + ch.bearing.x * scale;GLfloat ypos = y - (ch.size.y - ch.bearing.y) * scale;GLfloat w = ch.size.x * scale;GLfloat h = ch.size.y * scale;// 更新 VBO 数据(需预先创建)GLfloat vertices = {{xpos, ypos + h, 0.0, 0.0},{xpos, ypos, 0.0, 1.0},{xpos + w, ypos, 1.0, 1.0},{xpos, ypos + h, 0.0, 0.0},{xpos + w, ypos, 1.0, 1.0},{xpos + w, ypos + h, 1.0, 0.0}};glBindTexture(GL_TEXTURE_2D, ch.textureID);glBindBuffer(GL_ARRAY_BUFFER, m_vbo);glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);glDrawArrays(GL_TRIANGLES, 0, 6);x += (ch.advance >> 6) * scale; // 单位转换为像素}program.release();
}
关键问题解决
  1. 文本模糊‌:

    • 确保纹理过滤设置为 GL_LINEAR
    • 使用高分辨率字体或 MSDF(多通道有符号距离场)技术。
  2. 中文支持‌:

    • FreeType 方法需加载中文字体(如 .ttf),并遍历 Unicode 字符集。
  3. 性能优化‌:

    • 批处理文本绘制调用,减少状态切换。
    • 使用实例化渲染(Instancing)处理大量相同字体的文本。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

23种设计模式-适配器(Adapter)设计模式

适配器设计模式 &#x1f6a9;什么是适配器设计模式&#xff1f;&#x1f6a9;适配器设计模式的特点&#x1f6a9;适配器设计模式的结构&#x1f6a9;适配器设计模式的优缺点&#x1f6a9;适配器设计模式的Java实现&#x1f6a9;代码总结&#x1f6a9;总结 &#x1f6a9;什么是…

R语言对偏态换数据进行转换(对数、平方根、立方根)

我们进行研究的时候经常会遇见偏态数据&#xff0c;数据转换是统计分析和数据预处理中的一项基本技术。使用 R 时&#xff0c;了解如何正确转换数据有助于满足统计假设、标准化分布并提高分析的准确性。在 R 中实现和可视化最常见的数据转换&#xff1a;对数、平方根和立方根转…

REC一些操作解法

一.Linux命令长度突破 1.源码如下 <?php $param $_REQUEST[param];if ( strlen($param) < 8 ) {echo shell_exec($param); } 2.源码分析 echo执行函数&#xff0c;$_REQUEST可以接post、get、cookie传参 3.破题思路 源码中对参数长度做了限制&#xff0c;小于8位&a…

16个气象数据可视化网站整理分享

好的&#xff01;以下是关于“16个气象数据可视化网站整理分享”的软文&#xff1a; 16个气象数据可视化网站整理分享 气象数据可视化已成为现代气象研究、决策支持以及公众天气服务的重要组成部分。从天气预报到气候变化监测&#xff0c;全球许多气象数据可视化平台为专业人士…

Stereolabs ZED Box Mini:机器人与自动化领域的人工智能视觉新选择

在人工智能视觉技术快速发展的今天&#xff0c;其应用场景正在持续拓宽&#xff0c;从智能安防到工业自动化&#xff0c;从机器人技术到智能交通&#xff0c;各领域都在积极探索如何利用这一先进技术。而 Stereolabs 推出的ZED Box Mini&#xff0c;正是一款专为满足这些多样化…

LeetCode热题100|128.最长连续序列,283.移动零

128.最长连续序列 题目链接&#xff1a;128. 最长连续序列 - 力扣&#xff08;LeetCode&#xff09; 这里要求的一个乱序的数组里连续数字的个数&#xff0c;比如【100 &#xff0c;4&#xff0c;200&#xff0c;1&#xff0c;3&#xff0c;2】 里面连续的数字就是【1&#…

Unity-RectTransform设置UI width

不知道有没人需要这样的代码&#xff0c;就是.sizeDelta //不确定是不是英文翻译的原因&#xff0c;基本很难理解&#xff0c;sizeDeltaSize&#xff0c;//未必完全正确&#xff0c;但这么写好像总没错过 //image 在一个UnityEngine.UI.Image 的数组内foreach (var image in l…

GZCTF平台搭建及题目上传

前言 我用手里的Ubuntu虚拟机搭建的&#xff0c;大家根据自己的实际情况来吧 安装及部署 首先&#xff0c;你的虚拟机需要有Docker和Docker-Compose&#xff0c;前者可以看我之前的文章&#xff0c;另外一个可以输入下面的命令安装&#xff0c;注意先获取管理员权限&#xff…

记录Jmeter 利用BeanShell 脚本解析JSON字符串

下载org.json包(文档说明) #下载地址 https://www.json.org/ # github 地址 https://github.com/stleary/JSON-java # api 文档说明 https://resources.arcgis.com/en/help/arcobjects-java/api/arcobjects/com/esri/arcgis/server/json/JSONObject.htmlBeanShell脚本 import…

在Centos 7环境下安装MySQL

前言&#xff1a;在安装与卸载MySQL时&#xff0c;用户需切换为root&#xff0c;这样安装之后&#xff0c;普通用户也能够使用。 Tips:我们在刚开始学习时&#xff0c;尽量全部使用root进行&#xff0c;适应mysql语句&#xff0c;后面学了用户管理&#xff0c;就可以考虑新建普…

使用HTML5和CSS3实现3D旋转相册效果

使用HTML5和CSS3实现3D旋转相册效果 这里写目录标题 使用HTML5和CSS3实现3D旋转相册效果项目介绍技术栈核心功能实现思路1. HTML结构2. CSS样式解析2.1 基础样式设置2.2 3D效果核心样式2.3 卡片样式 3. JavaScript交互实现3.1 旋转控制3.2 自动播放功能 技术要点总结项目亮点总…

CentOS 7下安装PostgreSQL 15

一、简介 PostgreSQL是一种特性非常齐全的自由软件的对象-关系型数据库管理系统&#xff08;ORDBMS&#xff09;&#xff0c;是以加州大学计算机系开发的POSTGRES&#xff0c;4.2版本为基础的对象关系型数据库管理系统。POSTGRES的许多领先概念只是在比较迟的时候才出现在商业…

pytorch构建线性回归模型

仅仅用于自己记录pytorch学习记录 线性回归模型 &#xff08;1&#xff09;准备数据集 数据&#xff1a;三个数据x[x1,x2,x3] y[y1,y2,y3] import torch #线性回归&#xff0c;我们使用三组数据&#xff0c;分别是&#xff08;1,2&#xff09;&#xff0c;&#xff08;2,4&a…

Pytorch学习笔记(十二)Learning PyTorch - NLP from Scratch

这篇博客瞄准的是 pytorch 官方教程中 Learning PyTorch 章节的 NLP from Scratch 部分。 官网链接&#xff1a;https://pytorch.org/tutorials/intermediate/nlp_from_scratch_index.html 完整网盘链接: https://pan.baidu.com/s/1L9PVZ-KRDGVER-AJnXOvlQ?pwdaa2m 提取码: …

mysql--socket报错

错误原因分析 MySQL 服务未运行&#xff08;最常见原因&#xff09; 错误中的 (2) 表示 “No such file or directory”&#xff0c;即 /tmp/mysql.sock 不存在这通常意味着 MySQL 服务器根本没有启动 socket 文件路径不匹配 客户端尝试连接 /tmp/mysql.sock但 MySQL 服务器可…

进军场景智能体,云迹机器人又快了一步

&#xff08;图片来源&#xff1a;Pixels&#xff09; 2025年&#xff0c;AI和机器人行业都发生了巨大改变。 数科星球原创 作者丨苑晶 编辑丨大兔 2025年&#xff0c;酒店行业正掀起一股批量采购具备AI功能的软硬一体解决方案的热潮。 在DeepSeek、Manus等国产AI软件的推动…

WPS宏开发手册——JSA语法练习

目录 系列文章3、JSA语法练习3.1、运算练习3.2、比较练习3.3、if else练习3.4、for 练习3.5、字符串、数组方法练习3.6、语义转编程练习题 系列文章 使用、工程、模块介绍 JSA语法 JSA语法练习题 第四篇EXCEL常用API&#xff0c;持续更新中… 3、JSA语法练习 3.1…

ENSP学习day11

NAT地址转换&#xff08;二&#xff09;NAPT与easy ip 一&#xff1a;NAPT是Network Address Port Translation的缩写&#xff0c;也称为PAT&#xff08;Port Address Translation&#xff09;。NAPT是一种网络转换技术&#xff0c;用于在私有网络和公共网络之间进行地址转换以…

当Kafka化身抽水马桶:论组件并发提升与系统可用性的量子纠缠关系

《当Kafka化身抽水马桶&#xff1a;论组件并发提升与系统可用性的量子纠缠关系》 引言&#xff1a;一场OOM引发的血案 某个月黑风高的夜晚&#xff0c;监控系统突然发出刺耳的警报——我们的数据发现流水线集体扑街。事后复盘发现&#xff1a;Kafka集群、Gateway、Discovery服…

Web纯前端实现在线打开编辑保存PPT幻灯片

很多项目中有时会需要在线打开PPT并编辑保存到服务器。猿大师办公助手可以完美调用本地office在线打开ppt文件&#xff0c;跟本地打开效果一样。还可以在线打开word、excel、pdf等文件&#xff0c;支持本机OFFICE完整嵌入模式&#xff0c;本机OFFICE所有功能基本都可以在网页上…