整体步骤
绘制出一个图形,大体需要以下步骤:
- 创建上下文,并将其指定为当前的上下文
- 创建
GLKBaseEffect
对象,并对其进行相应的配置 - 创建并绑定
VAO
(vertex array object
,顶点数组对象) - 创建并绑定
VBO
(vertex buffer object
,顶点缓冲区对象) - 设置顶点数据
- 启用顶点属性,并告知其如何使用顶点数据
- 在进行每一帧的绘制时,先同步状态,也即调用
GLKBaseEffect
的prepareToDraw
方法 - 调用
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];
切记!!!也必须将其赋给GLKView
的context
属性:
glView.context = glCtx;
GLKBaseEffect
考虑到目前的顶点只有位置数据,因此绘制出来的三角形将会是单色的。
当useConstantColor
被设置为GL_TRUE
时,constantColor
将会被用作每个顶点的颜色。当useConstantColor
被设置为GL_FALSE
时,则表明需要启用顶点颜色属性,并为每个顶点提供颜色数据。
默认情况下,useConstantColor
为GL_TRUE
,constantColor
为白色。为了明确,显式地为它们进行赋值。
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);
这样,一个单色的三角形就出来了。
彩色三角形
根据上文内容,可以知道,为了让三角形是彩色的,就需要启用顶点颜色属性,并为顶点提供不同的颜色数据。
修改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));
这样,一个彩色的三角形就完成了:
本作品由Daniate采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。