深入探讨iOS平台下的图形编程技术

更新:10-28 民间故事 我要投稿 纠错 投诉

大家好,今天小编来为大家解答以下的问题,关于深入探讨iOS平台下的图形编程技术,这个很多人还不知道,现在让我们一起来看看吧!

通过调用glEnable(GL_BLEND) 函数打开混合,然后通过调用glBlendFunc(GLenum sfactor, GLenum dfactor) 设置混合函数。 sfactor 参数用于指定每个片段的最终颜色元素如何影响混合。 dfactor 参数用于指定目标帧缓冲区中已存在的颜色元素将如何影响混合。最常用的混合函数配置是将sfactor设置为GL_SRC_ALPHA,dfactor设置为GL_ONE_MINUS_SRC_ALPHA,如下代码所示:

glEnable(GL_BLEND);

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);其中GL_SRC_ALPHA用于将源片段的透明度元素与其他片段的颜色一一相乘。 GL_ONE_MINUS_SRC_ALPHA 用于将源片段的透明度元素与帧缓冲区中正在更新的像素的颜色元素相乘。最终结果是:如果片段的透明度为0,则帧缓冲区中不会出现片段的颜色。如果片段的透明度为1,则片段的颜色完全替换帧缓冲区中相应像素的颜色。透明度介于0.0 和1.0 之间意味着片段颜色的一部分将与帧缓冲区中相应像素颜色的一部分混合以产生混合结果。使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 时,帧缓冲区中的最终颜色使用以下公式计算:混合使用glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 产生与iOS Core Graphics 的"正常混合模式" 相同的结果。结果显示如下:

叶子纹理与帧缓冲区的像素颜色渲染缓冲区中的黑色像素混合,因此在叶子纹理包含透明纹理元素的任何地方,黑色像素都保持不变。然后使用错误图像的第二个纹理将其与像素颜色渲染缓存混合。最终的渲染结果是叶子纹理之上的虫子纹理,它位于黑色背景之上。让我们开始编写代码。首先我们需要定义顶点数据。

static const SceneVertex 顶点[]=

{

//位置坐标//纹理坐标

{{-1.0f, -0.6f, 0.0f}, {0.0f, 0.0f}}, //第一个三角形

{{ 1.0f, -0.6f, 0.0f}, {1.0f, 0.0f}},

{{-1.0f, 0.6f, 0.0f}, {0.0f, 1.0f}},

{{ 1.0f, -0.6f, 0.0f}, {1.0f, 0.0f}}, //第二个三角形

{{-1.0f, 0.6f, 0.0f}, {0.0f, 1.0f}},

{{ 1.0f, 0.6f, 0.0f}, {1.0f, 1.0f}},

};

定义两个三角形组成一个矩形,纹理就完整的展现出来了。将顶点数据发送到GPU内存缓存后,我们需要加载图像。从图像加载纹理与上一篇文章不同。这里,一个NSDictionary 对象用于设置选项。这里的GLKTextureLoaderOriginBottomLeft和对应的布尔值YES用于设置GLKit的GLKTextureLoader类垂直翻转图像数据。该操作可以抵消图像原点与OpenGL ES标准原点之间的差异。

NSString *leavesImagePath=[[NSBundle mainBundle] pathForResource:@"leaves" ofType:@"jpg"];

CGImageRef leavesImageRef=[UIImage imageWithContentsOfFile:leavesImagePath].CGImage;

self.textureInfo0=[GLKTextureLoadertextureWithCGImage:leavesImageRef options:[NSDictionarydictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],GLKTextureLoaderOriginBottomLeft, nil] error:NULL];

NSString *beetleImagePath=[[NSBundle mainBundle] pathForResource:@"beetle" ofType:@"jpg"];

CGImageRef beetleImageRef=[UIImage imageWithContentsOfFile:beetleImagePath].CGImage;

self.textureInfo1=[GLKTextureLoadertextureWithCGImage:beetleImageRef options:[NSDictionarydictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],GLKTextureLoaderOriginBottomLeft, nil] error:NULL];以下是- (void)glkView:(GLKView *)视图drawInRect3336中的调整0(CGRect)矩形方法。相同的几何体被渲染两次,第一次使用叶子纹理,第二次使用错误。每当由纹理着色的片段与像素颜色渲染缓冲区中已有的像素颜色混合时,就会发生混合。

self.baseEffect.texture2d0.name=self.textureInfo0.name;

self.baseEffect.texture2d0.target=self.textureInfo0.target;

[self.baseEffectprepareToDraw];

glDrawArrays(GL_TRIANGLES, 0, 6);

self.baseEffect.texture2d0.name=self.textureInfo1.name;

self.baseEffect.texture2d0.target=self.textureInfo1.target;

[self.baseEffectprepareToDraw];

glDrawArrays(GL_TRIANGLES, 0, 6); GLkit的baseEffect是由第一张纹理设置的,同时绘制缓存的数据。然后由第二个纹理设置baseEffect。同时再次绘制缓存的数据。这两个过程还伴随着与像素颜色渲染缓存的混合。绘制的顺序决定了哪个纹理出现在另一个纹理之上。在目前的情况下,是叶子上的虫子。反之则相反。

如果需要源码请前往GitHubLearnOpenGL ESbrach02

多重纹理通过将片段颜色与像素颜色渲染缓冲区中的现有颜色混合,可以实现许多有用的视觉效果。但这种技术有两个缺点:每次更新显示时,几何图形必须渲染一次或多次,并且混合函数需要从像素颜色渲染缓存中读取颜色数据,以便与片段颜色混合。然后结果被写回帧缓冲区。当具有透明度数据的多个纹理被级联时,每个纹理的像素颜色渲染缓冲区颜色被再次读取、混合和重写。多次读取和写入像素颜色渲染缓存以创建最终渲染像素的过程称为多通道渲染。与往常一样,内存访问会限制性能,因此多通道渲染并不是最优的。接下来介绍多重纹理,以避免多通道渲染的大多数陷阱。

所有现代GPU 都能够同时从至少两个纹理缓冲区中采样纹理像素。 GLKit 的GLKBaseEffect 类支持这两种纹理。执行纹理像素采样和混合的硬件组件称为纹理单元或采样器。如果您的应用程序需要两个以上的纹理单元,在确定一次传递中可以组合多少个纹理之前,您可以使用以下代码:

GLint iUnits;

glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, iUnits);

printf("%zd",iUnits);多个纹理引入了另一个组合配置选项。帮助降低复杂性。 iOS5中GLKit的GLKEffectPropertyTexture类提供了3种常见的多纹理模式:GLKTextureEnvModeReplace、GLKTextureEnvModeModulate、GLKTextureEnvModeDecal。 GLKEffectPropertyTexture 默认使用GLKTextureEnvModeModulate。这种模式几乎总是能产生最好的结果。 GLKTextureEnvModeModulate 模式会导致为灯光和其他效果计算的所有颜色与从纹理采样的颜色混合。详细解释请查看官方文档。

GLKEffectPropertyTexture 的envMode 属性用于配置混合模式。在此示例中,仍加载两个纹理,但不再需要显式启用与帧缓冲区的像素颜色渲染缓冲区的混合。相反,baseEffect 的第二个纹理属性texture2d1 设置为使用GLKTextureEnvModeDecal 模式,该模式使用类似于glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 的方法将第二个纹理与第一个纹理混合。

self.baseEffect.texture2d1.envMode=GLKTextureEnvModeDecal;NSString *leavesImagePath=[[NSBundle mainBundle] pathForResource:@"leaves" ofType:@"jpg"];

CGImageRef leavesImageRef=[UIImage imageWithContentsOfFile:leavesImagePath].CGImage;

self.textureInfo0=[GLKTextureLoadertextureWithCGImage:leavesImageRef options:[NSDictionarydictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],GLKTextureLoaderOriginBottomLeft, nil] error:NULL];

self.baseEffect.texture2d0.name=self.textureInfo0.name;

self.baseEffect.texture2d0.target=self.textureInfo0.target;

NSString *beetleImagePath=[[NSBundle mainBundle] pathForResource:@"beetle" ofType:@"jpg"];

CGImageRef beetleImageRef=[UIImage imageWithContentsOfFile:beetleImagePath].CGImage;

self.textureInfo1=[GLKTextureLoadertextureWithCGImage:beetleImageRef options:[NSDictionarydictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],GLKTextureLoaderOriginBottomLeft, nil] error:NULL];

self.baseEffect.texture2d1.name=self.textureInfo1.name;

self.baseEffect.texture2d1.target=self.textureInfo1.target;

self.baseEffect.texture2d1.envMode=GLKTextureEnvModeDecal;我们看一下glkView:(GLKView *)view drawInRec中的修改:

GLsizeipositionOffset=offsetof(SceneVertex,positionCoords);

glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL +positionOffset);

GLsizeitextureOffset=offsetof(SceneVertex,textureCoords);

glEnableVertexAttribArray(GLKVertexAttribTexCoord0);

glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL + 纹理偏移);

glEnableVertexAttribArray(GLKVertexAttribTexCoord1);

glVertexAttribPointer(GLKVertexAttribTexCoord1, 2, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL + 纹理偏移);

[self.baseEffectprepareToDraw];

用户评论

青山暮雪

iOS开发真刺激!这方面技术我还在摸索中。

    有16位网友表示赞同!

巷口酒肆

OpenGL ES 这块确实很好学习,可以做成很多炫酷的游戏

    有20位网友表示赞同!

烬陌袅

苹果生态的开发者都应该掌握这方面的知识吧?

    有14位网友表示赞同!

颜洛殇

看样子需要学习C++吗?

    有14位网友表示赞同!

┲﹊怅惘。

我想了解下开发iOS游戏的成本和收益。

    有10位网友表示赞同!

淡抹烟熏妆丶

最近想试试自己做个简单的游戏,学 OpenGL ES 挺不错的选择啊?

    有12位网友表示赞同!

看我发功喷飞你

我更喜欢 Unity 这种引擎开发的便捷性,你们觉得呢?

    有16位网友表示赞同!

妄灸

学习了 OpenGL ES 能用在其他平台吗?

    有11位网友表示赞同!

你很爱吃凉皮

感觉图形渲染这块越来越重要了,

    有14位网友表示赞同!

执笔画眉

有没有推荐一些相关的教程啊?

    有9位网友表示赞同!

↘▂_倥絔

OpenGL ES 现在用的比较少了,还是主流技术?

    有16位网友表示赞同!

致命伤

iOS 开发需要多学的东西太多了……

    有6位网友表示赞同!

可儿

将来做游戏开发是不是要学习 3D 模型制作 ?

    有17位网友表示赞同!

枫无痕

想了解下 OpenGL ES 和 Metal 的区别啊?

    有14位网友表示赞同!

此生一诺

感觉 iOS 开发越来越专业了,我也要努力提升一下技术水平。

    有15位网友表示赞同!

陌離

有没有做iOS游戏的开发者交流群啊?

    有5位网友表示赞同!

等量代换

学习 OpenGL ES 需要多久的时间呢?

    有9位网友表示赞同!

寂莫

希望看到一些 iOS 游戏用 OpenGL ES 做出的精彩作品!

    有15位网友表示赞同!

念旧是个瘾。

这篇文章介绍的比较透彻吗?能给我一些帮助?

    有13位网友表示赞同!

坏小子不坏

iOS 开发是未来不可忽视的方向啊!(づ ̄ ³ ̄)づ

    有20位网友表示赞同!

【深入探讨iOS平台下的图形编程技术】相关文章:

1.动物故事精选:寓教于乐的儿童故事宝库

2.《寓教于乐:精选动物故事助力儿童成长》

3.探索动物旅行的奇幻冒险:专为儿童打造的童话故事

4.《趣味动物刷牙小故事》

5.探索坚韧之旅:小蜗牛的勇敢冒险

6.传统风味烤小猪,美食探索之旅

7.探索奇幻故事:大熊的精彩篇章

8.狮子与猫咪的奇妙邂逅:一场跨界的友谊故事

9.揭秘情感的力量:如何影响我们的生活与决策

10.跨越两岸:探索彼此的独特世界

上一篇:巳月庚金命理:详解如何精准选取用神 下一篇:探索成长困境:那些无法长大的教师故事