wps初始化(wps恢复初始设置是什么意思)
638
2022-05-29
MRTs 允许应用程序同时渲染多个颜色缓冲区
话不多言,详细代码和注释如下:
// HelloBlitFramebuffer.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
#include
// -----------------------------------
typedef struct
{
// Handle to a program object
GLuint programObject;
// Handle to a framebuffer object
GLuint fbo;
// Texture handle
GLuint colorTexId[4];
// Texture size
GLsizei 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);
// 创建 FBO
glGenFramebuffers(1, &userData->fbo);
glBindFramebuffer(GL_FRAMEBUFFER, userData->fbo);
// 创建4个输出纹理,并绑定到 FBO
userData->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 buffers
glDrawBuffers(4, attachments);
if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER))
{
return FALSE;
}
// 恢复默认的 framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
return TRUE;
}
// 初始化 Shader Program,返回 Program ID
GLuint InitShaders(const char *vs, const char *fs)
{
GLint vertCompiled, fragCompiled, linked;
// Shaders
GLint 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); // Debug
if (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); // Debug
if (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)
{
// Esc
if (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;
}
结果:
OpenGL
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。