上一篇文章我們實現了用GLIKit加載一張圖片一也,本篇文章,我們稍微深入點风纠,實現一個立方體貼圖+旋轉蚯斯。
效果
設置立方體的頂點坐標
static GLfloat vertexData[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
屬性設置
image.png
配置基本信息
- (void)setupConfig{
// 使用OpenGLES3
// EAGLContext是蘋果iOS平臺下實現OpenGLES渲染層
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
// 判斷是否創(chuàng)建成功
if (!self.context) {
NSLog(@"Create ES context failed");
return;
}
// 設置當前上下文
[EAGLContext setCurrentContext:self.context];
// 獲取GLKView
GLKView *glkView = (GLKView *)self.view; // 因為當前VC是繼承自`GLKViewController`薄风,所有可以這樣直接獲取
glkView.delegate = self;
// 設置`GLKView`的`context`
glkView.context = self.context;
// 配置視圖渲染緩沖區(qū)
glkView.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
glkView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
// 設置背景顏色
glClearColor(0.5, 0.5, 0.5, 1);
}
配置頂點數據
- (void)setupVertexData{
// 每一行的前面3個是頂點坐標,后面2個是紋理坐標
// 紋理坐標系取值范圍[0,1];原點是左下角(0,0);
// 故而(0,0)是紋理圖像的左下角, 點(1,1)是右上角.
/*
頂點數組: 開發(fā)者可以選擇設定函數指針拍嵌,在調用繪制方法的時候遭赂,直接由內存?zhèn)魅腠旤c數據,也就是說這部分數據之前是存儲在內存當中的撰茎,被稱為頂點數組
頂點緩存區(qū): 性能更高的做法是嵌牺,提前分配一塊顯存,將頂點數據預先傳入到顯存當中龄糊。這部分的顯存逆粹,就被稱為頂點緩沖區(qū)
*/
// 開辟頂點緩沖區(qū)
// (1) 創(chuàng)建頂點緩沖區(qū)標識符ID
GLuint bufferID;
glGenBuffers(1, &bufferID); // 開辟1個頂點緩沖區(qū),所以傳入1
NSLog(@"bufferID:%d", bufferID);
// (2) 綁定頂點緩沖區(qū)
glBindBuffer(GL_ARRAY_BUFFER, bufferID);
// (3) 將頂點數組的數據copy到頂點緩沖區(qū)中(GPU顯存中)
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
// 打開讀取通道
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); // 第一個紋理坐標前面有3個值炫惩,是頂點坐標
}
配置紋理
- (void)setupTexture{
// 獲取紋理圖片
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"png"];
// 初始化紋理
NSDictionary *options = @{GLKTextureLoaderOriginBottomLeft: @(1)}; // 紋理坐標原點是左下角,但是圖片顯示原點應該是左上角
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
NSLog(@"textureInfo.name: %d", textureInfo.name);
// 使用蘋果`GLKit`提供的`GLKBaseEffect`完成著色器工作(頂點/片元)
self.baseEffect = [[GLKBaseEffect alloc] init];
self.baseEffect.texture2d0.enabled = GL_TRUE;
self.baseEffect.texture2d0.name = textureInfo.name;
// 設置透視投影矩陣
CGFloat aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0), aspect, 0.1, 100.0);
self.baseEffect.transform.projectionMatrix = projectionMatrix;
}
更新場景
會多次調用該方法
- (void)updateScene{
_angle = (_angle + 2);
GLKMatrix4 modelViewMatrix = GLKMatrix4Translate(GLKMatrix4Identity, 0, 0, -4.0);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(_angle), 0.3, 0.5, 0.7);
self.baseEffect.transform.modelviewMatrix = modelViewMatrix;
}
實現GLKViewDelegate
代理
正方體有6個面僻弹,需要12個三角形,每個三角形由三個頂點組成他嚷,所以這兒是12x3=36個點
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
// 清除顏色緩沖區(qū)蹋绽、深度緩沖區(qū)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 開啟深度測試
glEnable(GL_DEPTH_TEST);
[self updateScene];
// 準備繪制
[self.baseEffect prepareToDraw];
// 開始繪制
// 從第一個開始,所以是0
glDrawArrays(GL_TRIANGLES, 0, 48); // 正方體有6個面筋蓖,需要12個三角形卸耘,每個三角形由三個頂點組成,所以這兒是12x3=36個點
}