控制器使用GLKViewController數組
//.h文件
#import <UIKit/UIKit.h>
#import <GLKit/GLKit.h>
@interface ViewController : GLKViewController
@end
//.m文件
#import <OpenGLES/ES3/gl.h>
#import <OpenGLES/ES3/glext.h>
@interface ViewController ()
@end
@implementation ViewController
{
EAGLContext *_content;//上下文
GLKBaseEffect *effect;//繪製工具類
}
複製代碼
1.初始化上下文&設置當前上下文緩存
- (void)setBaseContent{
//creat context
_content = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
if (!_content){
NSLog(@"content failed");
}
//set context
[EAGLContext setCurrentContext: _content];
//view 關聯context
//注意:ViewController在storyBoard內,其view類型修已經改成了GLKView
GLKView *glkView = (GLKView *)self.view;
glkView.context = _content;
//清屏顏色
glClearColor(0.5, 0.5, 0.5, 1.0);
}
複製代碼
在初始化context時,咱們須要選擇咱們使用的OpenGL ES的版本,分別有以下幾種:bash
kEAGLRenderingAPIOpenGLES1 = 1, 固定管線
kEAGLRenderingAPIOpenGLES2 = 2,
kEAGLRenderingAPIOpenGLES3 = 3,
複製代碼
EAGLContext是蘋果iOS平臺下實現OpenGL ES渲染層。其中kEAGLRenderingAPIOpenGLES1相似前幾篇文章說的固定管線。而kEAGLRenderingAPIOpenGLES2和kEAGLRenderingAPIOpenGLES3,在這裏使用哪一個,區別不大,只是版本不一樣而已。工具
下面須要配置視圖建立的渲染緩衝區,以及設置背景顏色性能
glkView.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
glkView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
複製代碼
drawableColorFormat: 顏色緩衝區格式 在OpenGL ES中有一個緩存區,它用以存儲在屏幕中顯示的顏色。你可使用其屬性設置緩衝區中的每一個像素的顏色格式。 GLKViewDrawableColorFormatRGBA8888 = 0 默認值,緩衝區的每一個像素的最小組成部分(RGBA)使用8個bit,(因此每一個像素4個字節, 4*8個bit) GLKViewDrawableColorFormatRGB565 若是你的APP容許更小範圍的顏色,便可設置這個。會讓你的APP消耗更小的資源(內存和處理時間)ui
drawableDepthFormat: 深度緩存區格式 GLKViewDrawableDepthFormatNone = 0, 意味着徹底沒有深度緩衝區 GLKViewDrawableDepthFormat16, GLKViewDrawableDepthFormat24, 若是你要使用這個屬性(通常用於3D遊戲),你應該選擇GLKViewDrawableDepthFormat16或GLKViewDrawableDepthFormat24。這裏的差異是使用GLKViewDrawableDepthFormat16將消耗更少的資源spa
加載紋理數據(使用GLBaseEffect)指針
使用本地圖片做爲紋理code
- (void)loadTexture{
//讀取圖片紋理
NSString *filePath = [[NSBundle mainBundle] pathForResource: @"summerDay" ofType: @"png"];
//設置紋理參數
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: @(1), GLKTextureLoaderOriginBottomLeft, nil];
//紋理信息類
GLKTextureInfo *texInfo = [GLKTextureLoader textureWithContentsOfFile: filePath options:options error:nil];
//GLKit 提供GLKBaseEffect 完成着色器工做(頂點/片元)
effect = [[GLKBaseEffect alloc] init];
effect.texture2d0.enabled = GL_TRUE;
effect.texture2d0.name = texInfo.name;
}
複製代碼
注意: 在設置紋理參數的時,須要注意一點,紋理座標默認左下角爲原點(0,0),而iOS座標系中,默認手機屏幕的左上角爲原點(0,0),因此須要特別注意這一點,須要設置GLKTextureLoaderOriginBottomLeft,否則圖片顯示的時候,會發生翻轉。orm
加載頂點&紋理數據
設置繪製的頂點/紋理數據
- (void)setDrawContent{
//1.設置頂點數組
GLfloat vertexData[] = {
0.5, -0.5, 0.0f, 1.0f, 0.0f, //右下
0.5, 0.5, -0.0f, 1.0f, 1.0f, //右上
-0.5, 0.5, 0.0f, 0.0f, 1.0f, //左上
0.5, -0.5, 0.0f, 1.0f, 0.0f, //右下
-0.5, 0.5, 0.0f, 0.0f, 1.0f, //左上
-0.5, -0.5, 0.0f, 0.0f, 0.0f, //左下
};
//2.開闢頂點緩衝區
//建立頂點緩存區標識符ID
GLuint bufferId;
glGenBuffers(1, &bufferId);
//綁定頂點緩存區
glBindBuffer(GL_ARRAY_BUFFER, bufferId);
//將頂點數組的數據copy到頂點緩存區中(GPU顯存中)
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
//3.打開屬性通道讀取對應數據.
//頂點數據
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 0);
//紋理數據
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 3);
}
複製代碼
參數1: 指定要修改的屬性的索引值
參數2: 每次讀取數量(如position是由3個(x,y,z)組成,而顏色是4個(r,g,b,a),紋理則是2個.)
參數3: 指定數組中每一個組件的數據類型。可用的符號常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值爲GL_FLOAT。
參數4: 指定當被訪問時,固定點數據值是否應該被歸一化(GL_TRUE)或者直接轉換爲固定點值(GL_FALSE)
參數5: 指定連續頂點屬性之間的偏移量。若是爲0,那麼頂點屬性會被理解爲:它們是緊密排列在一塊兒的。初始值爲0 參數6: 指定一個指針,指向數組中第一個頂點屬性的第一個組件。初始值爲0
上述代碼中,對於頂點來講,每次讀取3個,數據類型爲浮點型,偏移量即讀取下一組頂點數據,須要移動5個位置,頂點讀取位置對應從數組的一開始讀取,因此最後一個參數寫成(GLfloat *)NULL + 0,這裏這樣的寫法是爲了方便讀者理解,也能夠直接寫成NULL。因此對於紋理的最後一個參數寫成(GLfloat *)NULL + 3也不難理解。
注意點:
在iOS中,默認狀況下,出於性能考慮,全部頂點着色器的屬性(Attribute)變量都是關閉的,意味着,頂點數據在着色器(服務端)是不可用的。即便你已經使用glBufferData方法,將頂點數據從內存拷貝到頂點緩衝區中(GPU顯存中); 因此,必須由glEnableVertexAttribArray方法打開通道,指定訪問屬性,才能讓頂點着色器可以訪問到從CPU複製到GPU的數據。 注意: 數據在GPU端是否可見,即着色器可否讀取到數據,由是否啓用了對應的屬性決定,這就是glEnableVertexAttribArray的功能,容許頂點着色器讀取GPU(服務端)數據。 GLKVertexAttribPosition, // 頂點 GLKVertexAttribNormal, // 法線 GLKVertexAttribColor, // 顏色 GLKVertexAttribTexCoord0, // 紋理 GLKVertexAttribTexCoord1
繪製視圖的內容
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
//1.清除顏色緩存區
glClear(GL_COLOR_BUFFER_BIT);
//2.準備繪製
[cEffect prepareToDraw];
//3.開始繪製
glDrawArrays(GL_TRIANGLES, 0, 6);
}
複製代碼
OK,案例內容結束,下面看實現效果(其實就是咱們平時用UIImageView加載一張圖片而已)