当前位置:网站首页>GPUImage链式纹理的简单实现
GPUImage链式纹理的简单实现
2022-06-12 13:26:00 【Li.CQ】
链式 shader 的实现
实现链式 shader 的核心思路利 : 用帧缓冲对象,将帧缓冲对象生成的纹理单元最为下一个 shader 纹理的输入;
源码
帧缓冲的实现核心
/** 设置帧缓冲对象 */
-(void)setuptextureSize:(CGSize)size{
glGenFramebuffers(1, &_frameBufferID);
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &_textureID);
glBindTexture(GL_TEXTURE_2D, _textureID);
// - 这里的 size 是需要渲染的填充的view 的size,而不是图片的 size
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width, size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_FRAMEBUFFER, _frameBufferID);
// - 帧缓冲对象
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, _textureID, 0);
/* 解绑纹理,解绑才能重新绑定新的纹理单元; 如果没有解绑操作, 那么帧缓冲的输出纹理单元就是GL_TEXTURE1, 但是如果作为一个帧缓冲的输出和另一个帧缓冲输入, 就会出现输入和输出是同一个纹理单元;(如下边的shaderCompiler2, frameBuffer1的输出纹理单元作为shaderCompiler2的输入单元是 GL_TEXTURE1, 经shaderCompiler2后的frameBuffer2的输出纹理单元也是GL_TEXTURE1, 这是不可以的哦) glActiveTexture() : 设置帧缓冲的输出纹理单元; glUniform1i() : 设置 shader 的纹理的输入; 输入和输出不能是同一个纹理单元; */
glBindTexture(GL_TEXTURE_2D, 0);
}
- (GLuint)textureID{
return _textureID;
}
- (GLuint)framebufferID{
return _frameBufferID;
}
/** 激活帧缓冲 */
-(void)activityFrameBuffer{
glBindFramebuffer(GL_FRAMEBUFFER, _frameBufferID);
}
链式纹理的实现
// - 输入的纹理
-(void)setupInputTexture{
GLuint texture;
UIImage *image = [UIImage imageNamed:@"gyy.jpg"];
size_t width = CGImageGetWidth(image.CGImage);
size_t height = CGImageGetHeight(image.CGImage);
_bufferSize = CGSizeMake(width, height);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
void *imageData = malloc( height * width * 4 );
CGContextRef context = CGBitmapContextCreate(imageData,
width,
height,
8,
4 * width,
colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease( colorSpace );
CGContextClearRect( context, CGRectMake( 0, 0, width, height ) );
CGContextTranslateCTM(context, 0, height);
CGContextScaleCTM (context, 1.0,-1.0);
CGContextDrawImage( context, CGRectMake( 0, 0, width, height ), image.CGImage );
CGContextRelease(context);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
(GLint)width,
(GLint)height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
imageData);
free(imageData);
}
// - 三个着色器程序 (原图纹理->shaderCompiler1->frameBuffe1, frameBuffe1->shaderCompiler2->frameBuffe2, frameBuffe2->shaderCompiler3->渲染在屏幕上)
-(void)setupShader{
self.shaderCompiler1 = [[QGShaderCompiler alloc]initWithvshaderFileName:@"VertextShader2" fshaderFileName:@"FragmentShader2_06"];
_position1 = [self.shaderCompiler1 addAttribute:@"position"];
_texture1 = [self.shaderCompiler1 addAttribute:@"textCoordinate"];
_uni1 = [self.shaderCompiler1 addUniform:@"colorMap"];
self.shaderCompiler2 = [[QGShaderCompiler alloc]initWithvshaderFileName:@"VertextShader2" fshaderFileName:@"FragmentShader2_04"];
_position2 = [self.shaderCompiler2 addAttribute:@"position"];
_texture2 = [self.shaderCompiler2 addAttribute:@"textCoordinate"];
_uni2 = [self.shaderCompiler2 addUniform:@"colorMap"];
self.shaderCompiler3 = [[QGShaderCompiler alloc]initWithvshaderFileName:@"VertextShader2" fshaderFileName:@"FragmentShader2_14"];
_position3 = [self.shaderCompiler3 addAttribute:@"position"];
_texture3 = [self.shaderCompiler3 addAttribute:@"textCoordinate"];
_uni3 = [self.shaderCompiler3 addUniform:@"colorMap"];
}
// - 两个提供输出的帧缓冲对象
-(void)setupFrameBufferObj{
self.frameBuffer1 = [[QGFrameBuffer alloc]initWithSize:self.frame.size];
self.frameBuffer2 = [[QGFrameBuffer alloc]initWithSize:self.frame.size];
}
// - 原图纹理->shaderCompiler1->frameBuffe1
-(void)render1{
[self.shaderCompiler1 glUseProgram];
[self.frameBuffer1 activityFrameBuffer];
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
/* 已知源纹理的输出纹理单元为 GL_TEXTURE0; 下边的 glUniform1i(_uni1, 0) 是将 GL_TEXTURE0 作为 self.shaderCompiler1 的输入纹理, QGFrameBuffer 中的 glActiveTexture(GL_TEXTURE1); 是将 GL_TEXTURE1, 作为帧缓冲纹理输出单元; */
glUniform1i(_uni1, 0);
GLfloat vertices[] = {
1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0,
-1.0, 1.0, 0.0};
GLfloat texturecoords[] ={
1.0, 1.0,
1.0, 0.0,
0.0, 1.0,
1.0, 0.0,
0.0, 0.0,
0.0, 1.0};
glVertexAttribPointer(_position1, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, vertices);
glVertexAttribPointer(_texture1, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, texturecoords);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
// - frameBuffe1->shaderCompiler2->frameBuffe2
-(void)render2{
[self.shaderCompiler2 glUseProgram];
[self.frameBuffer2 activityFrameBuffer];
glClearColor(0, 1, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
/* 前边已知self.frameBuffer1的输出纹理单元为 GL_TEXTURE1; glActiveTexture(GL_TEXTURE2); 和 glBindTexture(GL_TEXTURE_2D, [self.frameBuffer1 textureID]); 是将 self.frameBuffer1的输出纹理单元从 GL_TEXTURE1 改为 GL_TEXTURE2; glUniform1i(_uni2, 2) 是将 GL_TEXTURE2 作为 self.shaderCompiler2 的输入纹理; QGFrameBuffer 中的 glActiveTexture(GL_TEXTURE1); 是将 GL_TEXTURE1, 作为帧缓冲纹理输出单元; */
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, [self.frameBuffer1 textureID]);
glUniform1i(_uni2, 2);
GLfloat vertices[] = {
1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0,
-1.0, 1.0, 0.0};
GLfloat texturecoords[] ={
1.0, 1.0,
1.0, 0.0,
0.0, 1.0,
1.0, 0.0,
0.0, 0.0,
0.0, 1.0};
glVertexAttribPointer(_position2, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, vertices);
glVertexAttribPointer(_texture2, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, texturecoords);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
// - frameBuffe2->shaderCompiler3->渲染在屏幕上
-(void)render3{
[self.shaderCompiler3 glUseProgram];
[self activityFrameBuffer];
glClearColor(0, 0, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
/* 前边已知self.frameBuffer2的输出纹理单元为 GL_TEXTURE1; glActiveTexture(GL_TEXTURE2); 和 glBindTexture(GL_TEXTURE_2D, [self.frameBuffer1 textureID]); 是将 self.frameBuffer2的输出纹理单元从 GL_TEXTURE1 改为 GL_TEXTURE2; glUniform1i(_uni2, 2) 是将 GL_TEXTURE2 作为 self.shaderCompiler3 的输入纹理; 帧缓冲纹理输出单元渲染到屏幕上; */
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, [self.frameBuffer2 textureID]);
glUniform1i(_uni3, 2);
GLfloat vertices[] = {
1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0,
-1.0, 1.0, 0.0};
GLfloat texturecoords[] ={
1.0, 1.0,
1.0, 0.0,
0.0, 1.0,
1.0, 0.0,
0.0, 0.0,
0.0, 1.0};
glVertexAttribPointer(_position3, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, vertices);
glVertexAttribPointer(_texture3, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, texturecoords);
glDrawArrays(GL_TRIANGLES, 0, 6);
[[QGEAGLContext sharedInstance] presentRenderbuffer];
}
边栏推荐
- How to solve the problem of data table query error when SQLite writes the registration function?
- import torch_ Geometric first graph network example
- 1005: estimation of the earth's population carrying capacity
- Mui login database improvement and Ajax asynchronous processing [mui+flask+mongodb+hbuilderx]
- Further understanding of the network
- 实战 | 巧用位姿解算实现单目相机测距
- STM32F1与STM32CubeIDE编程实例-设备驱动-DHT11温度温度传感器驱动
- Build an embedded system software development environment - build a cross compilation environment
- JVM runtime parameters
- 章鱼网络进展月报 | 2022.5.1-5.31
猜你喜欢

Cocoapods的相关知识点

创新实训(十)高级界面美化

镜像扫描工具预研

章鱼网络进展月报 | 2022.5.1-5.31

Wechat web developer tools tutorial, web development issues

Realization of Joseph Ring with one-way ring linked list

Record some settings for visual studio 2019

【刷题篇】抽牌获胜的概率

D1 Nezha Development Board understands the basic startup and loading process

D1 哪吒开发板 了解基本的启动加载流程
随机推荐
How to solve the problem of data table query error when SQLite writes the registration function?
AWLive 结构体的使用
import torch_ Geometric first graph network example
Pytorch framework
【微信小程序开发】第1篇:开发工具安装及程序配置
Will the next star of PPT for workplace speech be you [perfect summary] at the moment
Seeking magic square of order n with C language
Design virtual network to realize communication between virtual machine instance and external network
imagemagick:a gentle introduction to magick++
Freshman girls' nonsense programming is popular! Those who understand programming are tied with Q after reading
torch_ geometric message passing network
看完这一篇就够了,web中文开发
2064: [example 2.1] exchange value
static 和 extern 关键字详解
A brief introduction to Verilog mode
Redis消息队列重复消费问题
苹果电脑上MySQL安装完成找不到怎么办
Installation of pagoda
"New continent" of mobile application going to sea
Application of list and Dict