- 浏览: 191732 次
- 性别:
- 来自: 无锡
文章分类
最新评论
-
luoqianjiang:
很好,谢谢
一些iOS高效开源类库 -
sgjsdf5944:
没看明白。。。。。。。。。。
UIWebView打开doc、pdf文件 -
593864589:
mac 上不支持呢?
cocos2d 粒子设计器 -
寻墨小楼:
多谢了...正在弄这个。
mysql for mac 安装和基本操作 -
yueliancao:
楼主如何联系啊 我的MAC系统 #LoadModule php ...
mac OS x中配置apache + php + mysql
原文链接地址:http://www.raywenderlich.com/4404/opengl-es-2-0-for-iphone-tutorial-part-2-textures 免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播。同时,转载时不要移除本申明。如产生任何纠纷,均与本博客所有人、发表该翻译稿之人无任何关系。谢谢合作! 教程截图: 在这个系列教程中,我们的目标是帮助大家揭开OpenGL ES 2.0的神秘面纱,同时给大家提供一个手把手的例子,能带领大家步入OpenGL ES 2.0的开发世界。 如果你还没有上一篇教程的工程的话,你可以从这里先下载样例工程。 下载完后,编译并运行工程,你将会看到一个旋转的立方体: 现在,我们的立方体看起来是红绿相间的,因为我们指定顶点的颜色就是这么做的---还没有使用任何纹理贴图。
读取像素数据 我们的第一步就是把图片数据读取到OpenGL中来。
这里有许多代码,让我们一段一段来看:- (GLuint)setupTexture:(NSString *)fileName { // 1 CGImageRef spriteImage = [UIImage imageNamed:fileName].CGImage; if (!spriteImage) { NSLog(@"Failed to load image %@", fileName); exit(1); } // 2 size_t width = CGImageGetWidth(spriteImage); size_t height = CGImageGetHeight(spriteImage); GLubyte * spriteData = (GLubyte *) calloc(width*height*4, sizeof(GLubyte)); CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4, CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast); // 3 CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage); CGContextRelease(spriteContext); // 4 GLuint texName; glGenTextures(1, &texName); glBindTexture(GL_TEXTURE_2D, texName); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData); free(spriteData); return texName; }
另一种非常简单的思考方式是,把GL_NEAREST看作是“pixel art-like”,而GL_LINEAR是“平滑”。 使用纹理数据 这里,我们声明了一个新的属性,叫做TexCoordIn。记住,属性就是一个值,你可以把它赋值给每一个顶点。因此,对于每一个顶点,我们为它指定需要映射的纹理坐标。attribute vec4 Position; attribute vec4 SourceColor; varying vec4 DestinationColor; uniform mat4 Projection; uniform mat4 Modelview; attribute vec2 TexCoordIn; // New varying vec2 TexCoordOut; // New void main(void) { DestinationColor = SourceColor; gl_Position = Projection * Modelview * Position; TexCoordOut = TexCoordIn; // New } 纹理坐标看起来有点奇怪,它们的取值范围总是0-1.因此(0,0)就代表纹理的左下角,而(1,1)则代表纹理的右上角。 但是,CoreGraphics在加载图片的时候会垂直翻转图片。所以,在代码中(0,1)是左下角,而(0,0)是左上角,够奇怪了吧! 我们也创建一个新的varying,叫做TexCoordOut,并且把TexCoordIn赋值给它。记住,一个varying也是一个值,OpenGL在进行片断着色的时候会为我们自动进行运算,得到正确的坐标点。因此,打个比方,如果我们把一个正方形的左下角映射纹理坐标为(0,0),而把右上角映射为(1,0)。如果我们在渲染左下角和右上角中间的某个像素的时候,片断着色器会自动计算得到(0.5,0)。 接下来,替换掉SimpleFragment.glsl: 之前我们老是把目标色直接赋值给输出色--现在,我们把这个目标色乘以纹理图片中相应的坐标点处的颜色。texture2D是Opengl内置的一个函数,它可以得到一个纹理。varying lowp vec4 DestinationColor; varying lowp vec2 TexCoordOut; // New uniform sampler2D Texture; // New void main(void) { gl_FragColor = DestinationColor * texture2D(Texture, TexCoordOut); // New } 现在,我们新的shaders准备就绪了,让我们来使用它们吧!打开OpenGLView.h,然后添加下面几个实例变量: 这些变量来用保存我们之前添加进来的两张图片的纹理名字,同时声明了新的输入属性槽(input attribute slot)和一个新的纹理统一槽(new texture uniform slot)。GLuint _floorTexture; GLuint _fishTexture; GLuint _texCoordSlot; GLuint _textureUniform; 然后打开OpenGLView.m,并作如下修改: 基于我们前面教程中所介绍的内容,这里的大部分内容应该非常容易理解。// Add texture coordinates to Vertex structure as follows typedef struct { float Position[3]; float Color[4]; float TexCoord[2]; // New } Vertex; // Add texture coordinates to Vertices as follows const Vertex Vertices[] = { {{1, -1, 0}, {1, 0, 0, 1}, {1, 0}}, {{1, 1, 0}, {1, 0, 0, 1}, {1, 1}}, {{-1, 1, 0}, {0, 1, 0, 1}, {0, 1}}, {{-1, -1, 0}, {0, 1, 0, 1}, {0, 0}}, {{1, -1, -1}, {1, 0, 0, 1}, {1, 0}}, {{1, 1, -1}, {1, 0, 0, 1}, {1, 1}}, {{-1, 1, -1}, {0, 1, 0, 1}, {0, 1}}, {{-1, -1, -1}, {0, 1, 0, 1}, {0, 0}} }; // Add to end of compileShaders _texCoordSlot = glGetAttribLocation(programHandle, "TexCoordIn"); glEnableVertexAttribArray(_texCoordSlot); _textureUniform = glGetUniformLocation(programHandle, "Texture"); // Add to end of initWithFrame _floorTexture = [self setupTexture:@"tile_floor.png"]; _fishTexture = [self setupTexture:@"item_powerup_fish.png"]; // Add inside render:, right before glDrawElements glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7)); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, _floorTexture); glUniform1i(_textureUniform, 0); 这里唯一值得详细指出来的就是最后3行代码。这也是我们如何把之前在片断着色器中定义的Texture uiniform映射到我们代码中的texture中来的。 首先,我们激活我们想要加载进入的纹理单元。在IOS上面,我们可以拥有至少2个纹理单元,最多是8个。当我们一次需要对不止一个纹理进行计算的时候,这个就发挥作用了。然后,在本教程中,我们并不需要多于一个的纹理单元,所以我们只需要第一个纹理单元(GL_TEXTURE0)。 然后,我们把纹理绑定到当前的纹理单元中(GL_TEXTURE0)。最后,把纹理单元0的索引设置为_textureUniform。 注意:其实第1和3句调用其实并不是必须的,有时候,你可能会看见别人的代码里面可能并没有包含这几行代码。这是因为我们假设GL_TEXTURE0就是当前激活的纹理单元了,我们也不需要设置uniform,因为它默认就是0.我在这篇教程中添加这3行代码的意思是方便初学者更好地理解代码。 编译并运行代码,这时你可以看到一个拥有纹理贴图的立方体啦! 恩。。。这个立方体的正面看起来还算ok,但是其它面看起来有点被拉伸了---这是怎么回事呢?
修复拉伸效果 这个问题的原因是,因为我们当前只是为每一个顶点设置一个纹理坐标,然后重复使用这些顶点。举个例子,我们把第一面的左下角映射到(0,0)。但是,在左边那一面,同样的顶点数据却变成了右上角,所以这时候如果使用(0,0)纹理坐标去贴图的话就没有意义了,这时候应该要使用(1,0)。(为什么不是(1,1),因为图片垂直翻转了!!!) 在OpenGL里面,你不能简单的把一个顶点当成是一个顶点坐标---而应该是把坐标、颜色和纹理坐标绑定到一起,统一属于某一个顶点。 继续并把你的顶点和索引数组替换成下面的内容,它为每一面都定义了顶点坐标、颜色和纹理坐标数据。 就和上一篇教程一样,我首先在纸上把这些数据先用笔标记出来,然后再写代码记录下来---读者最好亲自动手实践一下,这是一个很好的机会!!!#define TEX_COORD_MAX 1 const Vertex Vertices[] = { // Front {{1, -1, 0}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}}, {{1, 1, 0}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}}, {{-1, 1, 0}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}}, {{-1, -1, 0}, {0, 0, 0, 1}, {0, 0}}, // Back {{1, 1, -2}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}}, {{-1, -1, -2}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}}, {{1, -1, -2}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}}, {{-1, 1, -2}, {0, 0, 0, 1}, {0, 0}}, // Left {{-1, -1, 0}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}}, {{-1, 1, 0}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}}, {{-1, 1, -2}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}}, {{-1, -1, -2}, {0, 0, 0, 1}, {0, 0}}, // Right {{1, -1, -2}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}}, {{1, 1, -2}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}}, {{1, 1, 0}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}}, {{1, -1, 0}, {0, 0, 0, 1}, {0, 0}}, // Top {{1, 1, 0}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}}, {{1, 1, -2}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}}, {{-1, 1, -2}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}}, {{-1, 1, 0}, {0, 0, 0, 1}, {0, 0}}, // Bottom {{1, -1, -2}, {1, 0, 0, 1}, {TEX_COORD_MAX, 0}}, {{1, -1, 0}, {0, 1, 0, 1}, {TEX_COORD_MAX, TEX_COORD_MAX}}, {{-1, -1, 0}, {0, 0, 1, 1}, {0, TEX_COORD_MAX}}, {{-1, -1, -2}, {0, 0, 0, 1}, {0, 0}} }; const GLubyte Indices[] = { // Front 0, 1, 2, 2, 3, 0, // Back 4, 5, 6, 4, 5, 7, // Left 8, 9, 10, 10, 11, 8, // Right 12, 13, 14, 14, 15, 12, // Top 16, 17, 18, 18, 19, 16, // Bottom 20, 21, 22, 22, 23, 20 }; 注意,我们这一次重复了很多数据。我现在还没有找到一种更好的方式来做这件事,希望有牛人可以指出来,大家一起学习一下:) 编译并运行,这时我们有一个看起来更漂亮的立方体啦! 重复纹理 在OpenGL里面,如果你喜欢的话,你可以把一张图片重复地贴在某一个表面上。但是,保证重复纹理时能够拼接得很好,我们需要一些无缝纹理。 有了纹理之后,我们在OpenGLView.m里面定义下面的宏:
因此,现在,我们给立方体每一个表面从左下角(0,0)到右上角(4,4)都映射了纹理贴图。 当映射纹理坐标的时候,它的行为看起来好像是1的模---比如,如果你的纹理坐标是1.5,那么映射的纹理坐标就会是0.5. 编译并运行,现在你可以看到立方体上有非常好看的重复纹理啦。 注意: 这个能够工作的原因是因为GL_TEXTURE_WRAP_S 和GL_TEXTURE_WRAP_T 默认值是GL_REPEAT 。如果你不想让纹理这样子重复的知,你可以调用函数glTexParameteri来覆盖默认的行为。
|
发表评论
-
OpenGL ES2.0 – Iphone开发指引
2012-01-13 20:03 1049原文链接地址:http://www.raywenderlich ... -
OpenGL ES for iPhone: Drawing a Circle - Part III
2012-01-13 20:05 939原文地址:http://vormplus.be/b ... -
OpenGL ES for iPhone: Drawing a Circle - Part II
2012-01-13 20:12 1033原文地址:http://vormplus.be/b ... -
OpenGL ES for iPhone: Drawing a Circle - Part I
2012-01-18 12:19 1000原文地址:http://vormplus.be/blog ... -
OpenGL ES 从零开始系列9(完结):四元数
2012-01-18 12:20 2034在进入下一篇关于骨骼动画的文章之前,让我们先花点时间来了解一个 ... -
OpenGL ES 从零开始系列9a:动画基础和关键帧动画
2012-01-18 12:21 1978最初这篇教程我并 ... -
OpenGL ES 从零开始系列08:交叉存取顶点数据
2012-01-18 12:22 1128Technote 2230提出了很多用OpenGL ES来提升 ... -
从零开始学习OpenGL ES之四补遗 – setupView重写
2012-01-18 12:22 944我在从零开始学习OpenGL ES之四 – 光效 ... -
从零开始学习OpenGL ES之七 – 变换和矩阵
2012-01-29 16:03 1743今天的主题是我 ... -
从零开始学习OpenGL ES之六 – 纹理及纹理映射
2012-01-29 16:03 1478在OpenGL ES中另一种为 ... -
从零开始学习OpenGL ES之五 – 材质
2012-01-29 16:04 1696在 上一篇文章,我们讨论了光效的设定以及光效的各种属性 ... -
从零开始学习OpenGL ES之四 – 光效
2012-01-06 00:05 1340继续我们的iPhone OpenGL ES之旅,我们将 ... -
从零开始学习OpenGL ES之三 – 透视
2012-01-06 00:04 967现在你已经知道O ... -
从零开始学习OpenGL ES之一 – 基本概念
2012-01-02 22:28 1087我曾写过一些文章介绍iPhone OpenGL ES编 ...
相关推荐
作者: (美) 马鲁基-弗伊诺(Marucchi-Foino, R.) 著 ...原作名: Game and Graphics Programming for iOS and Android with OpenGL ES 2.0 译者: 王净 译. 出版年: 2014-2 页数: 288 装帧: 平装 ISBN: 9787302352303
- **帧缓存的区别**:OpenGLES命令对window-system-provided framebuffers的影响最终由分配帧缓存资源的窗口系统控制。窗口系统决定了OpenGL ES在任何特定上下文中的行为。 #### 六、OpenGL ES 2.0与OpenGL 2.0的...
OpenGL ES 2.0 编程指南中文版详细介绍了OpenGL ES 2.0的编程技术和方法,这是专为移动和嵌入式系统设计的图形API的2.0版本,广泛应用于各种便携式设备和游戏机上。 ### OpenGL ES基础 OpenGL ES(Open Graphics ...
openglES2.0 iPhone版 的教程例子源码,例子源码有注释,是学习iPhone 三维游戏的好教程。
OpenGL ES2.0开发库和OpenGL ES3.0开发库有差别,保留对OpenGL ES2.0开发库的使用 用RAR5.4解压
在Android系统中,OpenGLES2.0是广泛用于2D和3D图形渲染的标准,它提供了丰富的图形功能,为游戏开发提供了强大的支持。下面我们将深入探讨OpenGLES2.0在Android游戏开发中的关键知识点。 1. **顶点着色器(Vertex ...
OPENGLES 2.0 开发库 OPENGLES 2.0 开发库 OPENGLES 2.0 开发库
OpenGL ES 2.0是一种广泛应用于移动设备和嵌入式系统的图形API,是OpenGL(Open Graphics Library)的一个子集,专门用于3D图形和游戏开发。OpenGL ES 2.0支持的特性包括: 1. 着色器程序:OpenGL ES 2.0放弃了固定...
最后,了解如何与硬件加速的OpenGLES API交互,以及熟悉GLSL语言(OpenGL Shading Language),是成为OpenGL ES 2.0专家的必经之路。通过编写高效、可读性强的着色器代码,可以创造出各种复杂的视觉效果,实现令人...
开发 OpenGL ES 2.0 的应用程序,不要担心技术细节,懂得怎么去工作。 OpenGL ES 2.0 包含两部分:OpenGL ES 2.0 API 说明和 OpenGL ES 着色器语言说明, 图 1_1 显示 OpenGL ES 2.0 图像管线,图 1 _1 中的的着色器...
《OpenGL ES 2.0 编程指南 中文版》
### OpenGL ES 2.0 规格书解析 #### 一、OpenGL ES 2.0 概述 OpenGL ES(OpenGL for Embedded Systems)是OpenGL的一个分支版本,专门针对嵌入式系统设计,如智能手机和平板电脑等移动设备。OpenGL ES 2.0是该系列...
第3章~第10章介绍了基于OpenGL ES 2.0进行3D应用开发的一些必知必会的基本知识;第11章~第15章介绍了一些高级特效的实现方法;第16章~第17章介绍了3D游戏开发中相关的一些物理、碰撞检测知识以及常用的3D物理引擎...
OpenGL es 2.0教程 OpenGL es 2.0教程 附带源码和库 part2: http://download.csdn.net/source/3152396
OpenGL ES 2.0 Programming Guide中文版!
在Android系统中,OpenGLES 2.0是用于图形渲染的重要框架,支持3D图形和复杂的视觉效果。本教程旨在帮助开发者从零基础开始掌握OpenGLES 2.0,并通过实例Demo加深理解。 入门篇: 1. **环境配置**:首先,你需要...
《OpenGL ES 《OpenGL ES 2.0 编程指南 中文版》2.0 编程指南 中文版》
13.6 opengl es 1.x与opengl es 2.0实现方案的对比 363 13.7 本章小结 364 第14章 片元着色器的妙用 365 14.1 程序纹理技术 365 14.1.1 砖块着色器 365 14.1.2 沙滩球着色器 367 14.2 数字图像...
如题,Android 3D游戏开发技术宝典:OpenGL ES 2.0书中的全部源代码。该书由浅入深的讲解了OpenGL ES 2.0在3D游戏开发中的各个方面,还给出了BN赛艇、火力篮球、夜鹰行动三个经典游戏的全部源代码。
- 实例代码:`opengles_sample`可能包含了一些实际的示例代码,通过分析和运行这些代码,可以加深对OpenGL ES 2.0的理解。 - 在线教程:网上有许多教程和指南,如LearnOpenGLES.com、OpenGL-Tutorial.org等,它们...