IOS 中openGL使用教程3(openGL ES 入门篇 | 纹理贴图(texture)使用)
在这篇文章中,我们将学习如何在openGL中使用纹理贴图。
penGL中纹理可以分为1D,2D和3D纹理,我们在绑定纹理对象的时候需要指定纹理的种类。由于本文将以一张图片为例,因此我们为我们的纹理对象绑定一个GL_TEXTURE_2D的纹理。
本文将分为两个部分,一部分是如何通过图片获取一个2D的纹理,另一部分是如何使用一个纹理。
在上一篇中,我们介绍了如何使用shader来绘制一个多边形,本文是基于上一篇的提高,我们也将继续使用shader,对于shader使用不熟的童鞋可以看上一篇。
首先我们来看看如何通过图片获取一张2D的纹理。
+ (GLuint)createTextureWithImage:(UIImage *)image{
//转换为CGImage,获取图片基本参数
CGImageRef cgImageRef = [image CGImage];
GLuint width = (GLuint)CGImageGetWidth(cgImageRef);
GLuint height = (GLuint)CGImageGetHeight(cgImageRef);
CGRect rect = CGRectMake(, , width, height);
//绘制图片
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
void *imageData = malloc(width * height * );
CGContextRef context = CGBitmapContextCreate(imageData, width, height, , width * , colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmap ByteOrder32Big);
CGContextTranslateCTM(context, , height);
CGContextScaleCTM(context, 1.0f, -1.0f);
CGColorSpaceRelease(colorSpace);
CGContextClearRect(context, rect);
CGContextDrawImage(context, rect, cgImageRef);
//纹理一些设置,可有可无
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);
//生成纹理
glEnable(GL_TEXTURE_2D);
GLuint textureID;
glGenTextures(, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, , GL_RGBA, width, height, , GL_RGBA, GL_UNSIGNED_BYTE, imageData);
//绑定纹理位置
glBindTexture(GL_TEXTURE_2D, );
//释放内存
CGContextRelease(context);
free(imageData); return textureID;
}
获取纹理之后,我们就要开始使用纹理了。
和之前绘制多边形的过程一样,我们要先把参数传入shader中。在绘制多边形时我们只需要传入各个顶点的位置,但为了使用纹理,我们需要把纹理传入shader,
此外,还要传入所使用的纹理的范围(使用纹理的哪一部分来映射)。
Vertex Shader代码如下:
attribute vec4 Position;
attribute vec2 TextureCoords;
varying vec2 TextureCoordsOut; void main(void)
{
//用来展现纹理的多边形顶点
gl_Position = Position;
//表示使用的纹理的范围的顶点,因为是2D纹理,所以用vec2类型
TextureCoordsOut = TextureCoords;
}
Fragment Shader代码如下:
precision mediump float; uniform sampler2D Texture;
varying vec2 TextureCoordsOut; void main(void)
{
//获取纹理的像素
vec4 mask = texture2D(Texture, TextureCoordsOut);
gl_FragColor = vec4(mask.rgb, 1.0);
}
注意:
attribute属性只能通过Vertex Shader传入,再传给Fragment Shader,而uniform属性可以直接传入Fragment Shader。
同理的,与绘制多边形的过程一样,我们要编译shader,生成一个glProgram。不同的是,这次我们要传入着色器程序的参数有三个
GLuint fragmentShader = [self compileShader:@"MTShaderFragment"
withType:GL_FRAGMENT_SHADER];
_glProgram = glCreateProgram();
glAttachShader(_glProgram, vertexShader);
glAttachShader(_glProgram, fragmentShader);
glLinkProgram(_glProgram);
glUseProgram(_glProgram); _positionSlot = glGetAttribLocation(_glProgram, "Position");
//uniform类型的参数获取方式不同
_textureSlot = glGetUniformLocation(_glProgram, "Texture");
_textureCoordsSlot = glGetAttribLocation(_glProgram, "TextureCoords");
接下来就到了最后一步,将纹理“贴”到多边形上。
首先将纹理传入,激活索引为1的纹理。表示接下来的操作都是针对纹理1
glActiveTexture(GL_TEXTURE1);
//载入纹理
glBindTexture(GL_TEXTURE_2D, _textureID);
//为当前程序对象指定Uniform变量的值,参数1代表使用的新值(GL_TEXTURE1)
glUniform1i(_textureSlot, );
在指定区域绘制纹理。
注意:用于表示纹理范围时的坐标表示方式与UIKit和openGL的坐标都不同,范围从(0,0)左下到(1,1)右上。
//纹理使用范围顶点
const GLfloat texCoords[] = {
, ,//左下
, ,//右下
, ,//左上
, ,//右上
};
glVertexAttribPointer(_textureCoordsSlot, , GL_FLOAT, GL_FALSE, , texCoords);
glEnableVertexAttribArray(_textureCoordsSlot); //绘图区域顶点
const GLfloat vertices[] = {
-, -, , //左下
, -, , //右下
-, , , //左上
, , }; //右上 glVertexAttribPointer(_positionSlot, , GL_FLOAT, GL_FALSE, , vertices);
glEnableVertexAttribArray(_positionSlot); const GLubyte indices[] = {
,,,
,,
}; glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(indices[]), GL_UNSIGNED_BYTE, indices); [_context presentRenderbuffer:GL_RENDERBUFFER];
下一篇我们会讲解如何进行一些动态的操作和简单滤镜,让手指划过的区域变成灰色。
IOS 中openGL使用教程3(openGL ES 入门篇 | 纹理贴图(texture)使用)的更多相关文章
- android ndk调用OpenGL 实现纹理贴图Texture
android ndk调用OpenGL 实现纹理贴图Texture 时间 2014-06-25 05:24:39 CSDN博客 原文 http://blog.csdn.net/chrisfxs/a ...
- IOS 中openGL使用教程2(openGL ES 入门篇 | 绘制一个多边形)
在上一篇我们学习了如何搭建IOS下openGL的开发环境,接下来我们来学习如何绘制一个多边形. 在2.0之前,es的渲染采用的是固定管线,何为固定管线,就是一套固定的模板流程,局部坐标变换 -> ...
- (转)使用OpenGL显示图像(七)Android OpenGLES2.0——纹理贴图之显示图片
转:http://blog.csdn.net/junzia/article/details/52842816 前面几篇博客,我们将了Android中利用OpenGL ES 2.0绘制各种形体,并在上一 ...
- iOS-----openGL--openGL ES iOS 入门篇3---> 纹理贴图(texture)
在这篇文章中,我们将学习如何在openGL中使用纹理贴图. penGL中纹理可以分为1D,2D和3D纹理,我们在绑定纹理对象的时候需要指定纹理的种类.由于本文将以一张图片为例,因此我们为我们的纹理对象 ...
- OpenGL入门1.4:纹理/贴图Texture
每一个小步骤的源码都放在了Github 的内容为插入注释,可以先跳过 前言 游戏玩家对Texture这个词应该不陌生,我们已经知道了怎么为每个顶点添加颜色来增加图形的细节,但,如果想让图形看起来更真实 ...
- animation-play-state 在 ios 中不生效的解决办法(JS篇)
我们要实现动画的播放和暂停,animation-play-state 在安卓端可以使用,但是在 ios 中不起作用,这时可以使用 js 来实现相同效果. 原理 通过 js 获取当前元素的 transf ...
- IOS 中openGL使用教程1(openGL ES 入门篇 | 搭建openGL环境)
OpenGL版本 iOS系统默认支持OpenGl ES1.0.ES2.0以及ES3.0 3个版本,三者之间并不是简单的版本升级,设计理念甚至完全不同,在开发OpenGL项目前,需要根据业务需求选择合适 ...
- IOS 中openGL使用教程4(openGL ES 入门篇 | 离屏渲染)
通常情况下,我们使用openGL将渲染好的图片绘制到屏幕上,但有时候我们不想显示处理结果,这时候就需要使用离屏渲染了. 正常情况下,我们将屏幕,也就是一个CAEAGLLayer对象作为渲染目标,离屏渲 ...
- sql语句中出现笛卡尔乘积 SQL查询入门篇
2014-12-29 凡尘工作室 阅 34985 转 95 本篇文章中,主要说明SQL中的各种连接以及使用范围,以及更进一步的解释关系代数法和关系演算法对在同一条查询的不同思路. 多表连接简介 ...
随机推荐
- 《Android深度探索HAL与驱动开发》第三章阅读心得
Git是Linux内核代码对源代码进行管理的软件,他的各方面要优与其他同类的源代码管理软件. 安装Git后,查看Git文档在Linux下可以直接使用man命令看指令的帮助文档.安装git-doc后会安 ...
- dandelion datatables : Page index must not be less than zero!
java.lang.IllegalArgumentException: Page index must not be less than zero! at org.springframework.da ...
- POJ1986 Distance Queries (LCA)(倍增)
Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 12950 Accepted: 4577 ...
- apk安全测试思路
一: apk安全测试 对于一款android的apk程序,主要进行的测试分两部分: 1) 接口测试 ---接口测试实际上是常见的web安全测试 2) android组件测试 --组件测试实际上是and ...
- 好的bootstrap文章
http://www.cnblogs.com/gamehiboy/p/5176618.html http://www.cnblogs.com/landeanfen/p/5821192.html htt ...
- MYSQL权限表user操作
MYSQL权限表user cmd中进人mysql找到mysql安装目录 E:\wamp\bin\mysql\mysql5.6.12\bin>mysql.exe -u 用户名 - ...
- 崽崽帮www.zaizaibang.com精选14
[行走贵州]爽爽贵阳,乐活天堂! 北京儿童医院将建遗传代谢病专科医院 [山东十大最难懂方言]原来青岛话还是很好懂滴 ❤如果南宁的儿童医院长这样…… 成都三所小学入围中国百强小学名单 [乐湖新闻]学习中 ...
- System.Data.OleDb操作access数据库类,【bubuko.com】
access数据库在应用了System.Data.OleDb后操作会很方便,这是一个常用的数据库操作类,其中两个方法,一个是返回datatable的,一个是执行sql语句返回影响记录的(一般是inse ...
- 用户输入函数--raw_input、input
1.raw_input python2.7用户输入字符串的话用raw_input.如果使用input输入字符串的话需要先把字符串放到变量中才可,但是用input输入数字的话是可以直接输入的,所以说在p ...
- Async Programming - 1 async-await 糖的本质(1)
这一个系列的文章主要来讲 C# 中的语言特性 async-await 在语言层面的本质,我们都知道 await 是编译器进行了一个 rewrite,然而这个 rewrite 并不是直接 rewrite ...