当前位置: 首页 > ai >正文

Horse3D引擎研发笔记(四):在QtOpenGL下仿three.js,封装EBO绘制四边形

Horse3D引擎研发笔记(一):从使用Qt的OpenGL库绘制三角形开始
Horse3D引擎研发笔记(二):基于QtOpenGL使用仿Three.js的BufferAttribute结构重构三角形绘制
Horse3D引擎研发笔记(三):使用QtOpenGL的Shader编程绘制彩色三角形
Horse3D引擎研发笔记(四):在QtOpenGL下仿three.js,封装EBO绘制四边形

在三维图形开发中,效率是至关重要的。今天,我们将深入探讨如何在QtOpenGL框架下实现高效的图形绘制,特别是通过封装EBO(Element Buffer Object)来绘制四边形。这篇文章将详细介绍EBO的优势、Horse3D引擎中的封装实现,以及如何通过EBO高效地绘制四边形。


一、EBO简介

EBO,全称Element Buffer Object,是OpenGL中用于存储索引数据的一种缓冲对象。它允许我们通过索引数组来引用顶点缓冲中的顶点,从而减少重复顶点的存储需求。EBO在现代图形渲染中被广泛使用,尤其是在需要高效绘制大量几何图形的场景中。


二、EBO的优势

  1. 减少顶点重复:通过索引数组,EBO可以显著减少顶点数据的重复存储。例如,一个四边形由两个三角形组成,共6个顶点。如果没有EBO,我们需要存储6个顶点;而使用EBO,我们只需要存储4个顶点,索引数组告诉OpenGL如何引用这些顶点。

  2. 提高渲染效率:EBO减少了GPU需要处理的顶点数量,从而提高了渲染性能。这对于大规模场景的渲染尤为重要。

  3. 降低带宽消耗:EBO的数据通常驻留在GPU内存中,减少了CPU和GPU之间的数据传输,进一步提升了性能。


三、Horse3D引擎中的EBO封装

Horse3D是一款基于Qt和OpenGL开发的三维渲染引擎,旨在提供高效的图形渲染能力。为了更好地支持高效的图形绘制,我们在Horse3D中封装了EBO的功能。

1. EBO的封装类

在Horse3D中,我们定义了一个IndicesAttribute类,用于管理EBO的创建和绑定。

class IndicesAttribute {
private:std::vector<unsigned int> m_indices;GLuint m_ebo;public:IndicesAttribute(const std::vector<unsigned int>& indices): m_indices(indices) {}void createOpenGLState(IScreen* screen) {screen->glGenBuffers(1, &m_ebo);screen->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo);screen->glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof(unsigned int), m_indices.data(), GL_STATIC_DRAW);}
};
  • 构造函数:接收一个索引数组,并将其存储在m_indices中。
  • createOpenGLState方法:用于创建EBO并绑定索引数据。该方法通过glGenBuffers生成EBO对象,通过glBindBuffer绑定EBO,并通过glBufferData将索引数据上传到GPU。

2. EBO的使用

在Horse3D中,我们通过以下步骤使用EBO:

  1. 创建顶点数据和索引数据。
  2. 使用BufferAttribute类管理顶点缓冲对象(VBO)。
  3. 使用IndicesAttribute类管理元素缓冲对象(EBO)。
  4. 在渲染循环中绑定VBO和EBO,并调用glDrawElements进行绘制。

四、绘制四边形的实现

接下来,我们将详细讲解如何在Horse3D中通过EBO绘制一个四边形。

1. 顶点数据与索引数据

我们定义了一个四边形的顶点数据和索引数据:

const std::vector<GLfloat> vertices = {-0.5f, 0.5f, 0.0f,  // 左上角-0.5f, -0.5f, 0.0f, // 左下角0.5f, -0.5f, 0.0f,  // 右下角0.5f, 0.5f, 0.0f    // 右上角
};const std::vector<unsigned int> indices = {0, 1, 3, // 第一个三角形1, 2, 3  // 第二个三角形
};
  • 顶点数据:定义了四边形的四个顶点坐标。
  • 索引数据:定义了两个三角形的索引数组,每个三角形由3个顶点索引组成。

2. 初始化与绑定

在初始化阶段,我们创建了顶点缓冲对象(VBO)和元素缓冲对象(EBO),并将它们绑定到顶点数组对象(VAO)中。

glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);bufferAttribute->createOpenGLState(this); // 创建并绑定VBO
indicesAttribute->createOpenGLState(this); // 创建并绑定EBO

3. 着色器程序

我们定义了一个简单的着色器程序,用于为四边形着色。

shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex,
R"(#version 450 corelayout (location = 0) in vec3 aPos;void main(){gl_Position = vec4(aPos, 1.0);})");shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment,
R"(#version 450 coreout vec4 FragColor;void main(){FragColor = vec4(1.0, 0.5, 0.0, 1.0); // 橙色})");
shaderProgram->link();
  • 顶点着色器:将顶点位置传递给片段着色器。
  • 片段着色器:为每个像素设置颜色(橙色)。

4. 绘制过程

paintGL方法中,我们执行以下步骤:

  1. 清除颜色缓冲。
  2. 绑定着色器程序。
  3. 绑定顶点数组对象(VAO)。
  4. 调用glDrawElements进行绘制。
glClear(GL_COLOR_BUFFER_BIT);
shaderProgram->bind();
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
shaderProgram->release();

glDrawElements :使用EBO中的索引数据绘制三角形。GL_TRIANGLES表示绘制模式为三角形,6表示索引数量,GL_UNSIGNED_INT表示索引类型,0表示索引数据的起始位置。


五、Horse3D引擎项目介绍

Horse3D是一款基于Qt和OpenGL开发的三维渲染引擎,旨在提供高效的图形渲染能力。与three.js和Unity类似,Horse3D通过封装底层OpenGL功能,为开发者提供了一组简洁易用的API。

项目目标

  1. 高效渲染:通过优化OpenGL调用和数据管理,提供高性能的图形渲染能力。
  2. API友好:借鉴three.js和Unity的API设计,提供简洁直观的接口。
  3. 跨平台支持:基于Qt的跨平台能力,支持Windows、Linux和macOS等平台。

项目地址

感兴趣的朋友可以访问我们的Gitee仓库,查看更多细节和源代码:

https://gitee.com/shendeyidi/horse_x


六、总结

通过封装EBO,我们成功地在Horse3D引擎中实现了高效的四边形绘制。这一实现不仅减少了顶点数据的重复存储,还提高了渲染性能。未来,我们将继续优化Horse3D引擎的功能,为开发者提供更强大的三维图形渲染能力。

http://www.xdnf.cn/news/17544.html

相关文章:

  • HarmonyOS 开发入门 第一章
  • AI驱动的智能编码革命:从Copilot到全流程开发自动化
  • LAMPLNMP 最佳实践
  • 基于FPGA的热电偶测温数据采集系统,替代NI的产品(二)总体设计方案
  • Python Day27 HTML 核心知识笔记及例题分析
  • 【Kafka系列】第三篇| 在哪些场景下会选择使用 Kafka?
  • 自建Web应用防火墙(WAF)
  • React 19 通用 ECharts 组件
  • uni-app app端安卓和ios如何申请麦克风权限,唤起提醒弹框
  • 什么是网络准入控制系统?解析一款网络准入的详细功能
  • FPGA+护理:跨学科发展的探索(二)
  • 最短路问题从入门到负权最短路
  • 【算法专题训练】11、字符串中的变位词
  • “鱼书”深度学习进阶笔记(3)第四章
  • MLAG双活网络妙招:BGP + 静态VRRP实现智能负载均衡
  • (一)vscode搭建espidf环境
  • Linux线程——线程控制及理解
  • LLM大语言模型初步学习认识
  • day23|前端学习三件套
  • 集成电路学习:什么是URDF Parser统一机器人描述格式解析器
  • 10种经典学习方法的指令化应用
  • 动态创建可变对象:Python类工厂函数深度解析
  • 【k近邻】Kd树的构造与最近邻搜索算法
  • 用户虚拟地址空间布局
  • JVM管理数据的方式
  • 剧本杀小程序系统开发:推动行业数字化转型新动力
  • Linux中DNS系统搭建与配置指南(配实验步骤与注释)
  • 在 .NET Core 5.0 中启用 Gzip 压缩 Response
  • Tricentis Tosca:现代软件测试的自动化利器
  • 企业级 IT 运维服务平台数据备份方案:基于 rsync 的自动化实现