一.Hello--OpenGLES?
????????????????OpenGL可用于渲染2D和3D圖像瘸羡,是一個多用途的開源圖形庫。OpenGL設(shè)計用來將函數(shù)命令轉(zhuǎn)換成圖形命令搓茬,發(fā)送到GPU中犹赖。GPU正是被設(shè)計用來處理圖形命令的,所以O(shè)penGL的繪制非常高效卷仑。
????????????????OpenGLES是OpenGL的簡化版本峻村,拋棄了冗余的文件及命令,使之專用于嵌入式設(shè)備锡凝。OpenGLES使得移動APP能充分利用GPU的強(qiáng)大運(yùn)算能力粘昨。iOS設(shè)備上的GPU能執(zhí)行更精確的2D和3D繪制,以及更加復(fù)雜的針對每個像素的圖形腳本(shader)計算窜锯。?持的平臺: iOS, Andriod , BlackBerry ,bada ,Linux ,Windows张肾。
1.1準(zhǔn)備工程
????????????????iOS新建工程淆游,@interface ViewController : UIViewController改成-->@interface ViewController : GLKViewController,.h文件導(dǎo)入#import<GLKit/GLKit.h>炸渡,.m導(dǎo)入#import<OpenGLES/ES3/gl.h>#import<OpenGLES/ES3/glext.h>,最后在Main.storyboard中將view改成GLVIew
1.2EAGLContext(OpenGL 上下文)
? ??????????????EAGLContext對象管理著OpenGLES的渲染context岗喉,即所有繪制的狀態(tài)驾孔,命令及資源信息芍秆,并控制GPU去執(zhí)行渲染運(yùn)算。 繪制如textures及renderbuffers的過程翠勉,是由一個與context綁定的EAGLSharegroup對象來管理的妖啥。當(dāng)初始化一個EAGLContext對象的時候,可選擇新建一個sharegroup对碌,或者使用已有的荆虱,這一點我們往往采用系統(tǒng)默認(rèn)即可。在繪制到context之前,我們要先綁定一個完整的framebuffer對象到context中怀读。
? ? ? ? ? ? ? ? 1)初始化上寫文:context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES3];(參數(shù)知識選擇版本)
? ? ? ? ? ? ? ? 2)設(shè)置當(dāng)前上下文:[EAGLContext setCurrentContext:context];
? ? ? ? ? ? ? ? 3)GLView綁定上下文:GLKView *view =(GLKView *) self.view; ?view.context=context;
? ? ? ? ? ? ? ? 注意:在使用GLview中诉位,我們必須實現(xiàn)它的協(xié)議:GLKViewDelegate--->- (void)glkView:(GLKView*)viewdrawInRect:(CGRect)rect,GLKView對象使其OpenGL ES上下文成為當(dāng)前上下文愿吹,并將其framebuffer綁定為OpenGL ES呈現(xiàn)命令的目標(biāo)不从。然后,委托方法應(yīng)該繪制視圖的內(nèi)容犁跪。我們給GLview設(shè)置顏色椿息,看一下效果:glClearColor(1, 0, 0, 1.0);
二.顯示圖片
2.1設(shè)置頂點坐標(biāo)/紋理坐標(biāo)
?????????????????在OpenGl中我們顯示一張圖片,首先我們設(shè)置頂點數(shù)組坷衍,綁定紋理寝优,在OpenGLES中,我們一樣這么設(shè)置:
????????????????????????????????GLfloatvertexData[] = {
? ? ? ? ????????????????????????????????????????????????????????????????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,//左下
? ????????????????????????????????????????????????????????????????? };
? ????????????????在OpenGL中我們提到了圖形繪制是點枫耳,線乏矾,三角形,正方形由兩個三角形組成迁杨,就是六個頂點钻心,而我們知道,紋理的坐標(biāo)范圍是(0铅协,1)捷沸,其原點是在左下角,所以坐標(biāo)(0狐史,0)是原點痒给,右上角(1,1)骏全;
2.2開辟頂點緩存區(qū)并把數(shù)據(jù)存到緩中區(qū)
????????????????(1).創(chuàng)建頂點緩存區(qū)標(biāo)識符ID
? ? ????????????????????GLuint ?bufferID;
? ????????????????????? glGenBuffers(1, &bufferID);(分配紋理)
????????????????(2).綁定頂點緩存區(qū).(明確作用)
? ??????????????????????glBindBuffer(GL_ARRAY_BUFFER, bufferID);
? ??????????????(3).將頂點數(shù)組的數(shù)據(jù)copy到頂點緩存區(qū)中(GPU顯存中)
? ??????????????????????glBufferData(GL_ARRAY_BUFFER,sizeof(vertexData), vertexData,GL_STATIC_DRAW);
? ? ? ? ? ? ? ? (4).打開讀取通道.
? ? ? ? ? ? ? ? ? ? ? ? 1)頂點坐標(biāo)數(shù)據(jù)
? ????????????????????????? glEnableVertexAttribArray(GLKVertexAttribPosition);
? ? ????????????????????????glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 0);
? ? ? ? ? ? ? ? ? ? ? ? 2)紋理坐標(biāo)數(shù)據(jù)
????????????????????????????glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
? ? ????????????????????????glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 3);
特別說明:
? ??????????????????(1)在iOS中, 默認(rèn)情況下苍柏,出于性能考慮,所有頂點著色器的屬性(Attribute)變量都是關(guān)閉的.意味著,頂點數(shù)據(jù)在著色器端(服務(wù)端)是不可用的. 即使你已經(jīng)使用glBufferData方法,將頂點數(shù)據(jù)從內(nèi)存拷貝到頂點緩存區(qū)中(GPU顯存中).所以, 必須由glEnableVertexAttribArray 方法打開通道.指定訪問屬性.才能讓頂點著色器能夠訪問到從CPU復(fù)制到GPU的數(shù)據(jù).
?? ? ????????????????注意: 數(shù)據(jù)在GPU端是否可見姜贡,即试吁,著色器能否讀取到數(shù)據(jù),由是否啟用了對應(yīng)的屬性決定鲁豪,這就是glEnableVertexAttribArray的功能潘悼,允許頂點著色器讀取GPU(服務(wù)器端)數(shù)據(jù)。
? ????????????????? (2)方法簡介
? ? ????????????????????glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) ? ?功能: 上傳頂點數(shù)據(jù)到顯
存的方法(設(shè)置合適的方式從buffer里面讀取數(shù)據(jù))
? ? ? ? ?參數(shù)列表:
? ? ? ? ????????????????index,指定要修改的頂點屬性的索引值,例如 size, 每次讀取數(shù)量爬橡。(如position是由3個(x,y,z)組成,而顏色是4個(r,g,b,a),紋理則是2個,type,指定數(shù)組中每個組件的數(shù)據(jù)類型棒动〔谏辏可用的符號常量有GL_BYTE, GL_UNSIGNED_BYTE,GL_SHORT,GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值為GL_FLOAT船惨。 normalized,指定當(dāng)被訪問時柜裸,固定點數(shù)據(jù)值是否應(yīng)該被歸一化(GL_TRUE)或者直接轉(zhuǎn)換為固定點值(GL_FALSE)stride,指定連續(xù)頂點屬性之間的偏移量缕陕。如果為0,那么頂點屬性會被理解為:它們是緊密排列在一起的疙挺。初始值為0 ,ptr指定一個指針扛邑,指向數(shù)組中第一個頂點屬性的第一個組件。初始值為0
2.2獲取紋理
? ? ? ? ? ? ? ? 1)路徑:NSString *filePath = [[NSBundle mainBundle]pathForResource:@"kunkun" ofType:@"jpg"];
? ? ? ? ? ? ? ? 2)參數(shù):NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1),GLKTextureLoaderOriginBottomLeft, nil];
?? ?????????????????????????????GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
? ? ? ? ? ? ? ? 說明:紋理坐標(biāo)原點是左下角,但是圖片顯示原點應(yīng)該是左上角.我們要設(shè)置圖片繪制從左上角開始繪制GLKTextureLoaderOriginBottomLeft铐然;
? ? ? ? ? ? ? ? 3)cEffect:你可以把它理解成UIimageVIew蔬崩,用于顯示圖片的控件,iOS提供GLKBaseEffect 完成著色器工作(頂點/片元)
????????????????????????????cEffect = [[GLKBaseEffect alloc]init];
? ? ????????????????????????cEffect.texture2d0.enabled = GL_TRUE;
? ? ????????????????????????cEffect.texture2d0.name= textureInfo.name;
????????????????最后在GLVIew的delegate中:
????????????????????????????????????????????????1.清除顏色緩沖區(qū)
? ? ????????????????????????????????????????????glClear(GL_COLOR_BUFFER_BIT);
?? ?????????????????????????????????????????????2.準(zhǔn)備繪制
? ? ????????????????????????????????????????????[cEffect prepareToDraw];
?? ?????????????????????????????????????????????3.開始繪制
? ? ????????????????????????????????????????????glDrawArrays(GL_TRIANGLES, 0, 6);
三.OpenGLES繪制立方體
? ? ? ? 在OpenGLES繪制立方體搀暑,相當(dāng)于繪制六個面沥阳,十二個三角形,60個數(shù)據(jù)(當(dāng)然你在圖元連接方式那里可以選擇平面自点,GL_TRIANGLE_FAN桐罕,這樣就會少設(shè)置一點數(shù)據(jù),這里我選擇GL_TRIANGLES)
GLfloatvertexData[] = {
? ? ? ? //第一個面
? ? ? ? 0.5, -0.5, -0.5f,? ? 1.0f,0.0f,//右下
? ? ? ? 0.5,0.5,? -0.5f,? ? 1.0f,1.0f,//右上
? ? ? ? -0.5,0.5, -0.5f,? ? 0.0f,1.0f,//左上
? ? ? ? -0.5, -0.5, -0.5f,? 0.0f,0.0f,//左下
? ? ? ? 0.5, -0.5,0.5f,? ? 1.0f,0.0f,//右下
? ? ? ? 0.5,0.5,? 0.5f,? ? 1.0f,1.0f,//右上
? ? ? ? -0.5,0.5,0.5f,? ? 0.0f,1.0f,//左上
? ? ? ? -0.5, -0.5,0.5f,? 0.0f,0.0f,//左下
//
? ? ? ? //2
? ? ? ? 0.5, -0.5, -0.5f,? ? 1.0f,0.0f,//右下
? ? ? ? 0.5, -0.5,0.5f,? ? 1.0f,1.0f,//右下
? ? ? ? -0.5, -0.5,0.5f,? ? 0.0f,1.0f,//右下
? ? ? ? -0.5, -0.5, -0.5f,? ? 0.0f,0.0f,//右下
? ? ? ? 0.5,0.5, -0.5f,? ? 1.0f,0.0f,//右下
? ? ? ? 0.5,0.5,0.5f,? ? 1.0f,1.0f,//右下
? ? ? ? -0.5,0.5,0.5f,? ? 0.0f,1.0f,//右下
? ? ? ? -0.5,0.5, -0.5f,? ? 0.0f,0.0f,//右下
? ? ? ? //3
? ? ? ? 0.5, -0.5, -0.5f,? ? 1.0f,0.0f,//右下
? ? ? ? 0.5, -0.5,0.5f,? ? 1.0f,1.0f,//右下
? ? ? ? 0.5,0.5,0.5f,? ? 0.0f,1.0f,//右下
? ? ? ? 0.5,0.5, -0.5f,? ? 0.0f,0.0f,//右下
? ? ? ? -0.5, -0.5, -0.5f,? ? 1.0f,0.0f,//右下
? ? ? ? -0.5, -0.5,0.5f,? ? 1.0f,1.0f,//右下
? ? ? ? -0.5,0.5,0.5f,? ? 0.0f,1.0f,//右下
? ? ? ? -0.5,0.5, -0.5f,? ? 0.0f,0.0f,//右下
? ? };
四桂敛。CoreAnimation正方體的大體原理就是一個VIew上放六個imageVIew功炮,并設(shè)置imageVIew旋轉(zhuǎn)組成一個立方體,一共6個术唬,最后添加定時器控制view的layer轉(zhuǎn)動薪伏,達(dá)到效果,因為比較簡單碴开,這里不做展示