OpenGL学习笔记(十七)帧缓冲

官方教程:
帧缓冲
我这里只放自己调通了的代码加注释。
Frame_buffers_vertShader.vert

#version 330 core
layout (location=0) in vec2 aPos;
layout(location=1)in vec2 aTexCoords;
out vec2 TexCoords;
void main()
{
gl_Position=vec4(aPos.x,aPos.y,0.0f,1.0f);
TexCoords=aTexCoords;
}

Frame_buffers_fragment.frag

#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;//纹理


void main()
{
FragColor=texture(screenTexture,TexCoords);
}

创建帧缓冲的过程

Shader shader = Shader("Space_vertShader.vert", "Blending_fragment.frag");
Shader screenShader = Shader("Frame_buffers_vertShader.vert", "Frame_buffers_fragment.frag");


	unsigned int framebuffer;
	glGenFramebuffers(1,&framebuffer);//创建帧缓冲
	glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);//绑定帧缓冲
	
	unsigned int texColorBuffer;
	glGenTextures(1, &texColorBuffer);
	glBindTexture(GL_TEXTURE_2D, texColorBuffer);//当前的对GL_TEXTURE_2D的所有操作都是对texColorBuffer的
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, WIDTH, HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);//纹理大小为屏幕宽高,data为空
	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, texColorBuffer, 0);//绑定颜色附件。该函数1 帧缓冲目标,2附件类型,3纹理类型,4纹理本身,5多级渐远纹理级别

	//glDeleteFramebuffers(1, &framebuffer);删除帧缓冲,不过不能在这里删
	unsigned int rbo;
	glGenRenderbuffers(1, &rbo);//申请渲染缓冲
	glBindRenderbuffer(GL_RENDERBUFFER, rbo);//绑定渲染缓冲
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, WIDTH, HEIGHT);//绑定深度和模板附件
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);//把渲染绑定到帧缓冲上

	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)//检测帧缓冲是否完整
	{
		std::cout << "ERROR::FRAMEBUFFER::Framebuffer is not complete!" << std::endl;
	}
	glBindFramebuffer(GL_FRAMEBUFFER, 0);//恢复默认

绘制四边形所需的前置准备

float quadVertices[] = { // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
	// positions   // texCoords
	-1.0f,  1.0f,  0.0f, 1.0f,
	-1.0f, -1.0f,  0.0f, 0.0f,
	 1.0f, -1.0f,  1.0f, 0.0f,

	-1.0f,  1.0f,  0.0f, 1.0f,
	 1.0f, -1.0f,  1.0f, 0.0f,
	 1.0f,  1.0f,  1.0f, 1.0f
};
	GLuint quadVBO, quadVAO;
	glGenVertexArrays(1, &quadVAO);
	glGenBuffers(1, &quadVBO);
	glBindVertexArray(quadVAO);
	glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), quadVertices, GL_STATIC_DRAW);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4* sizeof(GLfloat), (GLvoid*)0);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat)));
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);

帧缓冲的使用


glfwInput(window);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);//在frambuffer上绘制渲染图形
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
drawcube();//前面有就不写了
drawplane();
glBindFramebuffer(GL_FRAMEBUFFER, 0);//绘制
		glDisable(GL_DEPTH_TEST); // disable depth test so screen-space quad isn't discarded due to depth test.

		// clear all relevant buffers
		glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // set clear color to white (not really necessery actually, since we won't be able to see behind the quad anyways)
		glClear(GL_COLOR_BUFFER_BIT);

		screenShader.Use();
		
		glBindVertexArray(quadVAO);
		glActiveTexture(GL_TEXTURE2);
		glBindTexture(GL_TEXTURE_2D, texColorBuffer);	// use the color attachment texture as the texture of the quad plane
		screenShader.setInt("screenTexture", 2);//这个挺重要的,必须自己手动设置才能确保无错
		glDrawArrays(GL_TRIANGLES, 0, 6);

输出效果:
在这里插入图片描述
没有看见教程里的那个白框,个人认为前面这一通操作就是为了在自定义的帧缓冲上渲染自己的图形。
接下来开始后期处理
反色
修改Frame_buffers_fragment.frag

#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;//纹理
void main()
{
FragColor=vec4(vec3(1.0-texture(screenTexture,TexCoords)),1.0);
}

输出效果:
在这里插入图片描述
灰度化
修改Frame_buffers_fragment.frag

#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;//纹理
void main()
{
  vec4 texColor=texture(screenTexture,TexCoords);
  float average=(texColor.r+texColor.g+texColor.b)/3.0;
  FragColor=vec4(average,average,average,1.0f);
}

输出效果:
在这里插入图片描述
修改Frame_buffers_fragment.frag 采用加权通道

#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;//纹理
void main()
{
  vec4 texColor=texture(screenTexture,TexCoords);
    float average=(0.2126*texColor.r+0.7152*texColor.g+0.0722*texColor.b)/3.0;
  FragColor=vec4(average,average,average,1.0f);
}

输出效果:
在这里插入图片描述
锐化
修改Frame_buffers_fragment.frag

#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;//纹理

const float offset=1.0/300.0;
void main()
{

//核
    vec2 offsets[9] = vec2[](
        vec2(-offset,  offset), // 左上
        vec2( 0.0f,    offset), // 正上
        vec2( offset,  offset), // 右上
        vec2(-offset,  0.0f),   // 左
        vec2( 0.0f,    0.0f),   // 中
        vec2( offset,  0.0f),   // 右
        vec2(-offset, -offset), // 左下
        vec2( 0.0f,   -offset), // 正下
        vec2( offset, -offset)  // 右下
    );
float kernel[9]=float[](
-1,-1,-1,
-1,9,-1,
-1,-1,-1
);
vec3 sampleTexs[9];
for(int i=0;i<9;i++)
{
 sampleTexs[i]=vec3(texture(screenTexture,TexCoords.st+offsets[i]));
}

vec3 col=vec3(0.0);
for(int i=0;i<9;i++)
   col+=sampleTexs[i]*kernel[i];
FragColor=vec4(col,1.0);

}

输出效果:
在这里插入图片描述
模糊

float kernel[9] = float[](
    1.0 / 16, 2.0 / 16, 1.0 / 16,
    2.0 / 16, 4.0 / 16, 2.0 / 16,
    1.0 / 16, 2.0 / 16, 1.0 / 16  
);

在这里插入图片描述
边缘检测

float kernel[9]=float[](
    1,1,1,
	1,-8,1,
	1,1,1
);

输出效果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值