接下来我们用一个案例,来使用GLKit绘制一个旋转的立方体。效果如下:
下面我会讲述一下案例流程,代码部分我只列出重要部分,完整案例可以查看Demo。
初始化
初始化上下文EAGLContext
,并设置为当前的上下文
//1.创建context
EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
//设置当前context
[EAGLContext setCurrentContext:context];
初始化GLKView
对象,并设置相关属性。
self.glkView = [[GLKView alloc] initWithFrame:frame context:context];
//3.使用深度缓存
self.glkView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
初始化纹理对象GLKTextureInfo
,之前的文章里,我们讲述了各种生成纹理对象的方法,这里我们用CGImage
对象来生成。
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithCGImage:[image CGImage]
options:options
error:NULL];
初始化着色器GLKBaseEffect
,并将纹理对象的名字赋值给着色器
self.baseEffect = [[GLKBaseEffect alloc] init];
self.baseEffect.texture2d0.name = textureInfo.name;
self.baseEffect.texture2d0.target = textureInfo.target;
//开启光照效果
self.baseEffect.light0.enabled = YES;
//漫反射颜色
self.baseEffect.light0.diffuseColor = GLKVector4Make(1, 1, 1, 1);
//光源位置
self.baseEffect.light0.position = GLKVector4Make(-0.5, -0.5, 5, 1);
设置顶点数组,我们这里使用结构体来存放顶点坐标,纹理坐标,以及光照坐标。只列出一个前面的一个面来说明各个坐标的设置。
typedef struct {
GLKVector3 positionCoord; //顶点坐标
GLKVector2 textureCoord; //纹理坐标
GLKVector3 normal; //法线
} CCVertex;
// 前面
self.vertices[0] = (CCVertex){{-0.5, 0.5, 0.5}, {0, 1}, {0, 0, 1}};
self.vertices[1] = (CCVertex){{-0.5, -0.5, 0.5}, {0, 0}, {0, 0, 1}};
self.vertices[2] = (CCVertex){{0.5, 0.5, 0.5}, {1, 1}, {0, 0, 1}};
self.vertices[3] = (CCVertex){{-0.5, -0.5, 0.5}, {0, 0}, {0, 0, 1}};
self.vertices[4] = (CCVertex){{0.5, 0.5, 0.5}, {1, 1}, {0, 0, 1}};
self.vertices[5] = (CCVertex){{0.5, -0.5, 0.5}, {1, 0}, {0, 0, 1}};
然后开辟顶点缓冲区,绑定顶点数组,之前说到iOS
默认关闭attribute
通道,所以我们需要手动开启,并且相关的参数意义在我们之前的文章里都有描述,这里不再赘述。
//开辟顶点缓存区
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
GLsizeiptr bufferSizeBytes = sizeof(CCVertex) * kCoordCount;
glBufferData(GL_ARRAY_BUFFER, bufferSizeBytes, self.vertices, GL_STATIC_DRAW);
//顶点数据
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(CCVertex), NULL + offsetof(CCVertex, positionCoord));
//纹理数据
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(CCVertex), NULL + offsetof(CCVertex, textureCoord));
//法线数据
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(CCVertex), NULL + offsetof(CCVertex, normal));
让立方体自动旋转需要设置定时器,这里可以自由发挥,比较简单,需要注意在代理方法里,开启关闭深度测试,准备绘制等。
//1.开启深度测试
glEnable(GL_DEPTH_TEST);
//2.清除颜色缓存区&深度缓存区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//3.准备绘制
[self.baseEffect prepareToDraw];
//4.绘图
glDrawArrays(GL_TRIANGLES, 0, kCoordCount);