最简单的 MRTs(Multi Render Targets)的完整代码示例【OpenGL】
来源:互联网 发布:淘宝66大促报名入口 编辑:程序博客网 时间:2024/05/17 22:55
MRTs 允许应用程序同时渲染多个颜色缓冲区
话不多言,详细代码和注释如下:
// HelloBlitFramebuffer.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>#include <GL/glew.h>#include <gl/freeglut.h>// -----------------------------------typedef struct{// Handle to a program objectGLuint programObject;// Handle to a framebuffer objectGLuint fbo;// Texture handleGLuint colorTexId[4];// Texture sizeGLsizei textureWidth;GLsizei textureHeight;} UserData;UserData *userData = NULL;const GLenum attachments[4] ={GL_COLOR_ATTACHMENT0,GL_COLOR_ATTACHMENT1,GL_COLOR_ATTACHMENT2,GL_COLOR_ATTACHMENT3};#define SCREEN_W 640#define SCREEN_H 640///// 初始化 FBO 和 MRTs//int InitFBO(){int i;GLint defaultFramebuffer = 0;glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFramebuffer);// 创建 FBOglGenFramebuffers(1, &userData->fbo);glBindFramebuffer(GL_FRAMEBUFFER, userData->fbo);// 创建4个输出纹理,并绑定到 FBOuserData->textureHeight = userData->textureWidth = 400;glGenTextures(4, &userData->colorTexId[0]);for (i = 0; i < 4; ++i){glBindTexture(GL_TEXTURE_2D, userData->colorTexId[i]);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,userData->textureWidth, userData->textureHeight,0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);// 设置过滤模式glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachments[i],GL_TEXTURE_2D, userData->colorTexId[i], 0);}// 指定待写入的 color buffersglDrawBuffers(4, attachments);if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER)){return FALSE;}// 恢复默认的 framebufferglBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);return TRUE;}// 初始化 Shader Program,返回 Program IDGLuint InitShaders(const char *vs, const char *fs){GLint vertCompiled, fragCompiled, linked;// ShadersGLint v = glCreateShader(GL_VERTEX_SHADER);GLint f = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(v, 1, &vs, NULL);glShaderSource(f, 1, &fs, NULL);glCompileShader(v);glGetShaderiv(v, GL_COMPILE_STATUS, &vertCompiled);// Debugif (vertCompiled != GL_TRUE){printf("Vertex Shader compied error! \n");}glCompileShader(f);glGetShaderiv(f, GL_COMPILE_STATUS, &fragCompiled);if (fragCompiled != GL_TRUE){printf("Fragment Shader compied error! \n");}//Program:GLuint p = glCreateProgram();glAttachShader(p, v);glAttachShader(p, f);glLinkProgram(p);glGetProgramiv(p, GL_LINK_STATUS, &linked); // Debugif (linked != GL_TRUE){printf("Program linked error! \n");}return p;}///// 初始化 shader 和 program//int Init(){const char vShaderStr[] =//"#version 300 es \n""#version 330 \n""layout(location = 0) in vec4 a_position; \n""void main() \n""{ \n"" gl_Position = a_position; \n""} \n";const char fShaderStr[] =//"#version 300 es \n"//"precision mediump float; \n""#version 330 \n""layout(location = 0) out vec4 fragData0; \n""layout(location = 1) out vec4 fragData1; \n""layout(location = 2) out vec4 fragData2; \n""layout(location = 3) out vec4 fragData3; \n""void main() \n""{ \n"" // first buffer will contain red color \n"" fragData0 = vec4 ( 1, 0, 0, 1 ); \n"" \n"" // second buffer will contain green color \n"" fragData1 = vec4 ( 0, 1, 0, 1 ); \n"" \n"" // third buffer will contain blue color \n"" fragData2 = vec4 ( 0, 0, 1, 1 ); \n"" \n"" // fourth buffer will contain gray color \n"" fragData3 = vec4 ( 0.5, 0.5, 0.5, 1 ); \n""} \n";userData->programObject = InitShaders(vShaderStr, fShaderStr);InitFBO();glClearColor(1.0f, 1.0f, 1.0f, 0.0f);return TRUE;}///// 绘制一个 Quad //void DrawGeometry(){GLfloat vVertices[] = { -1.0f, 1.0f, 0.0f,-1.0f, -1.0f, 0.0f,1.0f, -1.0f, 0.0f,1.0f, 1.0f, 0.0f,};GLushort indices[] = { 0, 1, 2, 0, 2, 3 };glViewport(0, 0, SCREEN_W, SCREEN_H);glClear(GL_COLOR_BUFFER_BIT);glUseProgram(userData->programObject);glVertexAttribPointer(0, 3, GL_FLOAT,GL_FALSE, 3 * sizeof(GLfloat), vVertices);glEnableVertexAttribArray(0);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);}///// ☆ 拷贝 MRTs 的输出到屏幕 ☆ //void BlitTextures(){// 绑定 FBO,用于读取glBindFramebuffer(GL_READ_FRAMEBUFFER, userData->fbo);// 选择一块 color buffer 作为源,拷贝输出到屏幕指定位置glReadBuffer(GL_COLOR_ATTACHMENT0);glBlitFramebuffer(0, 0, userData->textureWidth, userData->textureHeight,0, 0,SCREEN_W / 2, SCREEN_H / 2,// 左下角坐标GL_COLOR_BUFFER_BIT, GL_LINEAR);glReadBuffer(GL_COLOR_ATTACHMENT1);glBlitFramebuffer(0, 0, userData->textureWidth, userData->textureHeight,SCREEN_W / 2, 0,SCREEN_W, SCREEN_H / 2,// 右下角坐标GL_COLOR_BUFFER_BIT, GL_LINEAR);glReadBuffer(GL_COLOR_ATTACHMENT2);glBlitFramebuffer(0, 0, userData->textureWidth, userData->textureHeight,0, SCREEN_H / 2,SCREEN_W / 2, SCREEN_H, // 左上角坐标GL_COLOR_BUFFER_BIT, GL_LINEAR);glReadBuffer(GL_COLOR_ATTACHMENT3);glBlitFramebuffer(0, 0, userData->textureWidth, userData->textureHeight,SCREEN_W / 2, SCREEN_H / 2, // 右上角坐标SCREEN_W, SCREEN_H,GL_COLOR_BUFFER_BIT, GL_LINEAR);}///// 清理善后//void ShutDown(){glDeleteTextures(4, userData->colorTexId);glDeleteFramebuffers(1, &userData->fbo);glDeleteProgram(userData->programObject);}// -----------------------------------// 键盘响应事件static void ProcessNormalKeys(unsigned char key, int x, int y){// Escif (key == 27){ShutDown();exit(0);}}static void Display(){GLint defaultFramebuffer = 0;glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFramebuffer);// 使用 MRTs 输出4种颜色至4块缓冲区glBindFramebuffer(GL_FRAMEBUFFER, userData->fbo);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glDrawBuffers(4, attachments);DrawGeometry();// 恢复默认 framebuffer// 从之前的4块缓冲区中拷贝像素到屏幕指定位置glBindFramebuffer(GL_DRAW_FRAMEBUFFER, defaultFramebuffer);BlitTextures();glutSwapBuffers();}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA /*| GLUT_STENCIL | GLUT_DEPTH*/);glutInitWindowPosition(100, 100);glutInitWindowSize(SCREEN_W, SCREEN_H);glutCreateWindow("Hello BlitFramebuffer !");GLenum err = glewInit();if (err != GLEW_OK){fprintf(stderr, "Error: %s\n", glewGetErrorString(err));exit(-2);}userData = new UserData;if (!Init()){return GL_FALSE;}glutDisplayFunc(Display);glutIdleFunc(&Display);glutKeyboardFunc(ProcessNormalKeys);glutMainLoop(); return 0;}
结果:
0 0
- 最简单的 MRTs(Multi Render Targets)的完整代码示例【OpenGL】
- 《OpenGL ES 2.0 Programming Guide》第12章 “最简单的Multi-Pass+VBO”示例代码【C语言版】
- 最简单的粒子特效(Transform Feedback ) 的关键代码示例【OpenGL】
- 最简单的PBO(异步Read-Back)Demo 完整代码示例
- 《OpenGL ES 2.0 Programming Guide》第9章“最简单的MipMap”示例代码【C语言版】
- 《OpenGL ES 2.0 Programming Guide》第11章“最简单的MSAA”示例代码【C语言版】
- OpenGL ES 3.0-Multiple Render Targets
- Multiple Render Targets in OpenGL with Cg
- 用smarty实现简单分页的示例完整代码
- 《OpenGL ES 2.0 Programming Guide》第8章 “最简单的Vertex Buffer Object”示例代码【C语言版】
- 《OpenGL ES 2.0 Programming Guide》第9章 “最简单的本地纹理显示”示例代码【C语言版】
- 《OpenGL ES 2.0 Programming Guide》第12章“最简单的FBO Depth Texture”示例代码【C语言版】
- 《OpenGL ES 2.0 Programming Guide》第9章 “最简单的本地纹理+VBO”示例代码【C语言版】
- 《OpenGL ES 2.0 Programming Guide》第12章“最简单的ReadPixels并保存为BMP”示例代码【C语言版】
- 《OpenGL ES 2.0 Programming Guide》第12章 “最简单的本地纹理+FBO+VBO”示例代码【C语言版】
- 完整的最简单的谱聚类python代码
- 完整的最简单的谱聚类python代码
- 完整的最简单的谱聚类python代码
- Ubuntu开机直接进入命令行模式
- Spring与Quartz集成配置实现简单定时任务调度
- 小明的调查作业
- Javascript 6里的4个新语法
- Android从零开搞系列:网络框架系列(3)Retrofit+RxJava+MVP(上)Retrofit
- 最简单的 MRTs(Multi Render Targets)的完整代码示例【OpenGL】
- ADB 用法大全
- vs安装framwork 4 失败
- 安卓开发使用chrome浏览器进行调试
- ROS学习(九):ROS URDF->link
- Android 系列 5.9使用Inkscape创建Android Launcher图标
- 【资源分享】《机器学习&深度学习&自然语言处理》视频课程资源百度云下载
- Android TableLayout的优雅姿势《一》
- java中访问权限