FramBuffer离屏渲染上屏的简易操作

以下是一个完整的OpenGL程序示例,演示了如何进行离屏渲染并将渲染结果显示在屏幕上。

并非在帧缓冲绑定的纹理上。

这个示例包括了创建窗口、初始化OpenGL、编译着色器、设置帧缓冲、绘制场景、以及交换缓冲等步骤。

代码注释详细解释了每个步骤的作用和原理。

教程:

下面详细解释了程序中的各个部分以及涉及的OpenGL概念:

  1. 初始化窗口和OpenGL上下文: 通过GLFW库创建一个窗口,并设置OpenGL版本及配置。

  2. 初始化GLEW: 初始化GLEW库以访问OpenGL函数。

  3. 设置顶点数据和顶点着色器: 创建一个三角形的顶点数据,并创建相应的顶点缓冲对象和顶点数组对象。编写顶点着色器来处理顶点数据的传递。

  4. 编译着色器程序: 编译顶点和片段着色器,并将它们链接到一个着色器程序中。

  5. 设置帧缓冲: 创建一个帧缓冲对象,并将一个纹理附件附加到帧缓冲中。这个纹理附件用来保存离屏渲染的结果。

  6. 渲染循环: 在每次循环中,清除颜色缓冲区,进行离屏渲染,然后将渲染结果显示在屏幕上。在离屏渲染时,将帧缓冲对象绑定为当前渲染目标,并在上屏渲染时将其绑定回默认的帧缓冲对象。

  7. 释放资源: 释放所有创建的OpenGL对象和程序。

通过理解这个示例程序,你可以学到如何使用帧缓冲对象进行离屏渲染,以及如何将离屏渲染的结果显示在屏幕上。

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>void framebuffer_size_callback(GLFWwindow* window, int width, int height) {glViewport(0, 0, width, height);
}int main() {// 初始化GLFWglfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);// 创建窗口GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr);if (window == nullptr) {std::cerr << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);// 初始化GLEWglewExperimental = GL_TRUE;if (glewInit() != GLEW_OK) {std::cerr << "Failed to initialize GLEW" << std::endl;return -1;}// 设置顶点数据和顶点着色器float vertices[] = {-0.5f, -0.5f, 0.0f,  // 左下角0.5f, -0.5f, 0.0f,  // 右下角0.0f,  0.5f, 0.0f   // 顶部中心};unsigned int VBO, VAO;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);// 绑定VAOglBindVertexArray(VAO);// 绑定VBO并设置顶点数据glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// 设置顶点属性指针glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);// 解绑VBO和VAOglBindBuffer(GL_ARRAY_BUFFER, 0);glBindVertexArray(0);// 编译着色器const char* vertexShaderSource = "#version 330 core\n""layout (location = 0) in vec3 aPos;\n""void main()\n""{\n""    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n""}\0";const char* fragmentShaderSource = "#version 330 core\n""out vec4 FragColor;\n""void main()\n""{\n""    FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n""}\n\0";// 顶点着色器unsigned int vertexShader;vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);glCompileShader(vertexShader);// 片段着色器unsigned int fragmentShader;fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);glCompileShader(fragmentShader);// 着色器程序unsigned int shaderProgram;shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);glDeleteShader(vertexShader);glDeleteShader(fragmentShader);// 设置离屏渲染帧缓冲unsigned int framebuffer;glGenFramebuffers(1, &framebuffer);glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);// 创建纹理附件unsigned int textureColorbuffer;glGenTextures(1, &textureColorbuffer);glBindTexture(GL_TEXTURE_2D, textureColorbuffer);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0);// 检查帧缓冲完整性if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)std::cerr << "Framebuffer is not complete!" << std::endl;// 渲染循环while (!glfwWindowShouldClose(window)) {glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);// 离屏渲染glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);glViewport(0, 0, 800, 600); // 设置视口大小为纹理大小glClear(GL_COLOR_BUFFER_BIT);// 使用着色器程序glUseProgram(shaderProgram);// 绘制三角形glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 3);// 上屏渲染glBindFramebuffer(GL_FRAMEBUFFER, 0);glViewport(0, 0, 800, 600); // 重置视口大小为屏幕大小glClear(GL_COLOR_BUFFER_BIT);// 使用另一个着色器程序或者直接绘制// 这里假设你有一个简单的绘制纹理的着色器程序和四边形glUseProgram(shaderProgram);glBindVertexArray(VAO);glBindTexture(GL_TEXTURE_2D, textureColorbuffer); // 使用离屏渲染的纹理glDrawArrays(GL_TRIANGLES, 0, 6);glfwSwapBuffers(window);glfwPollEvents();}// 释放资源glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteFramebuffers(1, &framebuffer);glDeleteTextures(1, &textureColorbuffer);glDeleteProgram(shaderProgram);// 终止 GLFWglfwTerminate();return 0;
}

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

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

相关文章

【MySQL学习】MySQL的慢查询日志和错误日志

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

鸿蒙OS开发实战:【自动化测试框架】使用指南

概述 为支撑HarmonyOS操作系统的自动化测试活动开展&#xff0c;我们提供了支持JS/TS语言的单元及UI测试框架&#xff0c;支持开发者针对应用接口进行单元测试&#xff0c;并且可基于UI操作进行UI自动化脚本的编写。 本指南重点介绍自动化测试框架的主要功能&#xff0c;同时…

算法刷题记录 Day36

算法刷题记录 Day36 Date: 2024.04.02 lc 416. 分割等和子集 //2. 一维数组 class Solution { public:bool canPartition(vector<int>& nums) {// 将问题转化为从数组中任意取数&#xff0c;使得容量为数组总和一半的背包内的价值尽可能大。// dp[j]表示容积为j的…

python 会员管理系统

问题介绍 综合案例&#xff1a;会员管理系统实现-V2版&#xff08;不可超前使用面向对象&#xff09; 利用函数&#xff0c;编写会员管理系统&#xff0c;实现进入系统显示系统功能界面&#xff0c;选择添加、删除、修改&#xff0c;查询、显示所有会员信息以及退出系统等响应…

【Spring Security】2.实现最简单的身份验证

文章目录 一、找到官网的身份认证&#xff08;authentication&#xff09;示例代码二、实现最简单的身份验证1、创建Spring Boot项目2、创建IndexController3、创建index.html4、启动项目测试Controller 三、{/logout}的作用四、页面样式无法加载的问题 一、找到官网的身份认证…

二建考试搜题软件哪个好?分享8个可以搜答案的软件 #知识分享#笔记#学习方法

积极参加社团活动和实践项目&#xff0c;可以帮助大学生拓宽人脉圈和锻炼实际操作能力。 1.白鸽搜题 这是个微信公众号 多语言查询支持&#xff0c;满足国际用户需求。全球通用&#xff0c;无障碍搜题。 下方附上一些测试的试题及答案 1、等渗性脱水时&#xff0c;体液变化…

禅道任务如何删除

背景 利用禅道任务&#xff0c;来统计项目投入工时&#xff0c;但由于录入错误&#xff0c;导致工时写错&#xff0c;想修改但工时只会增加。 问题复现 先复现一下问题&#xff1a; 举例&#xff1a;2/6号工时之前由于操作失误&#xff0c;写成8小时&#xff0c;且任务状态为…

React - 你知道useffect函数内如何模拟生命周期吗

难度级别:中级及以上 提问概率:65% 很多前端开发人员习惯了Vue或者React的组件式开发,熟知组件的周期过程包含初始化、挂载完成、修改和卸载等阶段。但是当使用Hooks做业务开发的时候,看见一个个useEffect函数,却显得有些迷茫,因为在us…

DFS:深搜+回溯+剪枝解决排列、子集问题

创作不易&#xff0c;感谢三连支持&#xff01;&#xff01; 一、全排列I . - 力扣&#xff08;LeetCode&#xff09; class Solution { public://全局变量vector<vector<int>> ret;vector<int> path;bool check[6];vector<vector<int>> perm…

Hololens2远程音视频通话与AR远程空间标注,基于OpenXR+MRTK3+WebRTC实现

Hololens2远程音视频通话与AR远程空间标注 使用Unity2021.3.21版本开发&#xff0c;基于OpenXRMRTK3.0WebRTC实现。 &#xff08;1&#xff09;通过视频获取视频帧的矩阵的方法可以参考&#xff1a;https://learn.microsoft.com/zh-cn/windows/mixed-reality/develop/advanced…

异步和同步

异步和同步都是指对于数据的传输和处理的方式。在处理JSON&#xff08;JavaScript Object Notation&#xff09;数据时&#xff0c;异步和同步的方式也是可以用来读取和解析JSON数据的。 异步JSON是指使用异步的方式获取和处理JSON数据。异步操作允许程序在等待服务器响应的同…

(学习日记)2024.04.09:UCOSIII第三十七节:事件函数接口

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

Python入门的60个基础练习(一)

01-Hello World python的语法逻辑完全靠缩进&#xff0c;建议缩进4个空格。如果是顶级代码&#xff0c;那么必须顶格书写&#xff0c;哪怕只有一个空格也会有语法错误。下面示例中&#xff0c;满足if条件要输出两行内容&#xff0c;这两行内容必须都缩进&#xff0c;而且具有相…

七燕论文可靠吗 #经验分享#经验分享

七燕论文是一个非常好用的论文写作工具&#xff0c;它不仅可以帮助学生提高写作效率&#xff0c;还能帮助他们避免抄袭和提高论文质量。七燕论文的查重降重功能非常靠谱&#xff0c;能够帮助用户检测论文中的重复内容&#xff0c;并提供相应的修改建议&#xff0c;确保论文的原…

设计模式 -- 发布订阅模式

发布订阅模式&#xff1a; 订阅者把自己想订阅的事件注册到调度中心&#xff0c;当发布者发布该事件到调度中心&#xff0c;也就是该事件触发时&#xff0c;由调度者统一调度订阅者注册到调度中心的处理代码。 在javaScript 中我们一般使用事件模型来代替传统的发布订阅模式。 …

CSS设置网页颜色

目录 前言&#xff1a; 1.颜色名字&#xff1a; 2.十六进制码&#xff1a; 3.RGB&#xff1a; 4.RGBA&#xff1a; 5.HSL&#xff1a; 1.hue&#xff1a; 2.saturation&#xff1a; 3.lightness&#xff1a; 6.HSLA&#xff1a; 前言&#xff1a; 我们在电脑显示器&…

Windows 关闭占用指定端口的进程

以下示例以443端口为例&#xff0c;具体哪个端口视自己情况而定 输入命令 # 输出的最后一列就是进程号pid netstat -ano | findstr "443" 找出占用443端口的进程号(pid)&#xff08;第二列是你本机的应用占用的端口&#xff0c;看第二列就行&#xff09;如下图&am…

4 万字 102 道Java经典面试题总结(2024修订版)- 多线程篇

&#x1f345; 作者简介&#xff1a;哪吒&#xff0c;CSDN2021博客之星亚军&#x1f3c6;、新星计划导师✌、博客专家&#x1f4aa; &#x1f345; 哪吒多年工作总结&#xff1a;Java学习路线总结&#xff0c;搬砖工逆袭Java架构师 &#x1f345; 技术交流&#xff1a;定期更新…

前端js获取当hppt协议

在JavaScript中&#xff0c;你可以通过window.location对象来获取当前页面的URL&#xff0c;并从中解析出协议部分&#xff08;例如&#xff0c;http或https&#xff09;。下面是一个简单的示例&#xff1a; // 获取当前页面的完整URL var currentURL window.location.href…

关于GNSS硬件延迟初步学习,电离层提取

1、卫星端偏差分为频间和频内偏差&#xff08;inter or intra frequency&#xff09;&#xff0c;下面以GPS的C1C和C2W组合为例分析对PPP解算的影响&#xff1a; 如果不改正卫星端的inter-frequency&#xff08;即&#xff1a;C1C-C1W&#xff09;偏差&#xff08;因为每颗卫星…