GLKit实战 第02话 三角形

@Daniate  January 29, 2020

整体步骤

本文首发于Daniate的个人网站,文章链接:https://daniate.com/2020/01/29/166.html

绘制出一个图形,大体需要以下步骤:

  1. 创建上下文,并将其指定为当前的上下文
  2. 创建GLKBaseEffect对象,并对其进行相应的配置
  3. 创建并绑定VAO(vertex array object,顶点数组对象)
  4. 创建并绑定VBO(vertex buffer object,顶点缓冲区对象)
  5. 设置顶点数据
  6. 启用顶点属性,并告知其如何使用顶点数据
  7. 在进行每一帧的绘制时,先同步状态,也即调用GLKBaseEffectprepareToDraw方法
  8. 调用glDraw***函数进行绘制

其中,第3步,是被强烈建议使用的,这样可以提高性能,当然,也可以将其忽略。第4、5、6步,可以看作是一大步骤,它们必须都存在。

绘制三角形

先期准备

首先,会继承GLKViewController,并实现- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect方法。

根据上面的步骤,必须有顶点数据才行,因此,先定义一个结构体,用来描述顶点,其中的position,代表了顶点的位置,它属于顶点的一个属性:

typedef struct Vertex {
    GLKVector3 position;
} Vertex;

因为是绘制三角形,至少需要3个顶点,声明一个成员,用来存放顶点数据:

Vertex _vertices[3];

上下文

在视图加载完成后,创建出上下文对象,并将其指定为当前的上下文:

EAGLContext *glCtx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:glCtx];

切记!!!也必须将其赋给GLKViewcontext属性:

glView.context = glCtx;

GLKBaseEffect

考虑到目前的顶点只有位置数据,因此绘制出来的三角形将会是单色的。

useConstantColor被设置为GL_TRUE时,constantColor将会被用作每个顶点的颜色。当useConstantColor被设置为GL_FALSE时,则表明需要启用顶点颜色属性,并为每个顶点提供颜色数据。

GLKBaseEffect.h.jpg

默认情况下,useConstantColorGL_TRUEconstantColor为白色。为了明确,显式地为它们进行赋值。

self.effect = [[GLKBaseEffect alloc] init];
self.effect.useConstantColor = GL_TRUE;
self.effect.constantColor = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f);

创建VBO,设置顶点数据

这一部分,将第4、5、6步放在一起。

创建VBO:

glGenBuffers(1, &_vbo);

绑定VBO:

glBindBuffer(GL_ARRAY_BUFFER, _vbo);

设置顶点数据:

_vertices[0].position = GLKVector3Make( 0.5f,  0.5f, 0.0f);
_vertices[1].position = GLKVector3Make(-0.5f,  0.5f, 0.0f);
_vertices[2].position = GLKVector3Make(-0.5f, -0.5f, 0.0f);
glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices), _vertices, GL_STATIC_DRAW);

启用顶点的位置属性:

glEnableVertexAttribArray(GLKVertexAttribPosition);

告知顶点的位置属性,应该如何使用顶点数据:

glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), NULL + offsetof(Vertex, position));

绘制

在绘制之前,可以设置一下清除色,也即背景颜色,默认情况下,为黑色。虽然绘制的三角形使用的是白色,背景色和三角形的颜色对比明显,可以忽略其设置,但,为了更明确,还是设置一下比较好。

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect方法中,先应用背景色,也即清除颜色缓冲区:

glClear(GL_COLOR_BUFFER_BIT);

然后,同步状态,并绘制三角形:

[self.effect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 3);

这样,一个单色的三角形就出来了。

Pure Triangle.png

彩色三角形

根据上文内容,可以知道,为了让三角形是彩色的,就需要启用顶点颜色属性,并为顶点提供不同的颜色数据。

修改GLKBaseEffect的配置:

self.effect.useConstantColor = GL_FALSE;

删除self.effect.constantColor = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f);

其实,完全不用修改配置信息,因为,当启用顶点颜色属性,并提供颜色数据后,GLKBaseEffect中颜色相关的配置将会被忽略,也就是会失效。

修改Vertex结构体:

typedef struct Vertex {
    GLKVector3 position;
    GLKVector4 color;
} Vertex;

加入了color字段,用于表示顶点颜色。

配置顶点颜色数据:

在调用glBufferData之前,加入:

_vertices[0].color = GLKVector4Make(1.0f, 0.0f, 0.0f, 1.0f);
_vertices[1].color = GLKVector4Make(0.0f, 1.0f, 0.0f, 1.0f);
_vertices[2].color = GLKVector4Make(0.0f, 0.0f, 1.0f, 1.0f);

启用顶点颜色属性:

glEnableVertexAttribArray(GLKVertexAttribColor);

告知顶点的颜色属性,应该如何使用顶点数据:

glVertexAttribPointer(GLKVertexAttribColor, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), NULL + offsetof(Vertex, color));

这样,一个彩色的三角形就完成了:

Colorful Triangle.png

知识共享许可协议
本作品由Daniate采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。


添加新评论