OpenGL ES _ 入門_01

OpenGL ES _ 入門_01
OpenGL ES _ 入門_02
OpenGL ES _ 入門_03
OpenGL ES _ 入門_04
OpenGL ES _ 入門_05
OpenGL ES _ 入門練習(xí)_01
OpenGL ES _ 入門練習(xí)_02
OpenGL ES _ 入門練習(xí)_03
OpenGL ES _ 入門練習(xí)_04
OpenGL ES _ 入門練習(xí)_05
OpenGL ES _ 入門練習(xí)_06
OpenGL ES _ 著色器 _ 介紹
OpenGL ES _ 著色器 _ 程序
OpenGL ES _ 著色器 _ 語法
OpenGL ES_著色器_紋理圖像
OpenGL ES_著色器_預(yù)處理
OpenGL ES_著色器_頂點著色器詳解
OpenGL ES_著色器_片斷著色器詳解
OpenGL ES_著色器_實戰(zhàn)01
OpenGL ES_著色器_實戰(zhàn)02
OpenGL ES_著色器_實戰(zhàn)03

學(xué)習(xí)是一件開心的額事情

本節(jié)學(xué)習(xí)目標

  • 創(chuàng)建一個完整的OpenGL ES 工程代碼
  • 繪制三角形
    提醒:代碼你可能看不懂,因為你沒學(xué)過這個東西增显,看完這個只要你知道是什么東西就行了,后續(xù)內(nèi)容馬上跟進!

第一步.創(chuàng)建一個工程

CA60DADE-C80A-4F8A-A4C2-A8771C952B8D.png
](http://upload-images.jianshu.io/upload_images/1594482-6a9848ca8df11b95.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

第二步:刪除掉ViewController.h和ViewController.m文件


刪除自帶文件

第三步:創(chuàng)建繼承自GLKViewController 的控制器對象时鸵,我起了一個名字叫OSViewController


創(chuàng)建對象

第四步.在OSViewController.h文件中引用框架#import <GLKit/GLKit.h>


引用框架

第五步,將創(chuàng)建的控制器和storyborad的視圖進行綁定

綁定

完成以上幾步:我們的配置算是完成了!


第六步,創(chuàng)建一個EAGContext 對象软能,用來跟蹤OpenGL 的狀態(tài)和管理數(shù)據(jù)和命令

// MARK: - 創(chuàng)建一個EAGContext
-(void)createEagContext{
self.eagcontext = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:self.eagcontext];
}

第七步.配置GLKView(剛才創(chuàng)建的控制器的view的類型就是GLKView類型)

// MARK: - 配置GLKView
-(void)configure{
GLKView *view = (GLKView*)self.view;
view.context = self.eagcontext;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
}

第八步.編寫頂點著色器程序(Shader.vsh)

CA60DADE-C80A-4F8A-A4C2-A8771C952B8D.png
attribute vec4 position; // 屬性,如果綁定了這個屬性举畸,
uniform  vec4 color; // 需要從程序中傳入的值查排,一會我們會不斷改變這個值
varying lowp vec4 colorVarying; // 這個值需要和片段著色器的聲明相同

void main()
{
   gl_Position = position; // 設(shè)置頂點位置
   colorVarying = color;  // 設(shè)置頂點顏色
 }

第九步.編寫片段著色器程序(Shader.fsh)
和上面的創(chuàng)建類似,文件名字后綴不一樣

  varying lowp vec4 colorVarying;
  void main()
  {
    gl_FragColor = colorVarying; // 設(shè)置片段著色器中的顏色
  }

第十步. 分別編譯兩個頂點著色器程序和片斷著色器源代碼抄沮。

 // 1.創(chuàng)建標示
GLuint vertShader, fragShader;
// 2.獲取文件路徑
NSString *vertShaderPathname, *fragShaderPathname;
vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
// 3.編譯
if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
    NSLog(@"編譯失敗 vertex shader");
    return NO;
}

// 創(chuàng)建 編譯 片斷著色器
fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
    NSLog(@"Failed to compile fragment shader");
    return NO;
}

編譯代碼封裝了一下,具體代碼如下:

- (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
{

//1  獲取文件的內(nèi)容 并進行NSUTF8StringEncoding 編碼
const GLchar *source;
source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
if (!source) {
    NSLog(@"Failed to load vertex shader");
    return NO;
}
//2 根據(jù)類型創(chuàng)建著色器
*shader = glCreateShader(type);
//3. 獲取著色器的數(shù)據(jù)源
glShaderSource(*shader, 1, &source, NULL);
//4. 開始編譯
glCompileShader(*shader);
// 方便調(diào)試跋核,可以不用
#if defined(DEBUG)
GLint logLength;
glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
    GLchar *log = (GLchar *)malloc(logLength);
    glGetShaderInfoLog(*shader, logLength, &logLength, log);
    NSLog(@"Shader compile log:\n%s", log);
    free(log);
}
#endif
//5. 查看是否編譯成功
GLint status;

glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
if (status == 0) {
    glDeleteShader(*shader);
    return NO;
}

return YES;
}

經(jīng)過上面的代碼 岖瑰,我們就講兩個著色器程序編譯完成


第十一步.創(chuàng)建著一個空的色器程序,把剛才編譯好的兩個著色器目標代碼砂代,連接到這個空的程序中去

  _program = glCreateProgram();
// 第九步 將頂點著色器加到程序中
glAttachShader(_program, vertShader);

// 將片斷著色器加到程序中
glAttachShader(_program, fragShader);

第十二步.將著色器程序的屬性綁定到OpenGL 中

 // 綁定著色器的屬性
glBindAttribLocation(_program, 0, "position");  // 0代表枚舉位置

第十三步.開始正式鏈接著色器程序

    if (![self linkProgram:_program]) {
    NSLog(@"Failed to link program: %d", _program);
    
    if (vertShader) {
        glDeleteShader(vertShader);
        vertShader = 0;
    }
    if (fragShader) {
        glDeleteShader(fragShader);
        fragShader = 0;
    }
    if (_program) {
        glDeleteProgram(_program);
        _program = 0;
    }
    
    return NO;
}

下面是封裝的鏈接著色器程序

- (BOOL)linkProgram:(GLuint)prog
{
// 1鏈接程序
glLinkProgram(prog);

#if defined(DEBUG)
GLint logLength;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
    GLchar *log = (GLchar *)malloc(logLength);
    glGetProgramInfoLog(prog, logLength, &logLength, log);
    NSLog(@"Program link log:\n%s", log);
    free(log);
}
#endif
// 2 檢查鏈接結(jié)果
GLint status;
glGetProgramiv(prog, GL_LINK_STATUS, &status);
if (status == 0) {
    return NO;
}  
return YES;

}


第十四步.獲取著色器中輸入變量的索引值

 _vertexcolor = glGetUniformLocation(_program, "color");

第十五步. 將頂點數(shù)據(jù)加載到GPU 中去

 // 三角形頂點數(shù)據(jù)
static GLfloat vertex[6] = {
-1,-1,// 左下
-1,1, // 左上
1,1  // 右上
 };
// 加載數(shù)據(jù)蹋订,具體的參數(shù)說明暫時不寫了,后面會專門講
-(void)loadVertex{
glGenBuffers(1, &_vertexBuffer); // 申請內(nèi)存標識
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);// 綁定
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);// 申請內(nèi)存空間
glEnableVertexAttribArray(GLKVertexAttribPosition);// 開啟頂點數(shù)據(jù)
// 設(shè)置指針
glVertexAttribPointer(GLKVertexAttribPosition, 
2, 
GL_FLOAT,
GL_FALSE, 
8,
0);
} 

第十六步. 繪制數(shù)據(jù)

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
  static NSInteger count = 0;
 // 清除顏色緩沖區(qū)
 glClearColor(1, 1, 1, 1);
 glClear(GL_COLOR_BUFFER_BIT);
 count ++;
  if (count > 50 ) {
    count = 0;
    // 根據(jù)顏色索引值,設(shè)置顏色數(shù)據(jù)刻伊,就是剛才我們從著色器程序中獲取的顏色索引值
    glUniform4f(_vertexcolor,   arc4random_uniform(255)/225.0, arc4random_uniform(255)/225.0, arc4random_uniform(255)/225.0, 1);
  }
  // 使用著色器程序
  glUseProgram(_program);
  // 繪制
  glDrawArrays(GL_TRIANGLES, 0, 3);  
 }

代碼有點多露戒,請按照步驟敲打一遍。
效果是不斷變化顏色的三角形


切圖一
切圖二

總結(jié)

OpenGL 是一個很深奧捶箱,又很神奇的東西!想學(xué)技術(shù)的加群:578734141

代碼下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末智什,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子丁屎,更是在濱河造成了極大的恐慌荠锭,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晨川,死亡現(xiàn)場離奇詭異证九,居然都是意外死亡,警方通過查閱死者的電腦和手機础爬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門甫贯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人看蚜,你說我怎么就攤上這事叫搁。” “怎么了供炎?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵渴逻,是天一觀的道長。 經(jīng)常有香客問我音诫,道長惨奕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任竭钝,我火速辦了婚禮梨撞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘香罐。我一直安慰自己卧波,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布庇茫。 她就那樣靜靜地躺著港粱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪旦签。 梳的紋絲不亂的頭發(fā)上查坪,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天寸宏,我揣著相機與錄音,去河邊找鬼偿曙。 笑死氮凝,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的遥昧。 我是一名探鬼主播覆醇,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼炭臭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起袍辞,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤鞋仍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后搅吁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體威创,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年谎懦,在試婚紗的時候發(fā)現(xiàn)自己被綠了肚豺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡界拦,死狀恐怖吸申,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情享甸,我是刑警寧澤截碴,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站蛉威,受9級特大地震影響日丹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蚯嫌,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一哲虾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧择示,春花似錦束凑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至剪菱,卻和暖如春摩瞎,著一層夾襖步出監(jiān)牢的瞬間拴签,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工旗们, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蚓哩,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓上渴,卻偏偏與公主長得像岸梨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子稠氮,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

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

  • 版本記錄 前言 OpenGL ES是一個強大的圖形庫曹阔,是跨平臺的圖形API,屬于OpenGL的一個簡化版本隔披。iOS...
    刀客傳奇閱讀 7,579評論 0 2
  • 前言 本文是關(guān)于OpenGL ES的系統(tǒng)性學(xué)習(xí)過程赃份,記錄了自己在學(xué)習(xí)OpenGL ES時的收獲。這篇文章的目標是搭...
    秦明Qinmin閱讀 6,097評論 4 27
  • 前言 OpenGL ES2.0之前是固定管線繪制圖形奢米,2.0之后開始了可編程的繪制管線抓韩。所謂固定管線即系統(tǒng)只提供A...
    Hardy_Hu閱讀 338評論 0 2
  • 目錄結(jié)構(gòu): 第一步,明確要干嘛 第二步鬓长,怎么去畫(純理論) 第三步谒拴,怎么去畫(實戰(zhàn)) 第四步,練練手 第一步涉波,明確...
    半紙淵閱讀 8,079評論 18 57
  • 晨曦英上,我竊聽窗外的雨滴,那么有磁性怠蹂、干脆善延、凈美。它城侧,絕不會拖泥帶水易遣,猶柔徘徊。哇嫌佑!多么的透徹豆茫,一滴滴的落下。我不敢...
    孑逸閱讀 235評論 0 2