iOS開發(fā)-OpenGL ES入門教程1

前言

這里是一篇新手教程,環(huán)境是Xcode7+OpenGL ES 2.0,目標寫一個OpenGL ES的hello world。
OpenGL ES系列教程在這里,
OpenGL ES系列教程的代碼地址 ,

你的star和fork是我的源動力,你的意見能讓我走得更遠

核心思路

通過GLKit,盡量簡單地實現(xiàn)把一張圖片繪制到屏幕。

效果展示

具體細節(jié)

1、新建OpenGL ES上下文

- (void)setupConfig {
    //新建OpenGLES 上下文
    self.mContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; //2.0,還有1.0和3.0
    GLKView* view = (GLKView *)self.view; //storyboard記得添加
    view.context = self.mContext;
    view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;  //顏色緩沖區(qū)格式
    [EAGLContext setCurrentContext:self.mContext];
}

GLKView* view = (GLKView *)self.view;這里需要在storyboard里面把view的類設(shè)置成GLKView,其他代碼是OpenGL ES上下文的創(chuàng)建。

2、頂點數(shù)組和索引數(shù)組

    //頂點數(shù)據(jù),前三個是頂點坐標(x、y、z軸),后面兩個是紋理坐標(x,y)
    GLfloat squareVertexData[] =
    {
        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, //左下
    };

頂點數(shù)組里包括頂點坐標,OpenGLES的世界坐標系是[-1, 1],故而點(0, 0)是在屏幕的正中間。
紋理坐標系的取值范圍是[0, 1],原點是在左下角。故而點(0, 0)在左下角,點(1, 1)在右上角。
索引數(shù)組是頂點數(shù)組的索引,把squareVertexData數(shù)組看成4個頂點,每個頂點會有5個GLfloat數(shù)據(jù),索引從0開始。

3、頂點數(shù)據(jù)緩存

    //頂點數(shù)據(jù)緩存
    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(squareVertexData), squareVertexData, GL_STATIC_DRAW);
    
    glEnableVertexAttribArray(GLKVertexAttribPosition); //頂點數(shù)據(jù)緩存
    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);

這是本章節(jié)的核心內(nèi)容。

  • glGenBuffers申請一個標識符
  • glBindBuffer把標識符綁定到GL_ARRAY_BUFFER
  • glBufferData把頂點數(shù)據(jù)從cpu內(nèi)存復(fù)制到gpu內(nèi)存
  • glEnableVertexAttribArray 是開啟對應(yīng)的頂點屬性
  • glVertexAttribPointer設(shè)置合適的格式從buffer里面讀取數(shù)據(jù)

4、紋理貼圖


- (void)uploadTexture {
    //紋理貼圖
    NSString* filePath = [[NSBundle mainBundle] pathForResource:@"for_test" ofType:@"jpg"];
    NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@(1), GLKTextureLoaderOriginBottomLeft, nil];//GLKTextureLoaderOriginBottomLeft 紋理坐標系是相反的
    GLKTextureInfo* textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
    //著色器
    self.mEffect = [[GLKBaseEffect alloc] init];
    self.mEffect.texture2d0.enabled = GL_TRUE;
    self.mEffect.texture2d0.name = textureInfo.name;
}
  • GLKTextureLoader讀取圖片,創(chuàng)建紋理GLKTextureInfo
  • 創(chuàng)建著色器GLKBaseEffect,把紋理賦值給著色器

基礎(chǔ)

代碼帶了很多注釋,百度下相應(yīng)的概念,會有更多解釋。
如果對OpengGL ES感興趣,但是卻毫無圖形學(xué)基礎(chǔ)的,可以看看LearnOpenGL教程。

思考題

  • 1、代碼中有6個頂點坐標,能否使用更少的頂點顯示一個圖像?
  • 2、頂點緩存數(shù)組可以不用glBufferData,要如何實現(xiàn)?
  • 3、如果把這個圖變成左右兩只對稱的熊貓,該如何改?

這里可以下載demo代碼。

思考題答案

思考題1:
可以使用四個頂點,繪制2個三角形 的6個頂點中有2個是重復(fù)的,使用索引可以減少重復(fù)。

思考題2:
頂點緩存數(shù)組可以不用glBufferData,要如何實現(xiàn)?頂點數(shù)組可以通過glBufferData放入緩存,也可以直接通過glVertexAttribPointer最后一個參數(shù),直接把頂點數(shù)組從CPU傳送到GPU。區(qū)別:glBufferData里面的頂點緩存可以復(fù)用,glVertexAttribPointer是每次都會把頂點數(shù)組從CPU發(fā)送到GPU,影響性能。

思考題3
如果把這個圖變成左右兩只對稱的熊貓,該如何改?把屏幕切分成4個三角形,左邊兩個三角形同上,右邊兩個三角形的紋理坐標的x值調(diào)整即可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容