- OpenGL ES到底在做了什么?
簡單來說就協調GPU和CPU之間的數據交換如圖
屏幕快照 2017-06-27 下午9.56.32.png
- 首先來了解OpenGL的一些基本概念:
- 緩存(buffers):提供數據的最好方式;
OpenGL ES為兩個緩存區域之間的數據交換定義了緩存, CPU將數據復制到OpenGL ES的緩存中, GPU申請到權限之后, CPU就不會接觸這個緩存, 這樣GPU就會高效的讀寫數據.
2.為緩存提供數據7個步驟和對應的函數中對應的API(非常重要):
2.1)生成---glGenBuffers():請求生成一個獨一無二的標識符
2.2)綁定---glGindBuffer():告訴OpenGL為接下來的運算使用一個緩存
2.3)緩存數據---glBufferData():初始化(分配內存),復制數據到緩存中
2.4)啟用或者禁止---glEnableVertexAttribArray()和glDisableVertexAttribArray()
2.5)設置指針---glVertexAttribPointer()
2.6)繪圖---glDrawArrays()渲染
2.7)刪除---glDeleteBuffers()
- 幀緩存(frame buffer):接收渲染結果的緩沖區
4.上下文(context):(可以理解為畫布)用于配置OpenGL ES的保存在特定平臺的軟件數據結構中
5.著色器(shaders):它們是一個個獨立運行在GPU上的小程序, 這些小程序為圖形渲染管線的某個特定部分而運行
6.GLKit(iOS 5)框架:在iOS中使用OpenGL ES需要使用的框架
-
先看效果:在紅色的GLKView上渲染一個白色的三角形
圖片發自簡書App
- 現在正是開始上代碼
- 首先用到的是GLKit框架, 控制器使用的是UIViewController的子類GLKViewController
- 定義一個C結構體scene,用來保存GLKVector3(表示,x,y,z坐標)類型的成員變量positionCoords,數組point表示三角形的三個頂點坐標
typedef struct {
GLKVector3 positionCoords;
}scene;
static const scene point[] = {
{{0.5, -0.5, 0.0f}}, //右下
{{0.5, 0.5, -0.0f}}, //右上
{{-0.5, 0.5, 0.0f}} //左上
};
3.著色器和上下文
//頂點數據緩存的標識符
@property (nonatomic,assign)GLuint bufferID;
//著色器
@property (nonatomic,strong) GLKBaseEffect *baseEffect;
//上下文
@property (nonatomic,strong)EAGLContext *context;
4.初始化,配置上下文和著色器
GLKView *v = (GLKView *)self.view;
//初始化上下文
self.context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
v.context = self.context;
//設置當前的上下文
[EAGLContext setCurrentContext:self.context];
//著色器
self.baseEffect = [[GLKBaseEffect alloc]init];
self.baseEffect.useConstantColor = GL_TRUE;
self.baseEffect.constantColor = GLKVector4Make(1.0, 1.0, 1.0, 1.0);//紅,綠,藍,透明度
5.核心代碼,創建緩存(7個步驟,前5個步驟)
//創建緩存
glGenBuffers(1, &_bufferID);//生成標識符
glBindBuffer(GL_ARRAY_BUFFER, _bufferID);//綁定
glBufferData(GL_ARRAY_BUFFER, sizeof(point), point, GL_STATIC_DRAW);//復制頂點數據到緩存中
glEnableVertexAttribArray(GLKVertexAttribPosition);//允許
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(scene), NULL);//告訴OpenGL頂點數據在哪里
6.最后在glkView:(GLKView *)view drawInRect:(CGRect)rect的代理方法中實現實現繪制
//背景顏色
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
[self.baseEffect prepareToDraw];
glDrawArrays(GL_TRIANGLES, 0, 3);//重繪
遇到的問題:控制器要使用GLKViewController, 一開始嘗試直接在控制器嘗試在UIViewController中添加一個GLKView, 但是并沒有出現三角形.