#GLKit框架 GLKit框架的設計目的是爲了簡化OpenGL/OpenGL ES的應用開發。它的出現加快了OpenGL或OpenGL ES應用程序的開發。使用數學庫、背景紋理加載,預先建立着色器效果,以及標準視圖和視圖控制器來實現渲染循環。 GLKit框架提供了功能和類,能夠減小建立新的基於着色器的應⽤程序所需的⼯做量, 或者支持依賴早期版本的OpenGL ES或OpenGL提供的固定函數頂點或⽚段處理的現有 應用程序。數組
#GLKView 、GLKViewController 在iOS平臺下,蘋果給咱們封裝好了GLKViewController這樣的一個類,簡化了咱們經過OpenGL ES渲染圖形的工做。bash
//初始化GLKView
- (instancetype)initWithFrame:(CGRect)frame context:(EAGLContext *)context;
//顏色渲染緩衝區格式
@property (nonatomic) GLKViewDrawableColorFormat drawableColorFormat;
//深度渲染緩衝區格式
@property (nonatomic) GLKViewDrawableDepthFormat drawableDepthFormat;
//模板渲染緩衝區格式
@property (nonatomic) GLKViewDrawableStencilFormat drawableStencilFormat;
//多重採樣緩衝區格式
@property (nonatomic) GLKViewDrawableMultisample drawableMultisample;
//幀緩衝區屬性
@property (nonatomic, readonly) NSInteger drawableWidth; //緩衝區對象寬度
@property (nonatomic, readonly) NSInteger drawableHeight; //緩衝區對象高度
/**
* GLKViewDelegate必須實現的方法:在這個方法裏進行繪圖
* - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect;
*/
@property (nullable, nonatomic, assign) IBOutlet id <GLKViewDelegate> delegate;
//將底層的FrameBuffer對象綁定到OpenGL ES
- (void)bindDrawable;
//刪除視圖FrameBuffer對象
- (void)deleteDrawable;
//繪製視圖內容並將其做爲圖像對象返回
@property (readonly, strong) UIImage *snapshot;
//布爾,指定視圖是否響應使得視圖內容無效的信息
@property (nonatomic) BOOL enableSetNeedsDisplay;
//當即重繪
- (void)display;
複製代碼
#GLKTextureInfo 使用GLKTextureLoader能夠建立加載OpenGL紋理信息:框架
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:nil error:nil];
GLKTextureInfo有如下信息:
GLuint name; //紋理名稱
GLenum target; //紋理綁定的目標
GLuint width; //加載紋理的寬度
GLuint height; //加載紋理的高度
GLKTextureInfoAlphaState alphaState; //加載紋理中alpha狀態
GLKTextureInfoOrigin textureOrigin; //加載紋理的原點位置
BOOL containsMipmaps; //布爾值,加載的紋理是否包含mip貼圖
複製代碼
#GLKBaseEffect GLKBaseEffect是OpenGL ES提供的一種簡單的光照/着色系統,用於基於着色器的渲染。 #####配置光照ide
//爲基元兩側計算光照 (系統去作,開發者來控制開關)
@property (nonatomic, assign) GLboolean lightModelTwoSided;
//計算渲染圖元光照使⽤的材質屬性
@property (nonatomic, readonly) GLKEffectPropertyMaterial *material;
//環境顏⾊色,應⽤用效果渲染的全部圖元
@property (nonatomic, assign) GLKVector4 lightModelAmbientColor;
//第一、二、3個光照屬性
GLKEffectPropertyLight *_light0, *_light1, *_light2;
複製代碼
#####配置紋理函數
//配置第一、2個紋理
GLKEffectPropertyTexture *_texture2d0, *_texture2d1;
//紋理應用於渲染圖元的順序
NSArray *_textureOrder;
複製代碼
#####配置霧化性能
GLKEffectPropertyFog *_fog;
複製代碼
#####配置顏色信息ui
//表示計算光照與材質交互時是否使用顏色頂點屬性
@property (nonatomic, assign) GLboolean colorMaterialEnabled;
//是否使用常量顏色
@property (nonatomic, assign) GLboolean useConstantColor;
//不提供每一個頂點顏色數據時使用常量顏⾊
@property (nonatomic, assign) GLKVector4 constantColor;
複製代碼
#####準備繪製效果atom
- (void) prepareToDraw; //準備繪製效果(必須在繪製前寫上)
複製代碼
#下面演示使用GLKit來畫一個圖片到屏幕上spa
//配置環境
- (void)setupUpEnv {
//初始化上下文
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
if (context == nil) {
NSLog(@"content create fail");
return;
}
[EAGLContext setCurrentContext:context];
//獲取GLKView 設置context
GLKView * view = (GLKView *)self.view;
view.context = context;
view.delegate = self;
//配置視圖建立的渲染緩衝區
view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
//配置背景顏色
glClearColor(0, 1, 1, 1);
}
複製代碼
###配置頂點數據設計
// 設置頂點數據數組(頂點座標、紋理座標)
- (void)setUpVertexData {
//頂點數據和紋理數據都存在一個數組中 ,6個頂點,每五個數據 前三個爲xyz頂點座標 後兩個爲紋理座標st
GLfloat vertexData [] = {
0.6, -0.5, 0.0f, 1.0f, 0.0f, //右下
0.6, 0.5, -0.0f, 1.0f, 1.0f, //右上
-0.6, 0.5, 0.0f, 0.0f, 1.0f, //左上
0.6, -0.5, 0.0f, 1.0f, 0.0f, //右下
-0.6, 0.5, 0.0f, 0.0f, 1.0f, //左上
-0.6, -0.5, 0.0f, 0.0f, 0.0f, //左下
};
//將頂點數據copyj到頂點緩衝區 : 這樣作會提早分配一塊顯存,將頂點數據copy進去,這樣能夠性能更高
GLuint bufferID;
glGenBuffers(1, &bufferID); //建立頂點緩衝區的標識符ID
glBindBuffer(GL_ARRAY_BUFFER, bufferID); //綁定頂點緩衝區
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW); //將頂點數據copy到頂點緩衝區
/**打開讀取通道(默認是關閉的,這一步是必需要寫的)
方法簡介 : 上傳頂點數據到顯存的方法(設置合適的方式從buffer裏面讀取數據)
glVertexAttribPointer(GLuint indx , GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *ptr)
* 參數列表:
* indx :指定要修改的頂點屬性索引值 :好比 GLKVertexAttribPosition表明頂點 GLKVertexAttribTexCoord0表明紋理
* size :每次讀取的數量 (如position是由3個(x,y,z)組成,而顏色是4個(r,g,b,a),紋理則是2個.)
* type :指定數組中每一個組件的數據類型。可用的有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT,GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值爲GL_FLOAT。
* normalized :指定當被訪問時,固定點數據值是否應該被歸一化(GL_TRUE)或者直接轉換爲固定點值(GL_FALSE)
* stride :指定連續頂點屬性之間的偏移量。若是爲0,那麼頂點屬性會被理解爲:它們是緊密排列在一塊兒的。初始值爲0
* ptr :指定一個指針,指向數組中第一個屬性組件
*/
//頂點座標數據
glEnableVertexAttribArray(GLKVertexAttribPosition);
/** 每次讀3個數據,即x y z。 頂點偏移量爲5:
* 第一個頂點從下標0開始,第二個頂點從下標5開始,以此類推。。。
* (GLfloat *)NULL + 0 :表示首次讀取的位置,由於此時讀取是從顯存讀的 因此不能用數組地址去取 (GLfloat *)NULL表示首地址
*/
glVertexAttribPointer(GLKVertexAttribPosition , 3, GL_FLOAT,GL_FALSE, 5, (GLfloat *)NULL + 0);
//紋理座標數據
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 5, (GLfloat *)NULL + 3);
}
複製代碼
###配置頂點數據
//配置紋理
- (void)setUpTexture {
NSString * filePath = [[NSBundle mainBundle] pathForResource:@"memory" ofType:@"jpg"];
//由於紋理座標和屏幕座標是須要翻轉的,因此這裏須要配置一下映射關係
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1),GLKTextureLoaderOriginBottomLeft, nil];
GLKTextureInfo * textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
//使用 GLKBaseEffect 完成着色器的工做
cEffect = [[GLKBaseEffect alloc] init];
cEffect.texture2d0.enabled = GL_TRUE;
cEffect.texture2d0.name = textureInfo.name;
}
複製代碼
###GLKViewDelegate開始繪圖
#pragma mark - GLKViewDelegate
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
glClear(GL_COLOR_BUFFER_BIT);
//重要的一步!!!
[cEffect prepareToDraw];
//開始繪製
glDrawArrays(GL_TRIANGLES, 0, 6);
}
複製代碼
###viewDidLoad裏依次調用
[self setupUpEnv];
[self setUpVertexData];
[self setUpTexture];
複製代碼
運行效果以下: