C++自研3D教程OPENGL版本---动态批处理的基本实现

又开始找工作了,借机休息出去旅行两个月,顺便利用这段时间整理下以前写的东西。
以下是一个简单的动态批处理实现:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>// 顶点结构体
struct Vertex {float x, y, z; // 位置float r, g, b; // 颜色
};// 动态批处理类
class DynamicBatch {
public:DynamicBatch() {// 初始化 VAO 和 VBOglGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);// 设置顶点属性指针glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, x));glEnableVertexAttribArray(0);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, r));glEnableVertexAttribArray(1);glBindVertexArray(0);}~DynamicBatch() {glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);}// 添加顶点数据void AddVertex(const Vertex& vertex) {vertices.push_back(vertex);}// 更新顶点缓冲区void UpdateBuffer() {glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_DYNAMIC_DRAW);}// 渲染批处理void Render() {glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, vertices.size());glBindVertexArray(0);}// 清空顶点数据void Clear() {vertices.clear();}private:GLuint VAO, VBO; // 顶点数组对象和顶点缓冲区对象std::vector<Vertex> vertices; // 顶点数据
};

// 顶点着色器

const char* vertexShaderSource = R"(
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;
out vec3 ourColor;
void main() {gl_Position = vec4(aPos, 1.0);ourColor = aColor;
}
)";// 片段着色器
const char* fragmentShaderSource = R"(
#version 330 core
in vec3 ourColor;
out vec4 FragColor;
void main() {FragColor = vec4(ourColor, 1.0);
}
)";
// 编译着色器
GLuint CompileShader(GLenum type, const char* source) {GLuint shader = glCreateShader(type);glShaderSource(shader, 1, &source, nullptr);glCompileShader(shader);GLint success;glGetShaderiv(shader, GL_COMPILE_STATUS, &success);if (!success) {char infoLog[512];glGetShaderInfoLog(shader, 512, nullptr, infoLog);std::cerr << "Shader compilation failed: " << infoLog << std::endl;}return shader;
}// 链接着色器程序
GLuint CreateShaderProgram(const char* vertexSource, const char* fragmentSource) {GLuint vertexShader = CompileShader(GL_VERTEX_SHADER, vertexSource);GLuint fragmentShader = CompileShader(GL_FRAGMENT_SHADER, fragmentSource);GLuint shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);GLint success;glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);if (!success) {char infoLog[512];glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);std::cerr << "Shader program linking failed: " << infoLog << std::endl;}glDeleteShader(vertexShader);glDeleteShader(fragmentShader);return shaderProgram;
}int main() {// 初始化 GLFWif (!glfwInit()) {std::cerr << "Failed to initialize GLFW" << std::endl;return -1;}// 创建窗口GLFWwindow* window = glfwCreateWindow(800, 600, "Dynamic Batching Example", nullptr, nullptr);if (!window) {std::cerr << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);// 初始化 GLEWif (glewInit() != GLEW_OK) {std::cerr << "Failed to initialize GLEW" << std::endl;return -1;}// 创建着色器程序GLuint shaderProgram = CreateShaderProgram(vertexShaderSource, fragmentShaderSource);// 创建动态批处理对象DynamicBatch batch;// 主循环while (!glfwWindowShouldClose(window)) {glClear(GL_COLOR_BUFFER_BIT);// 添加顶点数据batch.Clear();batch.AddVertex({-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f});batch.AddVertex({0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f});batch.AddVertex({0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f});// 更新缓冲区并渲染batch.UpdateBuffer();glUseProgram(shaderProgram);batch.Render();// 交换缓冲区glfwSwapBuffers(window);glfwPollEvents();}// 清理glDeleteProgram(shaderProgram);glfwTerminate();return 0;
}

代码说明
DynamicBatch 类:

负责管理顶点数据、更新顶点缓冲区和渲染。使用 std::vector 存储动态顶点数据。
通过 glBufferData 将顶点数据上传到 GPU。
顶点和片段着色器:简单的着色器,用于渲染带颜色的三角形。
主循环:每一帧清空批处理数据,添加新的顶点数据,更新缓冲区并渲染。
动态更新:使用 GL_DYNAMIC_DRAW 标志更新顶点缓冲区,适用于频繁变化的顶点数据。

运行结果
运行程序后,你会看到一个彩色的三角形。每一帧都会动态更新顶点数据并渲染。

优化建议
减少内存分配:
如果顶点数据频繁变化,可以预先分配足够的内存,避免频繁调用 glBufferData。
使用实例化渲染:
如果需要渲染大量相同对象,可以使用实例化渲染(Instanced Rendering)进一步优化性能。
多线程更新:
在多线程环境中,可以将顶点数据的更新和渲染分离到不同的线程中。
通过动态批处理,你可以有效地减少绘制调用,提高渲染性能,特别是在需要渲染大量小对象的场景中。

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

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

相关文章

汽车智能座舱的技术演进与用户体验重构 —— 基于多模态交互与 AI 融合的范式创新

摘要&#xff1a; 汽车智能座舱作为人 - 车 - 环境交互的核心载体&#xff0c;正经历从功能驱动到体验驱动的范式变革。本文通过技术解构与用户行为分析&#xff0c;深入揭示智能座舱在异构计算、多模态感知、服务生态等维度的创新路径。研究表明&#xff0c;智能座舱的竞争焦…

SpringBoot3整合Swagger3时出现Type javax.servlet.http.HttpServletRequest not present错误

目录 错误详情 错误原因 解决方法 引入依赖 修改配置信息 创建文件 访问 错误详情 错误原因 SpringBoot3和Swagger3版本不匹配 解决方法 使用springdoc替代springfox&#xff0c;具体步骤如下&#xff1a; 引入依赖 在pom.xml文件中添加如下依赖&#xff1a; <…

ChatGPT提问技巧:行业热门应用提示词案例-文案写作

ChatGPT 作为强大的 AI 语言模型&#xff0c;已经成为文案写作的得力助手。但要让它写出真正符合你需求的文案&#xff0c;关键在于如何与它“沟通”&#xff0c;也就是如何设计提示词&#xff08;Prompt&#xff09;。以下是一些实用的提示词案例&#xff0c;帮助你解锁 ChatG…

mysql的cpu使用率100%问题排查

背景 线上mysql服务器经常性出现cpu使用率100%的告警&#xff0c; 因此整理一下排查该问题的常规流程。 1. 确认CPU占用来源 检查系统进程 使用 top 或 htop 命令&#xff0c;确认是否是 mysqld 进程导致CPU满载&#xff1a;top -c -p $(pgrep mysqld)2. 实时分析MySQL活动 …

使用jmeter进行压力测试

使用jmeter进行压力测试 jmeter安装 官网安装包下载&#xff0c;选择二进制文件&#xff0c;解压。 tar -xzvf apache-jmeter-x.tgz依赖jdk安装。 yum install java-1.8.0-openjdk环境变量配置&#xff0c;修改/etc/profile文件&#xff0c;添加以下内容。 export JMETER/…

【蓝桥杯嵌入式】6_定时器输入捕获

全部代码网盘自取 链接&#xff1a;https://pan.baidu.com/s/1PX2NCQxnADxYBQx5CsOgPA?pwd3ii2 提取码&#xff1a;3ii2 这是两个信号发生器&#xff0c;可以通过调节板上的两个电位器R39和R40调节输出频率。 将PB4、PA15选择ch1&#xff0c;两个信号发生器只能选择TIM3和TIM…

详解SQLAlchemy的函数relationship

在 SQLAlchemy 中&#xff0c;relationship 是一个非常重要的函数&#xff0c;用于定义模型之间的关系。它用于在 ORM 层面上表示数据库表之间的关联关系&#xff08;如 1 对 1、1 对多和多对多&#xff09;。relationship 的主要作用是提供一个高级接口&#xff0c;用于在模型…

iOS 音频录制、播放与格式转换

iOS 音频录制、播放与格式转换:基于 AVFoundation 和 FFmpegKit 的实现 在 iOS 开发中,音频处理是一个非常常见的需求,比如录音、播放音频、音频格式转换等。本文将详细解读一段基于 AVFoundation 和 FFmpegKit 的代码,展示如何实现音频录制、播放以及 PCM 和 AAC 格式之间…

数据结构与算法(test1)

一、树和二叉树 1. 看图&#xff0c;完成以下填空 (1).树的度为________。 (2).树中结点的最大层次&#xff0c;称为树的_____或树的______&#xff0c;值是______。 (3).结点A和B的度分别为________ 和 ________。 (4).结点A是结点B的________。 (5).结点B是结点A的________…

新版AndroidStudio 修改 jdk版本

一、问题 之前&#xff0c;在安卓项目中配置JDK和Gradle的过程非常直观&#xff0c;只需要进入Android Studio的File菜单中的Project Structure即可进行设置&#xff0c;十分方便。 如下图可以在这修改JDK: 但是升级AndroidStudio之后&#xff0c;比如我升级到了Android Stu…

cursor 开发java项目教程简单上手

1.官网下载 Cursor - The AI Code Editor 下载完后注册账号&#xff0c;可以使用无限邮的方式 注册完之后 设置中文 可以选择设置为中文 Ctrl Shift X 进入设置页面输入chinese 然后重启 更改jdk跟maven仓库设置 ctrlshiftp 打开输入框后输入json&#xff0c;把下面代码…

安装和使用 Ollama(实验环境windows)

下载安装 下载 https://ollama.com/download/windows 安装 Windows 安装 如果直接双击 OllamaSetup.exe 安装&#xff0c;默认会安装到 C 盘&#xff0c;如果需要指定安装目录&#xff0c;需要通过命令行指定安装地址&#xff0c;如下&#xff1a; # 切换到安装目录 C:\Use…

LQB(0)-python-基础知识

一、Python开发环境与基础知识 python解释器&#xff1a;用于解释python代码 方式&#xff1a; 1.直接安装python解释器 2.安装Anaconda管理python环境 python开发环境&#xff1a;用于编写python代码 1.vscode 2.pycharm # 3.安装Anaconda后可以使用网页版的jupyter n…

C# 中记录(Record)详解

从C#9.0开始&#xff0c;我们有了一个有趣的语法糖&#xff1a;记录(record)   为什么提供记录&#xff1f; 开发过程中&#xff0c;我们往往会创建一些简单的实体&#xff0c;它们仅仅拥有一些简单的属性&#xff0c;可能还有几个简单的方法&#xff0c;比如DTO等等&#xf…

使用 CSS 实现透明效果

在 CSS 中&#xff0c;实现透明效果有几种方法&#xff0c;具体使用哪种方法取决于具体需求。以下是一些常见的方法&#xff1a; 使用 opacity 属性&#xff1a; opacity 属性可以设置整个元素的透明度&#xff0c;包括其所有的子元素。 .transparent { opacity: 0.5; /* 0 表…

C语言:函数栈帧的创建和销毁

目录 1.什么是函数栈帧2.理解函数栈帧能解决什么问题3.函数栈帧的创建和销毁的过程解析3.1 什么是栈3.2 认识相关寄存器和汇编指令3.3 解析函数栈帧的创建和销毁过程3.3.1 准备环境3.3.2 函数的调用堆栈3.3.3 转到反汇编3.3.4 函数栈帧的创建和销毁 1.什么是函数栈帧 在写C语言…

25/2/6 <机器人基础> 运动学中各连杆的变换矩阵求法

变换矩阵 机器人通常包含多个关节和连杆&#xff0c;每个关节和连杆都有自己的局部坐标系。变换矩阵能够将一个点或向量从一个坐标系转换到另一个坐标系&#xff0c;从而实现对机器人各个部件位置和姿态的统一描述 变换矩阵能够将复杂的运动分解为旋转和平移的组合。通过矩阵乘…

AllData数据中台核心菜单十二:数据同步平台

&#x1f525;&#x1f525; AllData大数据产品是可定义数据中台&#xff0c;以数据平台为底座&#xff0c;以数据中台为桥梁&#xff0c;以机器学习平台为中层框架&#xff0c;以大模型应用为上游产品&#xff0c;提供全链路数字化解决方案。 ✨奥零数据科技官网&#xff1a;…

【FPGA】 MIPS 12条整数指令 【3】

实现乘除 修改框架 EX&#xff1a;实现带符号乘除法和无符号乘除法 HiLo寄存器&#xff1a;用于存放乘法和除法的运算结果。Hi、Lo为32bit寄存器。电路描述与实现RegFile思想一致 仿真 代码 DataMem.v include "define.v"; module DataMem(input wire clk,input…

文件基础IO

理解"文件" 1-1 狭义理解 文件在磁盘里磁盘是永久性存储介质&#xff0c;因此文件在磁盘上的存储是永久性的磁盘是外设&#xff08;即是输出设备也是输入设备&#xff09;磁盘上的文件 本质是对文件的所有操作&#xff0c;都是对外设的输入和输出简称IO 1-2 广义理…