在上一文中我们说到,苹果提供了与EAGL作为操作系统与OpenGL ES的接口,下面我们来看一下如何使用这个接口实现一个简单绘制功能。
1、初始化视图
GLKit使用中的视图显示依赖于GLKView,所以我们在做承载视图是有两种方法,第一个自己创建一个GLKView加入到自己的视图上,第二个使用GLKViewController。
_glView = [[GLKView alloc] initWithFrame:self.view.bounds];
_glView.delegate = self;
[self.view addSubview:_glView];
2、初始化配置信息
1.初始化上下文(
/*
EAGLContext 是苹果iOS平台下实现OpenGLES 渲染层.
kEAGLRenderingAPIOpenGLES1 = 1, 固定管线
kEAGLRenderingAPIOpenGLES2 = 2, 可编程管线
kEAGLRenderingAPIOpenGLES3 = 3, ES2的扩展 */
_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
2.设置EAGLContext
[EAGLContext setCurrentContext:_context];
3.设置glView的context
_glView.context = _context;
4.设置颜色缓存区格式以及深度缓存区格式
// drawableColorFormat: 颜色缓存区格式.
_glView.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
// drawableDepthFormat: 深度缓存区格式
_glView.drawableDepthFormat = GLKViewDrawableDepthFormat16;
OpenGL ES 又一个缓存区,用于储存在屏幕上显示的颜色,可以用来drawableColorFormat设置缓存区中每个像素的颜色格式。 GLKViewDrawableColorFormatRGBA8888 = 0,默认缓存区中每个像素的最小组成部分RGBA使用8个bit(每个像素4个字节,4*8)。如果开发中允许更小范围的颜色可以设置为GLKViewDrawableColorFormatRGB565,可以降低app的资源消耗。
5.添加背景颜色
glClearColor(1, 0, 0, 1.0);
3、设置顶点数据
1、初始化顶点数组(坐标顶点,纹理坐标)
GLfloat vertexData[] = {
1, -0.5, 0.0f, 1.0f, 0.0f, //右下
1, 0.5, -0.0f, 1.0f, 1.0f, //右上
-1, 0.5, 0.0f, 0.0f, 1.0f, //左上
1, -0.5, 0.0f, 1.0f, 0.0f, //右下
-1, 0.5, 0.0f, 0.0f, 1.0f, //左上
-1, -0.5, 0.0f, 0.0f, 0.0f, //左下
};
2、开辟顶点缓存区
(1)创建顶点缓存区标识符号
GLuint bufferID;
glGenBuffers(1, &bufferID);
(2)绑定顶点缓存区
glBindBuffer(GL_ARRAY_BUFFER, bufferID);
(3)将顶点数组数据copy到顶点缓存区
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
(4)打开读取通道
在iOS中,默认情况下,所有顶点着色器的属性变量都是关闭的,意味着顶点数据在着色器端不可用,所以必须由glEnableVertexAttribArray方法打开通道,指定访问属性。
//顶点坐标数据
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 0);
//纹理坐标数据
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 3);
参数1:指定要修改的顶点属性(是顶点,还是纹理)
参数2:每次读取的数量 (如position是由3个(x,y,z)组成,而颜色是4个(r,g,b,a),纹理则是2个.
参数3:指定数组中数据类型。
参数4:指定被访问时,固定点数据是否被归一化(GL_True)或者直接转换为固定点值(GL_FALSE)
参数5:指定连续点属性之间的偏移量
参数6:指定第一个数据的指针
4、读取纹理信息
1、获取纹理路径
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"模特切图" ofType:@"png"];
2、设置纹理参数
//纹理的坐标原点在左下角,图片显示的原点在左上角
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1),GLKTextureLoaderOriginBottomLeft, nil];
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
3、使用GLKit的GLKBaseEffect 完成着色器工作
cEffect = [[GLKBaseEffect alloc]init];
cEffect.texture2d0.enabled = GL_TRUE;
cEffect.texture2d0.name = textureInfo.name;
5、实现代理方法
GLKView对象使其成为OpenGL ES的上下文成为当前上下文,并将framebuffer绑定为OpenGL ES呈现命令的目标,然后,委托方位绘制视图内容
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
//1.
glClear(GL_COLOR_BUFFER_BIT);
//2.准备绘制
[cEffect prepareToDraw];
//3.开始绘制
glDrawArrays(GL_TRIANGLES, 0, 6);
}
附效果图: