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,一经查实,立即删除!

相关文章

61. Linux内核启动流程简介

一、vmlinux.lds简介 从arch/arm/kernel/vmlinux.lds分析Linux内核第一行启动代码。找到ENTRY(stext) 入口函数是stext&#xff0c;image和zImage是经过压缩的&#xff0c;Linux内核会先进行解压缩&#xff0c;解压缩完成以后就要运行Linux内核。要求&#xff1a; 1、MMU关闭 …

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

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

使用 Let‘s Encrypt 和 OpenResty 实现域名转发与 SSL 配置

在搭建网站或服务时&#xff0c;确保域名的安全性和正确的流量转发是非常重要的。本文将介绍如何使用 Let’s Encrypt 获取免费的 SSL 证书&#xff0c;并将其配置到 OpenResty 中&#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…

供排水水工公司开展企业获得用水营商环境满意度调查

为了持续提升企业的供水服务品质&#xff0c;进一步优化当地的营商环境&#xff0c;深圳市供排水公司水工公司紧密结合其实际工作情况&#xff0c;特别委托民安智库开展了2023年度优化营商环境调查专项工作。该项目的核心目的是深入了解并评估市各类获得用水企业的用水环境满意…

【Elasticsearch】分桶聚合功能概述

这些聚合功能可以根据它们的作用和应用场景分为几大类&#xff0c;以下是分类后的结果&#xff1a; 1.基础聚合&#xff08;Basic Aggregations&#xff09; • Terms&#xff08;字段聚合&#xff09; 根据字段值对数据进行分组并统计。 例子&#xff1a;按产品类别统计销…

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

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

人工智能赋能企业系统架构设计:以ERP与CRM系统为例

一、引言 1.1 研究背景与意义 在数字化时代&#xff0c;信息技术飞速发展&#xff0c;人工智能&#xff08;Artificial Intelligence, AI&#xff09;作为一项具有变革性的技术&#xff0c;正深刻地影响着各个领域。近年来&#xff0c;AI 在技术上取得了显著突破&#xff0c;…

使用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/…

深入理解流(Streams)—— 声明式数据处理的艺术

1. 引言 大家好&#xff01;欢迎来到本系列博客的第三篇。在前两篇文章中&#xff0c;我们已经领略了 Java 8 中 行为参数化 和 Lambda 表达式 的魅力。 在第 1 章 Java行为参数化&#xff1a;从啰嗦到简洁的代码进化中&#xff0c;我们了解到如何通过将行为&#xff08;代码…

【Linux】之【Get√】nmcli device wifi list 与 wpa_cli scan 和 wpa_cli scan_result 区别

nmcli device wifi list 是 NetworkManager 的命令行工具 nmcli 的一部分&#xff0c;它用于列出当前可用的无线网络。它的作用和 wpa_cli 的扫描功能类似&#xff0c;但有一些不同点。 1. nmcli device wifi list 功能&#xff1a; nmcli device wifi list 命令用于显示当前…

【蓝桥杯嵌入式】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;用于在模型…

分桶函数的使用

除了 NTILE 函数&#xff0c;SQL 中还有其他一些与 分桶&#xff08;bucketization&#xff09;相关的函数&#xff0c;虽然它们的实现方式不同&#xff0c;但都涉及将数据分成多个区间或组。以下是一些常用的分桶函数&#xff1a; 1. CASE 语句 虽然 CASE 不是开窗函数&…

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…

litemall,又一个小商场系统

litemall Spring Boot后端 Vue管理员前端 微信小程序用户前端 Vue用户移动端 代码地址&#xff1a;litemall: 又一个小商城。 litemall Spring Boot后端 Vue管理员前端 微信小程序用户前端 Vue用户移动端

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

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