iOS-零基礎學習OpenGL-ES入門教程(一)

寫在前面

由於作的攝像頭相關工做,工做中經常使用到OpenGL去作視頻渲染,圖形變換等,雖然說知足了開發需求,可是本身對於OpenGL的學習一直沒有很系統完善,屬於需求驅動學習。因此纔有了這個開篇html

OpenGL ES的開始學習必然是有一點點枯燥和難理解的哈,沒有C語言編程基礎的童鞋,初次接觸C接口編程會有一點疑惑,可是不要緊,所謂孰能生巧,多思考,練習便可。git

學習書籍這塊:github

  1. OpenGL ES應用開發實踐指南:iOS卷
  2. 紅寶書 OpenGL Programming Guide,出到第八版
  3. 藍寶書 OpenGL SuperBible,出到第六版

入門教程以及demo代碼主要來源於《OpenGL ES應用開發實踐指南:iOS卷》web

1.OpenGL ES概述

關於概念介紹我就貼上百度了哈(哈哈,偷懶一下) OpenGL ES百度百科編程

OK,OpenGL是用於2D/3D圖形編程的一套基於C語言的統一接口,在桌面windows,Mac,Linux/Unix上都可兼容。windows

OpenGL ES是在OpenGL嵌入式設備上面的版本,也就是安卓/iPhone,其餘嵌入式等移動設備的編程規範。(除此以外,在web上也有相應的WebGL)數組

如今在iOS平臺上目前支持的OpenGL版本有緩存

  • OpenGL1.0
  • OpenGL2.0
  • OpenGL3.0

後面的教程均基於OpenGL2.0環境下。(其中1.0版本基本已經再也不使用了。)bash

從上面的簡單介紹咱們知道了OpenGL ES是作圖形編程的, 下圖摘自蘋果的官方介紹: OpenGL ES Programming Guide架構

cpu_gpu_2x.png

能夠看到咱們經過OpenGL ES驅動gpu圖形處理器實現圖形編程。

發散小思考: OpenGL ES做爲iOS相對底層庫,能夠完成2D/3D圖形渲染,那麼咱們日常的UIView也能夠基於CoreAnimation完成3D動畫,圖形顯示,那麼UIView和OpenGL有什麼內在關係呢,咱們的iPhone最終是怎麼完成圖像顯示的呢?

Cocoa Touch OpenGL ES軟件架構

從上圖能夠看到core animation Layers就是經過OpenGL ES繪製最後混合,而後經過幀緩存顯示到屏幕上的。

2.iOS OpenGL ES最簡單的實踐

OK,因爲是開篇,下面咱們經過一個簡單的例子完成一個三角形的繪製 在這裏咱們使用GLkit:這是蘋果作的一層封裝,能夠簡化在iOS下OPENGL ES代碼。

至於GLkit具體作了什麼,後面隨着咱們深刻學習能夠再回頭來看,後面會編寫不使用GLkit的demo,能夠經過比對來看到底優化了哪些流程,這裏暫時只須要記住使用GLkit能夠簡化代碼。

  • GLKViewController:UIViewController的子類,接收當視圖須要重繪時的消息
  • GLKView:UIView的子類,簡化了經過用Core Animation層來自動建立並管理幀緩存和渲染緩存共享內存所須要作的工做。
  1. 建立OpenGL ES上下文 建立一個GLKViewController,在ViewdidLoad生命週期中:
GLKView *view  = (GLKView *)self.view;
    //建立OpenGL ES2.0上下文
    view.context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
    //設置當前上下文
    [EAGLContext setCurrentContext:view.context];
複製代碼
  1. 聲明一個GLKBaseEffect屬性
@property (nonatomic,strong)GLKBaseEffect *baseEffect;
複製代碼

而且在ViewDidLoad實例化

self.baseEffect = [[GLKBaseEffect alloc]init];
//使用靜態顏色繪製
  self.baseEffect.useConstantColor = GL_TRUE;
//設置默認繪製顏色,參數分別是 RGBA
  self.baseEffect.constantColor = GLKVector4Make(1.0f, 1.0f, 1.0f, 1.0f);
   //設置背景色爲黑色
   glClearColor(0.0f,0.0f,0.0f,1.0f);
複製代碼

GLKBaseEffect使咱們不須要編寫shader Language代碼就能夠簡單完成圖形繪製,關於Shader Language後面再講解學習

  1. 頂點數據 咱們須要繪製一個三角形天然須要三個頂點,OpenGL ES採用的笛卡爾座標系
    OPENGL ES座標系
//頂點結構體
typedef struct{
    GLKVector3 positionCoords;
}sceneVertex;

//三角形的三個頂點
static const sceneVertex vertices[] = {
    {{-0.5f,-0.5f,0.0}},
    {{0.5f,-0.5f,0.0}},
    {{-0.5f,0.5f,0.0}},
};
複製代碼
  1. 生成緩存而且爲緩存提供數據,這是最重要的一步
//聲明緩存ID屬性
@property (nonatomic,assign)GLuint *vertextBufferID;
複製代碼
//viewdidload中生成並綁定緩存數據
  glGenBuffers(1, &vertextBufferID);
  glBindBuffer(GL_ARRAY_BUFFER, vertextBufferID); //綁定指定標識符的緩存爲當前緩存
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
複製代碼
  • glGenBuffers申請一個標識符
  • glBindBuffer 將標識符綁定到GL_ARRAY_BUFFER
  • glBufferData複製頂點數據從CPU到GPU

接下來在GLKViewController的 -(void)glkView:(GLKView *)view drawInRect:(CGRect)rect 代理方法中

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
    [self.baseEffect prepareToDraw];
    
    //Clear Frame Buffer
    glClear(GL_COLOR_BUFFER_BIT);
    
    //開啓緩存
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    
    //設置緩存數據指針
    glVertexAttribPointer(GLKVertexAttribPosition,
                          3,
                          GL_FLOAT,
                          GL_FALSE, //小數點固定數據是否被改變
                          sizeof(sceneVertex),
                          NULL);  //從開始位置
    //繪圖
    glDrawArrays(GL_TRIANGLES,
                 0,
                 3);

}
複製代碼
  • glEnableVertexAttribArray 開啓對應的頂點緩存屬性
  • glVertexAttribPointer 設置指針從頂點數組中讀取數據
  • glDrawArrays 繪製圖形
  1. 釋放緩存數據 在dealloc方法中釋放掉緩存數據
- (void)dealloc{
    GLKView *view = (GLKView *)self.view;
    [EAGLContext setCurrentContext:view.context];
    if ( 0 != vertextBufferID) {
        glDeleteBuffers(1,
                        &vertextBufferID);
        vertextBufferID = 0;
    }
}
複製代碼

最後的運行結果圖以下

運行結果

拓展小問題:1. 如何將背景色改爲紅色 2. 如何將三角形顏色改爲黑色,而不是如今的白色

  • (void)glkView:(GLKView *)view drawInRect:(CGRect)rect是GLKViewController系統給咱們回調的繪製消息,該方法會一直被調用,和display方法一致

EAGLContext上下文本質上是個狀態機,只有在當前上下文下,Opengl ES API調用纔會生效

3.總結: 建立緩存數據並完成最終渲染顯示的七個步驟

  1. 生成: glGenBuffers()
  2. 綁定緩存數據: glBindBuffer()
  3. 緩存數據:glBufferData()
  4. 啓用:glEnableVertexAttribArray()
  5. 設置指針:glVertexAttribPointer()
  6. 繪圖:glDrawArrays()
  7. 刪除:glDeleteBuffers()

好了,就此咱們就使用OpenGL ES完成了一個最簡單的繪製demo,初次學習OpenGL ES確定對其中概念會有不少疑問,這都不要緊,咱們先熟悉一下,隨着後續的學習再回來看這些疑問。

2017-0413更新: Demo代碼地址:LearnOpenGLESDemo

參考書籍:1. OpenGL ES應用開發實踐指南:iOS卷

相關文章
相關標籤/搜索