GLKit初探

99 阅读3分钟

在上一文中我们说到,苹果提供了与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);

}

附效果图: