OpenGLES入门13-Blend混合

OpenGLES入门13-Blend混合

2023年7月14日发(作者:)

OpenGLES⼊门13-Blend混合欢迎关注我的 OpenGL ES⼊门专题概述混合技术在某些情况下特别有⽤。⽐如在iOS中做⾳乐播放器的时候,我们希望歌词当前的播放进度与整句歌词具有明显的颜⾊区分。我们可以这样做:@interface MVMusicView : UILabel@property (nonatomic, assign) CGFloat progress;@end@implementation MVMusicView- (void)setProgress:(CGFloat)progress{ _progress = progress; [self setNeedsDisplay];}- (void)drawRect:(CGRect)rect{ [super drawRect:rect];

[[UIColor greenColor] setFill];

CGRect lyricRect = CGRectMake(0, 0, * _progress, ); UIRectFillUsingBlendMode(lyricRect, kCGBlendModeSourceIn);}@endBlend效果:效果.png在OpenGL ES 中物体透明技术通常被叫做混合(Blending)。透明是⾮纯⾊⽽是混合⾊,这种颜⾊来⾃于不同浓度的⾃⾝颜⾊和它后⾯的物体颜⾊。⼀个物体的透明度,被定义为它的颜⾊的alpha值,alpha颜⾊值是⼀个颜⾊向量的第四个元素。实现效果接下来我们⽤OpenGL ES 实现类似的效果,效果图如下所⽰:效果图.png基础知识⽚段着⾊器运⾏完成并且所有的测试都通过以后,混合⽅程才能⾃由执⾏⽚段的颜⾊输出,当前它在颜⾊缓冲中(前⾯⽚段的颜⾊在当前⽚段之前储存)。源和⽬标颜⾊会⾃动被OpenGL设置,⽽源和⽬标因⼦可以让我们⾃由设置。开启混合glEnable(GL_BLEND);关闭混合glDisable(GL_BLEND);混合因⼦计算公式result = source * Fsource + destination * Fdestination

参数 source:源颜⾊向量。这是来⾃纹理的本来的颜⾊向量。参数 destination:⽬标颜⾊向量。这是储存在颜⾊缓冲中当前位置的颜⾊向量。参数 Fsource:源因⼦。设置了对源颜⾊的alpha值影响。参数 Fdestination:⽬标因⼦。设置了对⽬标颜⾊的alpha影响。混合因⼦设置函数void glBlendFunc (GLenum sfactor, GLenum dfactor);源(source)和⽬标(destination)因⼦相关设置选项:选项GL_ZEROGL_ONEGL_SRC_COLORGL_ONE_MINUS_SRC_COLORGL_SRC_ALPHAGL_ONE_MINUS_SRC_ALPHAGL_DST_ALPHAGL_ONE_MINUS_DST_ALPHA值01源颜⾊向量1 − 源颜⾊向量源的alpha值1 − 源的alpha值⽬标的alpha值1 − ⽬标的alpha值实现过程加载png图⽚。在这⾥主要是⽤到了两张png的纹理,加载的时候分别加载,并⽣成纹理对象。- (void)setupTexure{ NSString *path = [[NSBundle mainBundle] pathForResource:@"text" ofType:@"png"];

pic_data pngData; read_png_file(8String, &pngData); // 创建纹理 if ( > 0) { _texture = createTexture2D(GL_RGBA, , , ); }else { _texture = createTexture2D(GL_RGB, , , ); }

if () { free(); = NULL; }}- (void)setupTexure1{ NSString *path = [[NSBundle mainBundle] pathForResource:@"wood" ofType:@"png"];

pic_data pngData; read_png_file(8String, &pngData); // 创建纹理 if ( > 0) { _texture1 = createTexture2D(GL_RGBA, , , ); }else { _texture1 = createTexture2D(GL_RGB, , , ); }

if () { free(); = NULL; }}开启混合测试。这个测试主要是测试开启混合以及相应的混合因⼦对结果的影响。- (void)render{ glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, , );

glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

// 激活纹理 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, _texture); glUniform1i(glGetUniformLocation(_program, "image"), 0);

glDrawArrays(GL_TRIANGLES, 0, _vertCount);

[_context presentRenderbuffer:GL_RENDERBUFFER];} //将指定 renderbuffer 呈现在屏幕上,在这⾥我们指定的是前⾯已经绑定为当前 renderbuffer 的那个,在 renderbuffer 可以被呈现之前,必须调⽤renderbufferStorage:fromDra顶点着⾊器attribute vec3 position;attribute vec2 texcoord;varying vec2 vTexcoord;void main(){ gl_Position = vec4(position, 1.0); vTexcoord = texcoord;}⽚源着⾊器precision mediump float;uniform sampler2D image;uniform sampler2D image1;varying vec2 vTexcoord;void main(){ gl_FragColor = texture2D(image, vTexcoord);}效果图开启混合.png两张图⽚进⾏混合测试。⼀张图⽚先渲染到帧缓存中,然后再渲染另⼀张,并与帧缓存中的图像混合。- (void)render{ glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, , );

// 第⼀个纹理关闭混合 glDisable(GL_BLEND);

// 激活纹理 glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, _texture1); glUniform1i(glGetUniformLocation(_program, "image"), 1);

glDrawArrays(GL_TRIANGLES, 0, _vertCount);

// 渲染的时候开启混合 glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE);

// 激活纹理 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, _texture); glUniform1i(glGetUniformLocation(_program, "image"), 0);

glDrawArrays(GL_TRIANGLES, 0, _vertCount);

[_context presentRenderbuffer:GL_RENDERBUFFER];} //将指定 renderbuffer 呈现在屏幕上,在这⾥我们指定的是前⾯已经绑定为当前 renderbuffer 的那个,在 renderbuffer 可以被呈现之前,必须调⽤renderbufferStorage:fromDra顶点着⾊器attribute vec3 position;attribute vec2 texcoord;varying vec2 vTexcoord;void main(){ gl_Position = vec4(position, 1.0); vTexcoord = texcoord;}⽚源着⾊器precision mediump float;uniform sampler2D image;uniform sampler2D image1;varying vec2 vTexcoord;void main(){ gl_FragColor = texture2D(image, vTexcoord);}效果图:两张纹理混合.png歌词显⽰效果测试。⾃⼰通过编写着⾊器进⾏相关混合。在这⾥由于⽂字的渲染⽐较复杂(如果想渲染⽂字可以使⽤FreeType2,它是⼀个免费、开源、可移植且⾼质量的字体引擎,被⼴泛使⽤着。),因此⽤透明的png字体图代替⽂字的渲染,即⼯程中的

。- (void)render{ glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, , );

// 激活纹理 glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, _texture1); glUniform1i(glGetUniformLocation(_program, "image"), 1);

// 激活纹理 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, _texture); glUniform1i(glGetUniformLocation(_program, "image1"), 0);

glDrawArrays(GL_TRIANGLES, 0, _vertCount);

[_context presentRenderbuffer:GL_RENDERBUFFER];} //将指定 renderbuffer 呈现在屏幕上,在这⾥我们指定的是前⾯已经绑定为当前 renderbuffer 的那个,在 renderbuffer 可以被呈现之前,必须调⽤renderbufferStorage:fromDra顶点着⾊器attribute vec3 position;attribute vec2 texcoord;varying vec2 vTexcoord;void main(){ gl_Position = vec4(position, 1.0); vTexcoord = texcoord;}⽚源着⾊器。利⽤纹理坐标,使纹理坐标s轴0.43左边的为红⾊字体,右边的保持原来的颜⾊。precision mediump float;uniform sampler2D image;uniform sampler2D image1;varying vec2 vTexcoord;void main(){ vec4 des = vec4(1.0, 0.0, 0.0, 1.0); vec4 src = texture2D(image1, vTexcoord); vec4 bld; if (vTexcoord.x <= 0.43) { bld = vec4(vec3(des), src.a); }else { bld = src; }

gl_FragColor = bld * bld.a + vec4(1.0) * (1.0 - bld.a);}效果图:效果图.png常见问题由于Xcode在打包的时候会对png图⽚进⾏优化处理,因此我们在使⽤libpng读取读⽚的时候可能出现以下错误:libpng error: CgBI: unhandled critical chunk解决办法是关闭Xcode对png的优化处理解决办法.png

发布者:admin,转转请注明出处:http://www.yc00.com/news/1689264925a226444.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信