OpenGLES 1.1教程(四)-纹理映射
2012-10-12 10:40
375 查看
http://www.helmsmansoft.com/index.php/archives/1536
继续哈,从前面的几篇文章里,可以在三维空间里绘制出一个z轴为0的平面图形,这样绘制出来的东西看起来没什么意思,所以本课来介绍下“纹理映射”,这是一个将图像(纹理)应用到原始图像或图形的过程。它的基本概念:对每个定义多边形中的一个顶点,还得提供一个顶点来定义纹理中的一个点。然后将此信息提供给OpenGL ES ,OpenGL ES执行一系列复杂的工作以使纹理和多边形匹配,并在多边形内将纹理渲染出来。
纹理坐标:用于在纹理内部确定位置。范围为0到1.
本课继续使用前面课程所建立的模板,如果您还没有下载此模板,可以在本站查看前几篇文章并下载模板。
言归正传,继续我们的课程风格,用代码说事,在RenderView.h里添加属性
在RenderView.m文件里添加如下代码:
render方法修改如下:
render内的注释为new的是新添加的代码。
下面来具体解释下上面所用到的方法:
上面很多都加了详细的注释,这里说下关于OpenGL ES纹理映射的一些相关内容:
图像大小:在OpenGL ES中所有纹理大小必须为2的幂,也就是说,图像的高度和宽度应该等于以下的值之一
2 4 8 16 32 64 128 256 512 1024
高度和宽度不必相同。PS:iPhone3G,iPhone 4和iPad都支持2048*2048的纹理尺寸
如果需要的图片不是以上的大小,需要使用程序进行处理,使其符合以上尺寸。
glTexImage2D这个方法的几个参数:
第一个参数:目标纹理,必须为GL_TEXTURE_2D
第二个参数:细节程度。0是基本图像水平。 n级为mipma中的第n个缩小的图像。必须大于等于0.
第三个参数:纹理中的颜色组件,必须和之后的颜色参数相同。
第四个参数:纹理图像的宽度
第五个参数:纹理图像的高度
第六个参数:边框的宽度,必须为0
第七个参数:像素数据的格式
第八个参数:像素数据中使用的数据类型
第九个参数:内存中指向图像数据的指针
此命令发出后,imageData实力变量中的图像数据将被加载到OpenGL ES并与当前绑定的纹理关联。
到此运行程序,界面效果如下:
继续哈,从前面的几篇文章里,可以在三维空间里绘制出一个z轴为0的平面图形,这样绘制出来的东西看起来没什么意思,所以本课来介绍下“纹理映射”,这是一个将图像(纹理)应用到原始图像或图形的过程。它的基本概念:对每个定义多边形中的一个顶点,还得提供一个顶点来定义纹理中的一个点。然后将此信息提供给OpenGL ES ,OpenGL ES执行一系列复杂的工作以使纹理和多边形匹配,并在多边形内将纹理渲染出来。
纹理坐标:用于在纹理内部确定位置。范围为0到1.
本课继续使用前面课程所建立的模板,如果您还没有下载此模板,可以在本站查看前几篇文章并下载模板。
言归正传,继续我们的课程风格,用代码说事,在RenderView.h里添加属性
GLuint textures[1];
在RenderView.m文件里添加如下代码:
//添加下面的方法 //载入纹理 - (void)loadTexture { CGImageRef textureImage = [UIImage imageNamed:@"texture.png"].CGImage;//通过CGImage获取被UIImage加载的底层位图图数据,存储在CGImageRef结构体中 if(!textureImage){ //判断是否加载成功 NSLog(@"Load the Image failed!"); return; } NSInteger textImageWidth = CGImageGetWidth(textureImage); //获取图片数据 宽度 NSInteger textImageHeight = CGImageGetHeight(textureImage); //获取图片数据 高度 GLubyte *imageData = (GLubyte *)malloc(textImageWidth*textImageHeight*4); //分配textImageWidth*textImageHeight*4字节空间,并返回指向这块内存的指针,存储在GLubyte中 CGContextRef textureContext = CGBitmapContextCreate(imageData, textImageWidth, textImageHeight, 8, textImageWidth*4, CGImageGetColorSpace(textureImage), kCGImageAlphaPremultipliedLast); //创建位图语境, CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)textImageWidth, (float)textImageHeight), textureImage); ///* Draw `image' in the rectangular area specified by `rect' in the context`c'. The image is scaled, if necessary, to fit into `rect'. */ CGContextRelease(textureContext); //释放创建的语境 glGenTextures(1, &textures[0]); //创建文理名称,这里是创建一个文理,也可以创建多个,第一个参数为文理个数 glBindTexture(GL_TEXTURE_2D, textures[0]); //绑定纹理,第一个参数为作用目标,在O盆GLES里必须使用GL_TEXTURE_2D,因为OpenGLES只支持这个,第二个为需要绑定的纹理名称,即上面创建的 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textImageWidth, textImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);//将图像数据加载到纹理中 free(imageData);//释放内存 /*下面两行为设置纹理相关参数,GL_LINEAR参数能呈现一个平滑的、消除了锯齿的外观*/ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //图像被缩小时GL_TEXTURE_MIN_FILTER, glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //图像被放大时GL_TEXTURE_MAG_FILTER glEnable(GL_TEXTURE_2D); //开启2D纹理贴图功能 }
render方法修改如下:
//渲染方法 - (void)render { static GLfloat rotation = 0.0; //角度 static CGFloat spinnySquareVertices[12] = { -0.5f, -0.5f, -1, 0.5f, -0.5f, -1, -0.5f, 0.5f, -1, 0.5f, 0.5f, -1, }; // static CGFloat spinnSquareColor[] = { // // 255,255,0,255, // 0,255,255,255, // 0,0,0,0, // 255,0,255,255, // // }; const GLshort square[] = { 0,0, 1,0, 0,1, 1,1 }; glClearColor(0.1f, 0.8f, 1.0f, 1.0f); //设置清屏颜色 glClear(GL_COLOR_BUFFER_BIT); //清屏 glViewport(0, 0, backingWidth, backingHeight); //设置视口 glLoadIdentity(); //清空当前矩阵,还原默认矩阵 glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f); //正交模式下可视区域 glColor4f(1.0, 1.0, 1.0, 1.0); //绘制的颜色 glVertexPointer(3, GL_FLOAT, 0, spinnySquareVertices); //确定使用的顶点坐标数列的位置和尺寸 glEnableClientState(GL_VERTEX_ARRAY); //启动独立的客户端功能,告诉OpenGL将会使用一个由glVertexPointer定义的定点数组 // glColorPointer(4, GL_FLOAT, 0, spinnSquareColor); // glEnableClientState(GL_COLOR_ARRAY); glTexCoordPointer(2, GL_SHORT, 0, square); //new //纹理坐标.参数含义跟以上的方法大相迳庭 glEnableClientState(GL_TEXTURE_COORD_ARRAY); //new // glShadeModel(GL_FLOAT); glRotatef(rotation, 0.0, 0.0, 1.0); //旋转 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); //进行连续不间断的渲染,在渲染缓冲区有了一个准备好的要渲染的图像 glDisableClientState(GL_TEXTURE_COORD_ARRAY); rotation += 0.5; [_context presentRenderbuffer:GL_RENDERBUFFER_OES]; //将渲染缓冲区的内容呈现到屏幕上 }
render内的注释为new的是新添加的代码。
下面来具体解释下上面所用到的方法:
上面很多都加了详细的注释,这里说下关于OpenGL ES纹理映射的一些相关内容:
图像大小:在OpenGL ES中所有纹理大小必须为2的幂,也就是说,图像的高度和宽度应该等于以下的值之一
2 4 8 16 32 64 128 256 512 1024
高度和宽度不必相同。PS:iPhone3G,iPhone 4和iPad都支持2048*2048的纹理尺寸
如果需要的图片不是以上的大小,需要使用程序进行处理,使其符合以上尺寸。
glTexImage2D这个方法的几个参数:
第一个参数:目标纹理,必须为GL_TEXTURE_2D
第二个参数:细节程度。0是基本图像水平。 n级为mipma中的第n个缩小的图像。必须大于等于0.
第三个参数:纹理中的颜色组件,必须和之后的颜色参数相同。
第四个参数:纹理图像的宽度
第五个参数:纹理图像的高度
第六个参数:边框的宽度,必须为0
第七个参数:像素数据的格式
第八个参数:像素数据中使用的数据类型
第九个参数:内存中指向图像数据的指针
此命令发出后,imageData实力变量中的图像数据将被加载到OpenGL ES并与当前绑定的纹理关联。
到此运行程序,界面效果如下:
相关文章推荐
- OpenGLES 1.1教程(四)-纹理映射
- Direct3D 10教程7:纹理映射和常量缓存
- opengl 教程(16) 纹理映射
- Directx11教程40 纹理映射(10)
- OpenGL教程之纹理映射
- OpenGLES 1.1教程(二)-简单图形的绘制
- NeHe OpenGL教程 第六课:纹理映射
- 【Visual C++】游戏开发笔记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)
- Directx11教程(33) 纹理映射(3)
- 【Visual C++】游戏开发笔记四十三 浅墨DirectX教程十一 为三维世界添彩:纹理映射技术(二)
- 【Qt OpenGL教程】06:纹理映射
- 【Visual C++】游戏开发笔记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)
- opengl 教程(16) 纹理映射
- 【Visual C++】游戏开发笔记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)
- 【Visual C++】游戏开发笔记四十三 浅墨DirectX教程十一 为三维世界添彩:纹理映射技术(二)
- NeHe的opengl教程delphi版(6)----纹理映射(贴图)
- 西蒙iphone-OpenGL ES 教程-05 :纹理映射我们的矩形
- opengles(五) 纹理映射
- android OpenGLES开发 第五课 纹理映射
- 【Visual C++】游戏开发笔记四十三 浅墨DirectX教程十一 为三维世界添彩:纹理映射技术(二)