OpenGL ES學(xué)習(xí)筆記1: 使用GLKit繪制三角形和圖片

<h5>1蔗包、先上效果圖</h5>

繪制三角形和圖片.png

<h5>2、背景知識</h5>

  • OpenGL ES(OpenGL for Embedded Systems)是OpenGL三維圖形API的子集剔蹋,針對手機(jī)催烘、PDA和游戲主機(jī)等嵌入式設(shè)備而設(shè)計的。
  • OpenGL ES只能繪制點浪感、線段和三角形
  • GLKit 框架是為了簡化iOS上OpenGL ES的開發(fā),提供的基于OpenGL ES的iOS框架。
  • GLKit 中重要的類:GLKViewController & GLKView & GLKBaseEffect矫付、GLKReflectionMapEffect舰始、GLKSkyboxEffect Class等。
  • 紋理:姑且認(rèn)為是個小圖片
  • 紋理坐標(biāo): 在x和y軸上峻堰,范圍為0到1之間(注意我們使用的是2D紋理圖像)讹开。紋理坐標(biāo)起始于(0, 0),也就是紋理圖片的左下角捐名,終始于(1, 1)旦万,即紋理圖片的右上角。

<h5>3镶蹋、代碼實現(xiàn)主要思路(以繪制圖片為例成艘,繪制三角形代碼比較簡單,見項目源碼)</h5>

1)創(chuàng)建OpenGL ES上下文
2)設(shè)置頂點數(shù)據(jù)信息
3)創(chuàng)建著色器效果贺归,并啟動著色器

  1. 實現(xiàn)GLKViewDelegate代理方法淆两,繪制圖片到屏幕

<h5>4、重要代碼說明<h5>

  • 需要引用框架#import <GLKit/GLKit.h>
  • 使用GLKit展示所在的ViewController需要繼承GLKViewController
  • 設(shè)置好頂點信息數(shù)組 和 頂點索引數(shù)組
//設(shè)置頂點信息數(shù)組 
const GLfloat Vertices[] = {
    0.5, -0.5, 0.0f,    1.0f, 0.0f, //右下(x,y,z坐標(biāo) + s,t紋理)
    -0.5, 0.5, 0.0f,    0.0f, 1.0f, //左上
    -0.5, -0.5, 0.0f,   0.0f, 0.0f, //左下
    0.5, 0.5, 0.0f,    1.0f, 1.0f, //右上
};

//設(shè)置頂點索引數(shù)組
const GLuint indices[] = {
    0,1,2,
    1,3,0
};

<h6>4.1拂酣、重要代碼說明 之 創(chuàng)建OpenGL ES上下文<h6>

/**
 設(shè)置OpenGL ES上下文
 */
- (void)setupContext{

    self.context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
    if (!self.context) {
        NSLog(@"Failed to initialize OpenGLES 2.0 context");
        exit(1);
    }

    GLKView *view = (GLKView *)self.view;
    view.context = self.context;
    //顏色緩沖區(qū)格式
    view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
    //self.context為OpenGL的"當(dāng)前激活的Context"秋冰。之后所有"GL"指令均作用在這個Context上。
    if (![EAGLContext setCurrentContext:self.context]) {
        NSLog(@"Failed to set current OpenGL context");
        exit(1);
    }
  }

說明

  • 只要使用OpenGL婶熬,總需要這個 EAGLContext對象丹莲,EAGLContext對象管理所有通過OpenGL進(jìn)行draw的信息
  • 這里使用OpenGL ES 2.0的API
  • 簡單的容錯處理

<h6>4.2、重要代碼說明 之 設(shè)置頂點數(shù)據(jù)信息</h6>

- (void)setupVBOs{

   /** VBO : 頂點緩存區(qū)對象
      兩種頂點緩存類型:一種是用于跟蹤每個頂點信息的(Vertices)尸诽,另一種是用于跟蹤組成每個三角形的索引信息(我們的Indices)
 */
    GLuint verticesBuffer;
    glGenBuffers(1, &verticesBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

    GLuint indicesBuffer;  
    glGenBuffers(1, &indicesBuffer);  
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    //啟動
    glEnableVertexAttribArray(GLKVertexAttribPosition); 
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0); 
   
    //為vertex shader的兩個輸入?yún)?shù)(Position 和 TexCoord)配置兩個合適的值
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 3);
}

重要函數(shù)說明

*1甥材、 glGenBuffers (GLsizei n, GLuint buffers) **

創(chuàng)建一個緩存對象

2、glBindBuffer (GLenum target, GLuint buffer)

激活緩沖對象性含,buffer指向target洲赵,target可以是GL_ARRAY_BUFFER(坐標(biāo),顏色 等)、GL_ELEMENT_ARRAY_BUFFER (索引坐標(biāo))或者GL_TEXTURE_BUFFER(紋理緩沖)

*3叠萍、glBufferData (GLenum target, GLsizeiptr size, const GLvoid data, GLenum usage) **

用數(shù)據(jù)分配和初始化緩沖區(qū)對象 ,demo中usage使用GL_STATIC_DRAW (預(yù)先指定辅鲸,只寫1次,可讀n次)
DRAW: 客戶機(jī)指定了用于渲染的數(shù)據(jù)
READ:從OPENGL緩沖區(qū)讀取數(shù)據(jù)值,并且在應(yīng)用程序中用于各種魚渲染不直接相關(guān)的計算過程
COPY:從OPENGL緩沖區(qū)讀取數(shù)據(jù)值,作為用于渲染的數(shù)據(jù)

STREAM:緩沖區(qū)對象中數(shù)據(jù)需要經(jīng)常更新,但是作為繪圖或其他操作使用較少
STATIC:緩沖區(qū)數(shù)據(jù)只指定1次,但是這些數(shù)據(jù)使用頻率非常高
DYNAMIC:緩沖區(qū)數(shù)據(jù)常常更新管行,并且使用頻率也很高

4、glEnableVertexAttribArray (GLuint index)

 開啟對應(yīng)的頂點屬性(坐標(biāo),紋理坐標(biāo),顏色等)

5、glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid ptr)*

  為頂點屬性(坐標(biāo),紋理坐標(biāo)狂秘,顏色等)配置合適的值
 //參數(shù)1:GLuint indx 聲明這個屬性的名稱
 //參數(shù)2:GLint size定義這個屬性由多少個值組成清女。譬如說position是由3個GLfloat組成
 //參數(shù)3: GLenum type聲明每一個值是什么類型。我們都用了GL_FLOAT
 //參數(shù)4:GLboolean normalized , GL_FALSE就好了
 //參數(shù)5:GLsizei stride stride的大小卦方,描述每個vertex數(shù)據(jù)的大小
 //參數(shù)6:const GLvoid* ptr , 數(shù)據(jù)結(jié)構(gòu)的偏移量。從這個結(jié)構(gòu)中哪里開始獲取值。
 //Position的值在前面擒贸,所以傳(GLfloat *)NULL + 0進(jìn)去就可以了案淋。
 //而TexCoord是緊接著位置的數(shù)據(jù)誉碴,而position的大小是3個float的大小,所以是從(GLfloat *)NULL + 3開始的

<h6>4.3瓣距、重要代碼說明 之 創(chuàng)建著色器效果</h6>

//創(chuàng)建著色器效果
- (void)setupBaseEffect{

    //GLKTextureLoader讀取圖片黔帕,創(chuàng)建紋理GLKTextureInfo
    NSString *filePath = [[NSBundle mainBundle]pathForResource:@"ic_dog" ofType:@"jpeg"];
    //GLKTextureLoaderOriginBottomLeft 參數(shù)是避免紋理上下顛倒,原因是紋理坐標(biāo)系和世界坐標(biāo)系的原點不同蹈丸。
    NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], GLKTextureLoaderOriginBottomLeft, nil];
    //加載圖片
    GLKTextureInfo* textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];

    // 創(chuàng)建著色器GLKBaseEffect蹬屹,把紋理賦值給著色器
    self.mEffect = [[GLKBaseEffect alloc] init];
    self.mEffect.texture2d0.enabled = GL_TRUE;
    self.mEffect.texture2d0.name = textureInfo.name;

    //啟動著色器
    [self.mEffect prepareToDraw];
  }

<h6>4.4侣背、重要代碼說明 之 繪制圖片到屏幕</h6>

#pragma mark - GLKViewDelegate
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    // 清屏
    glClearColor(0.3f, 0.6f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // 繪制 
    // self.mCount = sizeof(indices) / sizeof(indices[0]);
    glDrawElements(GL_TRIANGLES, self.mCount, GL_UNSIGNED_INT, 0);
}

函數(shù)
glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid indices)*

 //繪制,在每個vertex上調(diào)用我們的vertex shader慨默,每個像素調(diào)用fragment shader贩耐。
 //參數(shù)1:聲明用哪種特性來渲染圖形。有GL_LINE_STRIP厦取、GL_TRIANGLE_FAN和GL_TRIANGLE等潮太。然而GL_TRIANGLE(三角形)最常用。
 //參數(shù)2: 告訴渲染器有多少個圖形要渲染虾攻。
 //參數(shù)3: 指每個indices中的index類型,GL_UNSIGNED_INT
 //參數(shù)4:它是一個指向indices的指針铡买。已經(jīng)存入緩存,這里不需要了.

<h5>5霎箍、思考</h5>

1奇钞、為什么繪制出來的三角形,矩形(圖片的幾何位置)的高比寬長漂坏。
答: 雖然本例中景埃,三角形、矩形在純數(shù)學(xué)的OpenGL ES坐標(biāo)系中顶别,長和寬是相等的谷徙。但是在本例中,幀緩存是按像素來匹配屏幕尺寸的驯绎。在渲染時候完慧,GPU會轉(zhuǎn)換 純數(shù)學(xué)的OpenGL ES坐標(biāo)系的X、Y剩失、Z坐標(biāo)幀緩存中所對應(yīng)的真實像素位置屈尼。幀緩存中的像素位置叫做視口(viewport)坐標(biāo)。轉(zhuǎn)換為視口坐標(biāo)的后果就是:所繪制的集合圖形被拉伸以適應(yīng)屏幕大小拴孤,也就是高比寬大了脾歧。

代碼直通車QSOpenGLES001

iOS開發(fā)-OpenGL ES入門教程1
OpenGL學(xué)習(xí)八:緩沖區(qū)對象

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市乞巧,隨后出現(xiàn)的幾起案子涨椒,更是在濱河造成了極大的恐慌,老刑警劉巖绽媒,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚕冬,死亡現(xiàn)場離奇詭異,居然都是意外死亡是辕,警方通過查閱死者的電腦和手機(jī)囤热,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來获三,“玉大人旁蔼,你說我怎么就攤上這事锨苏。” “怎么了棺聊?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵伞租,是天一觀的道長。 經(jīng)常有香客問我限佩,道長葵诈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任祟同,我火速辦了婚禮作喘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘晕城。我一直安慰自己泞坦,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布砖顷。 她就那樣靜靜地躺著贰锁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪择吊。 梳的紋絲不亂的頭發(fā)上李根,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天槽奕,我揣著相機(jī)與錄音几睛,去河邊找鬼。 笑死粤攒,一個胖子當(dāng)著我的面吹牛所森,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播夯接,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼焕济,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了盔几?” 一聲冷哼從身側(cè)響起晴弃,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎逊拍,沒想到半個月后上鞠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡芯丧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年芍阎,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缨恒。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡谴咸,死狀恐怖轮听,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情岭佳,我是刑警寧澤血巍,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站珊随,受9級特大地震影響藻茂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜玫恳,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一辨赐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧京办,春花似錦掀序、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至财饥,卻和暖如春换吧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钥星。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工沾瓦, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人谦炒。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓贯莺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親宁改。 傳聞我的和親對象是個殘疾皇子缕探,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容