OpenGL ES

GLKit案例解析

2020-07-28  本文已影响0人  爱看书de图图

  接下来我们用一个案例,来使用GLKit绘制一个旋转的立方体。效果如下:

GIF
  下面我会讲述一下案例流程,代码部分我只列出重要部分,完整案例可以查看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);
上一篇下一篇

猜你喜欢

热点阅读