OpenGL 使用FBO为渲染对象并从GPU取出存图的代码

#include "gl/glew.h"
#include "gl/glut.h"
#include <fstream>
#define isize 512
const char* vertexShaderSource = "#version 460 \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 460 \n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"   FragColor = vec4(0.0f, 1.0f, 1.0f, 1.0f);\n"
"}\n\0";void saveToBMP24(void* packBuffer, const std::string& img);
int main(int argc, char** argv)
{argc;argv;//初始化窗口以及渲染上下文//创建viewportint iViewportIndex = 0;float fv4Viewport[4] = {0.0f,0.0f,512.0f,512.0f};glViewportIndexedfv(iViewportIndex, fv4Viewport);//创建FBO绑定的纹理GLuint texName;glGenTextures(1, &texName);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, texName);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexImage2D(GL_TEXTURE_2D, GLint(0), GL_RGBA, isize, isize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);//创建FOBGLuint FramebufferName;glGenFramebuffers(1, &FramebufferName);glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texName, 0);//三角形的三个顶点数据float vertices[] = {-0.5f, -0.5f, 0.0f, // left  0.5f, -0.5f, 0.0f, // right 0.0f, 0.5f, 0.0f  // top   };//创建VAO VBO unsigned int VBO, VAO;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glBindVertexArray(VAO);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);//初始化program,shaderint vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);glCompileShader(vertexShader);int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);glCompileShader(fragmentShader);int shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);//清背景glClearColor(0.0f, 0.0f, 0.0f, 0.0f);glClear(GL_COLOR_BUFFER_BIT);//设置绘制buffer,数组形式设置GLuint a[] = { GL_COLOR_ATTACHMENT0 };glDrawBuffers(1, a);glUseProgram(shaderProgram);//绑定VAOglBindVertexArray(VAO);//绘制三角形glDrawArrays(GL_TRIANGLES, 0, 3);//备份int iOldPixelPackAlignment(1);glGetIntegerv(GL_PACK_ALIGNMENT, &iOldPixelPackAlignment);//设置新的对齐glPixelStorei(GL_PACK_ALIGNMENT, 1);//绑定fbo,读取数据glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferName);glReadBuffer(GL_COLOR_ATTACHMENT0);void* pImage = new char[isize * isize * 4];glReadPixels(0, 0, isize, isize,GL_RGBA, GL_UNSIGNED_BYTE, pImage);glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);//存图 bmp格式saveToBMP24(pImage, "/usr/sss1.bmp");return 0;
}void saveToBMP24(void* packBuffer, const std::string& img)
{using namespace std;//读入一个bmp格式文件,创建头用,todo:尺寸和位数对应fstream in("/usr/123.bmp", ios_base::in | ios_base::binary);if (!in){return;}char bmpHeader[54] = { 0 };in.read(bmpHeader, sizeof(bmpHeader));char* pBuffer = new char[isize * isize *3];in.read(pBuffer, isize * isize * 3);in.close();fstream out(img.c_str(), ios_base::out | ios_base::binary | ios_base::trunc);if (!out){in.close();delete[] pBuffer;return;}//RGB数据拷贝,A丢弃for (size_t i = 0; i < isize*isize; i++){int num = i * 4;int numI = i * 3;pBuffer[numI] = ((char*)packBuffer)[num + 2];pBuffer[numI+1] = ((char*)packBuffer)[num + 1];pBuffer[numI+2] = ((char*)packBuffer)[num ];}*((int*)&bmpHeader[0x12]) = isize;*((int*)&bmpHeader[0x16]) = isize;//bmp对齐int totals = (isize) * 3;while (totals % 4 != 0)++totals;totals = totals * (isize);out.write(bmpHeader, sizeof(bmpHeader));out.write(pBuffer, totals);out.close();delete[]pBuffer;
}

OpenGL:使用FBO为渲染对象并从GPU取出存图相关推荐

  1. OpenGL ES 多目标渲染(MRT)

    OpenGL ES 多目标渲染 OpenGL ES 多目标渲染 OpenGL ES 多目标渲染(MRT),即多重渲染目标,是 OpenGL ES 3.0 新特性,它允许应用程序一次渲染到多个缓冲区. ...

  2. OpenGL学习脚印: 帧缓冲对象(Frame Buffer Object)

    写在前面 一直以来,我们在使用OpenGL渲染时,最终的目的地是默认的帧缓冲区,实际上OpenGL也允许我们创建自定义的帧缓冲区.使用自定义的帧缓冲区,可以实现镜面,离屏渲染,以及很酷的后处理效果.本 ...

  3. 音视频开发之旅(38) -使用FBO实现渲染到纹理(Render to texture)

    目录 FBO基本知识 FBO实现渲染到纹理的流程 实践 遇到的问题 资料 收获 在之前的学习实践中我们把图片.视频.图形等渲染到屏幕时,采用的是直接屏幕上即默认的帧缓冲区,如果我们在渲染时不想直接渲染 ...

  4. OS X下使用OpenGL做离屏渲染

    本文为转载内容,原地址 有时,我们想通过GPU做一些视频.图像处理,而处理的结果不需要显示在显示器上,而是直接交给主存,这时候我们可以通过OpenGL的离屏渲染来实现. 由于我们不需要将渲染好的像素显 ...

  5. Android OpenGL ES 学习(十一) –渲染YUV视频以及视频抖音特效

    OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学 ...

  6. OpenGL使用FBO与PBO上行纹理 (YUYV)

      本文记录在OpenGL中使用 帧缓冲 (FBO)和像素缓冲(PBO)来上行视频帧数据(YUYV), 并最终渲染显示出来.在之前的文章中介绍了渲染 YUV420 和 YUYV 的流程,不过都是用的默 ...

  7. OpenGL/OpenGL ES入门:渲染YUV数据实践

    纹理:GPU中的一块数据结构,YUV数据先经过采样,转成rgb显示. 着色器代码,先通过compile编译成GPU能识别的机器语言,再交由GPU进行显示. shader着色器,texture纹理,Ut ...

  8. Android音视频学习系列(六) — 掌握视频基础知识并使用OpenGL ES 2.0渲染YUV数据

    系列文章 Android音视频学习系列(一) - JNI从入门到精通 Android音视频学习系列(二) - 交叉编译动态库.静态库的入门 Android音视频学习系列(三) - Shell脚本入门 ...

  9. openGL 入门 2--顶点数组对象 VAO 和 缓存对象 VBO

    用户输入的数据 以 顶点数组对象表示 Vertex Array Object,VAO void glGenVertexArrays(GLsizei n, GLuint *arrays); 返回 n个 ...

最新文章

  1. RK3288 GMAC整理
  2. 一起谈.NET技术,.NET并行(多核)编程系列之七 共享数据问题和解决概述
  3. [HOW TO]-官网拉取Trusty-TEE的代码
  4. 从 WordCount 到 MapReduce 计算模型
  5. 在Dll中创建对话框并调用
  6. 九、Spark模块和安装
  7. OpenCV图像旋转,指定填充背景颜色边界颜色
  8. 数据结构(单链表的相关操作)
  9. 河流为什么是弯曲的?
  10. python爬虫requests源码链家_python爬虫——爬取链家房价信息(未完待续)
  11. python安装xlrd和xlwt及应用
  12. JS数据结构学习之排序
  13. 5u以太网用交换机连接电脑_干货丨如何用自己的电脑直接连接NUS打印机
  14. GRE over IPSec 隧道配置案例
  15. Java基础:接口多态的综合案例 —— 笔记本电脑
  16. txt文档下载另存为解决
  17. FasterRCNN
  18. AngularJs中input uib-typeahead 搜索加自动补全 注意点
  19. 计算四则表达式(中缀式转后缀式,然后计算结果)
  20. 【java基础】同比和环比

热门文章

  1. ASP.NET MVC 3: Razor视图引擎中 @: 和text 语法【转载】
  2. 慢速HTTP拒绝服务攻击
  3. 解决vscode之前好好的能连接上linux服务器,后来报错,窗口出现故障
  4. Mysql 日期、字符串、时间戳互转
  5. springmvc的相关配置文件
  6. nodeJS 事件绑定
  7. JavaScript splice() 方法使用
  8. 使用事件委托降低重复的事件绑定,从而降低dom操作的对性能的消耗
  9. OpenCV中GPU模块使用
  10. MFC和OpenCV结合