- 浏览: 193874 次
- 性别:
- 来自: 无锡
-
文章分类
最新评论
-
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 1085原文链接地址:http://www.raywenderlich ... -
OpenGL ES for iPhone: Drawing a Circle - Part III
2012-01-13 20:05 951原文地址:http://vormplus.be/b ... -
OpenGL ES for iPhone: Drawing a Circle - Part II
2012-01-13 20:12 1049原文地址:http://vormplus.be/b ... -
OpenGL ES for iPhone: Drawing a Circle - Part I
2012-01-18 12:19 1022原文地址:http://vormplus.be/blog ... -
OpenGL ES 从零开始系列9(完结):四元数
2012-01-18 12:20 2066在进入下一篇关于骨骼动画的文章之前,让我们先花点时间来了解一个 ... -
OpenGL ES 从零开始系列9a:动画基础和关键帧动画
2012-01-18 12:21 2024最初这篇教程我并 ... -
OpenGL ES 从零开始系列08:交叉存取顶点数据
2012-01-18 12:22 1139Technote 2230提出了很多用OpenGL ES来提升 ... -
从零开始学习OpenGL ES之四补遗 – setupView重写
2012-01-18 12:22 956我在从零开始学习OpenGL ES之四 – 光效 ... -
从零开始学习OpenGL ES之七 – 变换和矩阵
2012-01-29 16:03 1779今天的主题是我 ... -
从零开始学习OpenGL ES之六 – 纹理及纹理映射
2012-01-29 16:03 1510在OpenGL ES中另一种为 ... -
从零开始学习OpenGL ES之五 – 材质
2012-01-29 16:04 1716在 上一篇文章,我们讨论了光效的设定以及光效的各种属性 ... -
从零开始学习OpenGL ES之四 – 光效
2012-01-06 00:05 1366继续我们的iPhone OpenGL ES之旅,我们将 ... -
从零开始学习OpenGL ES之三 – 透视
2012-01-06 00:04 1006现在你已经知道O ... -
从零开始学习OpenGL ES之一 – 基本概念
2012-01-02 22:28 1099我曾写过一些文章介绍iPhone OpenGL ES编 ...
相关推荐
作者: (美) 马鲁基-弗伊诺(Marucchi-Foino, R.) 著 ...原作名: Game and Graphics Programming for iOS and Android with OpenGL ES 2.0 译者: 王净 译. 出版年: 2014-2 页数: 288 装帧: 平装 ISBN: 9787302352303
OpenGL ES2.0开发库和OpenGL ES3.0开发库有差别,保留对OpenGL ES2.0开发库的使用 用RAR5.4解压
OpenGL ES 2.0 编程指南中文版详细介绍了OpenGL ES 2.0的编程技术和方法,这是专为移动和嵌入式系统设计的图形API的2.0版本,广泛应用于各种便携式设备和游戏机上。 ### OpenGL ES基础 OpenGL ES(Open Graphics ...
- **帧缓存的区别**:OpenGLES命令对window-system-provided framebuffers的影响最终由分配帧缓存资源的窗口系统控制。窗口系统决定了OpenGL ES在任何特定上下文中的行为。 #### 六、OpenGL ES 2.0与OpenGL 2.0的...
openglES2.0 iPhone版 的教程例子源码,例子源码有注释,是学习iPhone 三维游戏的好教程。
在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 Programming Guide中文版!
《OpenGL ES 《OpenGL ES 2.0 编程指南 中文版》2.0 编程指南 中文版》
《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
在Android系统中,OpenGLES 2.0是用于图形渲染的重要框架,支持3D图形和复杂的视觉效果。本教程旨在帮助开发者从零基础开始掌握OpenGLES 2.0,并通过实例Demo加深理解。 入门篇: 1. **环境配置**:首先,你需要...
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等,它们...