前言:
OpenGL ES是跨平台的可应用于WindowsPhone、Andriod、iOS 等移动平台。
GLKit和OpenGL ES的关系:
GLKit是在iOS 开发中OpenGL ES 的框架,其地位等同于AVFoundation、UIKit等框架。
GLKit对OpenGL ES进行封装、极大地简化了我们使用OpenGL ES的步骤和代码。
其实我们常用的CoreAnimation也是对OpenGL ES进行了封装。

其实上面这张图并非十分准确,因为OpenGL ES主要作用于GPU,其次还会作用于CPU,如:从CPU数据进行数据缓存,协调GPU和CPU的数据交换。
涉及到的英语:
我们需要掌握一些简单地英文,方便我们记忆,我整理到常用的主要有这几个
英语 | 汉语 | 发音
----------|-----------
Vector | 矢量 | ['vektə]
Coords | 坐标| ['kurz]
Scene | 场景 | [siːn]
position | 位置 | [pə'zɪʃ(ə)n]
Vertex |顶点 | ['vɜːteks]
vertices| vertex的复数|--
buffer|缓冲|['bʌfə]
Gen(generate)|使形成;发生;生殖;产生物理反应|['dʒenəreɪt]
Bind|绑;约束|[baɪnd]
Elements|n. 基础;原理|['elimənts]
绘制图形的7个步骤:
步骤 | C语言函数 |
---|---|
1.生成独一无二的标识符 | glGenBuffers() |
2.绑定 | glBindBuffer() |
3.缓存数据(分配内存并从CPU控制的内存复制到刚刚分配的内存) | glBufferData() |
4.启用或禁止使用缓存数据 | glEnableVertexAttribArray()或glDisableVertexAttribArray() |
5.设置指针 | glVertexAttribPointer() |
6.绘图 | glDrawArrays()或者glDrawElements() |
7.删除 | glDelegateBuffers() |
以上这7个步骤是绘图的必要步骤。
在OpenGL ES 应用程序开发指南中创建了下面两个类:
AGLKContext
以及AGLKVertexAttribArrayBuffer
分别用于清除顶点缓存和简化这七个步骤。
AGLKContext
继承于EAGLContentext
,添加了clearColor属性和设置上下文的帧缓存中的每个像素为clearColor.
AGLKVertexAttribArrayBuffer
添加了 三个方法 用于简化这七个步骤:
方法一:
//其中包含了绑定、生成、缓存数据三个步骤
- (id)initWithAttribStride:(GLsizei)stride
numberOfVertices:(GLsizei)count
bytes:(const GLvoid *)dataPtr
usage:(GLenum)usage;
封装了1、2、3三个步骤(绑定、生成、缓存数据):
NSParameterAssert(0 < aStride);
NSAssert((0 < count && NULL != dataPtr) ||
(0 == count && NULL == dataPtr),
@"data must not be NULL or count > 0");
if(nil != (self = [super init]))
{
stride = aStride;
bufferSizeBytes = stride * count;
glGenBuffers(1, // STEP 1
&name);
glBindBuffer(GL_ARRAY_BUFFER, // STEP 2
self.name);
glBufferData( // STEP 3
GL_ARRAY_BUFFER, // Initialize buffer contents
bufferSizeBytes, // Number of bytes to copy
dataPtr, // Address of bytes to copy
usage); // Hint: cache in GPU memory
NSAssert(0 != name, @"Failed to generate name");
}
return self;
方法二:
- (void)prepareToDrawWithAttrib:(GLuint)index
numberOfCoordinates:(GLint)count
attribOffset:(GLsizeiptr)offset
shouldEnable:(BOOL)shouldEnable;
封装了2、4、5三个步骤
NSParameterAssert((0 < count) && (count < 4));
NSParameterAssert(offset < self.stride);
NSAssert(0 != name, @"Invalid name");
glBindBuffer(GL_ARRAY_BUFFER, // STEP 2
self.name);
if(shouldEnable)
{
glEnableVertexAttribArray( // Step 4
index);
}
glVertexAttribPointer( // Step 5
index, // Identifies the attribute to use
count, // number of coordinates for attribute
GL_FLOAT, // data is floating point
GL_FALSE, // no fixed point scaling
(self.stride), // total num bytes stored per vertex
NULL + offset); // offset from start of each vertex to
// first coord for attribute
#ifdef DEBUG
{ // Report any errors
GLenum error = glGetError();
if(GL_NO_ERROR != error)
{
NSLog(@"GL Error: 0x%x", error);
}
}
#endif
}
方法三:
- (void)drawArrayWithMode:(GLenum)mode
startVertexIndex:(GLint)first
numberOfVertices:(GLsizei)count
封装了6
NSAssert(self.bufferSizeBytes >=
((first + count) * self.stride),
@"Attempt to draw more vertex data than available.");
glDrawArrays(mode, first, count); // Step 6```
以及重写7:
- (void)dealloc
{
// Delete buffer from current context
if (0 != name)
{
glDeleteBuffers (1, &name); // Step 7
name = 0;
}
}
****
###绘制一个三角形
- 引入GLKit
- 继承GLKViewContriller
- 绘制
- 重写viewDidUnload
#####C知识:
定义一个C结构体 GLKVector3类型 可以用来保存三个坐标(x\y\z)
typedef struct{
GLKVector3 positionCoords;
}
SceneVertex;
定义一个C数组 储存的 `SceneVertex`类型数组 --上面定义的
`SceneVertex :GLKVector3` (3个向量的)
static const SceneVertex vertices[] = {
{{-0.5f, -0.5f, 0.0}},//第三象限的点
{{ 0.5f, -0.5f, 0.0}},//第四象限的点
{{-0.5f, 0.5f, 0.0}}//第二象限的点
};
-
(void)viewDidLoad {
[super viewDidLoad];GLKView *view = (GLKView *)self.view;
NSAssert([view isKindOfClass:[GLKView class]], @"不是GLKView");view.context = [[AGLKContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
[AGLKContext setCurrentContext:view.context];self.baseEffect = [[GLKBaseEffect alloc]init];
self.baseEffect.useConstantColor = GL_TRUE;
self.baseEffect.constantColor = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f);((AGLKContext *)view.context).clearColor = GLKVector4Make(0.0f, 0.0f, 0.0f, 1.0f);
self.vertexBuffer = [[AGLKVertexAttribArrayBuffer alloc]
initWithAttribStride:sizeof(SceneVertex)
numberOfVertices:sizeof(vertices)/sizeof(SceneVertex)
bytes:vertices
usage:GL_STATIC_DRAW];
}
-
(void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
[self.baseEffect prepareToDraw];[(AGLKContext *)view.context clear:GL_COLOR_BUFFER_BIT];
[self.vertexBuffer prepareToDrawWithAttrib:GLKVertexAttribPosition
numberOfCoordinates:3
attribOffset:offsetof(SceneVertex, positionCoords)
shouldEnable:YES];[self.vertexBuffer drawArrayWithMode:GL_TRIANGLES
startVertexIndex:0
numberOfVertices:3];
}
-
(void)viewDidUnload{
[super viewDidUnload];
GLKView *view = (GLKView *)self.view;
[AGLKContext setCurrentContext:view.context];self.vertexBuffer = nil;
((GLKView *)self.view).context = nil;[EAGLContext setCurrentContext:nil];
}
[Demo1使用原生 ](https://coding.net/u/Xoxo_x/p/OpenGL-ES1/git/blob/master/OpenGL_ES_1.zip)
[Demo2使用简化的类](https://coding.net/u/Xoxo_x/p/OpenGL_ES_2/git/blob/master/OpenGL_ES_2.zip)
****
####绘制三角形注释版:http://www.jianshu.com/p/3988825ef858
网友评论