OpenGL ES - iOS (一)

緩存

緩存:指圖形處理器能夠控制和管理的連續(xù)RAM,程序從CPU的內(nèi)存復(fù)制數(shù)據(jù)到OpenGL ES的緩存,在GPU取得一定的所有權(quán)之后,運(yùn)行在CPU中的程序理想的情況下將不在接觸這個(gè)緩存。為緩存提供數(shù)據(jù)有如下7個(gè)步驟:
1.生成(Generate) :請(qǐng)求OpenGL ES 為圖形處理器控制的緩存生成一個(gè)獨(dú)一無二的標(biāo)識(shí)符。
2.綁定(Bind):告訴OpenGL ES為接下來的運(yùn)算使用一個(gè)緩存。
3.緩存數(shù)據(jù)(Buffer Data):讓OpenGL ES為當(dāng)前綁定的緩存分配并初始化足夠的連續(xù)內(nèi)存(通常是從CPU控制的內(nèi)存復(fù)制數(shù)據(jù)到分配的內(nèi)存)。
4.啟用(Enable)或者禁止(Disable):告訴OpenGL ES在接下來的渲染中是否使用緩存中的數(shù)據(jù)。
5.設(shè)置指針(Set Pointers):告訴OpenGL ES在緩存中的數(shù)據(jù)類型和所需要訪問的數(shù)據(jù)的內(nèi)存偏移值。
6.繪圖(Draw):使用當(dāng)前綁定并啟用的緩存中的數(shù)據(jù)渲染整個(gè)場(chǎng)景或者某個(gè)場(chǎng)景的一部分。
7.刪除(Delete):刪除以前生成的緩存并釋放相關(guān)的資源。

OpenGL ES為一種類型的緩存在使用過程中的每一個(gè)步驟的執(zhí)行定義了下面的C語言函數(shù),同時(shí)為其他的類型緩存提供了類似的函數(shù)

  • glGenBuffers() ----為圖形處理器控制的緩存生成一個(gè)獨(dú)一無二的標(biāo)識(shí)符。
  • glBindBuffer() -----為接下來的運(yùn)算使用一個(gè)緩存。
  • glBufferData() 或glBufferSubData() ----為當(dāng)前綁定的緩存分配并出水啊足夠的連續(xù)內(nèi)存。
  • glEnableVertexAttribArray()或glDisableVertexAttribArray() ----在接下來的渲染中是否使用緩存中的數(shù)據(jù)。
  • glVertexAttribPointer() ----在緩存中的數(shù)據(jù)的類型和所有需要訪問的數(shù)據(jù)的內(nèi)存偏移值
  • glDrawArrays() 或者glDrawElements----使用當(dāng)前綁定并啟用的緩存中的數(shù)據(jù)渲染整個(gè)場(chǎng)景或者某個(gè)場(chǎng)景的一部分。
  • glDeleteBuffers() ----刪除以前生成的緩存并釋放相關(guān)的資源。

畫一個(gè)簡(jiǎn)單的三角形 --示例代碼

#import "ViewController.h"

@interface ViewController ()
{
    GLuint vertexBufferID;
}

@property(nonatomic,strong)GLKBaseEffect *baseEffect;

@end

@implementation ViewController

@synthesize baseEffect;

typedef struct{

    GLKVector3 positionCoords;
    
}scenVertex;

static const scenVertex vertices[] =
{
    {{-0.5f,-0.5f,0.0}}, //左下角
    {{0.5f,-0.5f,0.0}},  //右下角
    {{-0.5f,0.5f,0.0}}   //左上角

};

- (void)viewDidLoad {
    [super viewDidLoad];
    
    GLKView *view = (GLKView *)self.view;
    
    NSAssert([view isKindOfClass:[GLKView class]],@"這個(gè)View不是GLKitViewController的View");
    
    view.context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
    
    [EAGLContext setCurrentContext:view.context];
    
    self.baseEffect = [[GLKBaseEffect alloc]init];
    
    self.baseEffect.useConstantColor = GL_TRUE;
    //用白色來渲染三角形,意味著在三角形中每一個(gè)像素都有相同的顏色值。
    self.baseEffect.constantColor = GLKVector4Make(1.0f,    //Red
                                                   1.0f,    //Green
                                                   1.0f,    //Blue
                                                   1.0f);  //Alpha
   
    //設(shè)置當(dāng)前上下文的“清除顏色” 為不透明黑色,用戶上下文的幀緩存被清除時(shí)候初始化每個(gè)像素的顏色值
    glClearColor(0.0f,   //Red
                 0.0f,   //Green
                 0.0f,   //Blue
                 1.0f);  //Alpha
    /* 步驟一:為緩存生成一個(gè)獨(dú)一無二的標(biāo)識(shí)符。
     */
    glGenBuffers(1,                 //第一個(gè)參數(shù)是生成緩存標(biāo)識(shí)符的數(shù)量。
                 &vertexBufferID);  //第二個(gè)參數(shù)是一個(gè)指針 指向生成標(biāo)識(shí)符的內(nèi)存保存位置,
    
    /* 步驟二:為接下來的運(yùn)算綁定緩存,綁定指定標(biāo)識(shí)符的緩存到當(dāng)前緩存
     */
    glBindBuffer(GL_ARRAY_BUFFER,   //第一個(gè)參數(shù)是常量,用于指定綁定哪一種類型的緩存 有GL_ARRAY_BUFFER和
                                    //GL_ELEMENT_ARRAY_BUFFER;其中GL_ARRAY_BUFFER用于指定一個(gè)頂點(diǎn)屬性的數(shù)組。
                 vertexBufferID);   //
    /* 步驟三:復(fù)制數(shù)據(jù)到緩存中,復(fù)制應(yīng)用的頂點(diǎn)數(shù)據(jù)到當(dāng)前的上下文所綁定的頂點(diǎn)緩存中
     */

    glBufferData(GL_ARRAY_BUFFER,   //第一個(gè)參數(shù)指定要更新當(dāng)前上下文中所綁定的哪一個(gè)緩存
                 sizeof(vertices),  //第二個(gè)參數(shù)指定要復(fù)制進(jìn)這個(gè)緩存的字節(jié)的數(shù)量
                 vertices,          //第三個(gè)參數(shù)要復(fù)制字節(jié)的地址
                 GL_STATIC_DRAW);   //第四個(gè)參數(shù)是緩存在未來的運(yùn)算中可能將會(huì)被怎樣使用,其中GL_STATIC_DRAW提示會(huì)告訴上下文緩存中的內(nèi)容適合復(fù)制到GPU控制的內(nèi)存 因?yàn)楹苌傩薷?可以幫助OpenGL ES優(yōu)化內(nèi)存使用,而使用GL_DYNAMIC_DRAW提示會(huì)告訴上下文緩存中的數(shù)據(jù)會(huì)頻繁改變,并提示OpenGL ES以不同的方式來處理緩存數(shù)據(jù)。
  
    // Do any additional setup after loading the view, typically from a nib.
}

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
    
    [self.baseEffect prepareToDraw];

    glClear(GL_COLOR_BUFFER_BIT);
    
    /*步驟四:啟動(dòng),通過glEnableVertexAttribArray()來啟動(dòng)頂點(diǎn)緩存渲染操作
     */
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    
    /*步驟五:設(shè)置指針
     */
    glVertexAttribPointer(GLKVertexAttribPosition,  //第一個(gè)參數(shù):當(dāng)前綁定的緩存包含每個(gè)頂點(diǎn)的位置信息
                          3,                        //第二個(gè)參數(shù):每個(gè)位置有三個(gè)部分
                          GL_FLOAT,                 //第三個(gè)參數(shù):每個(gè)部分都保存為一個(gè)浮點(diǎn)值類型
                          GL_FALSE,                 //第四個(gè)參數(shù):小數(shù)點(diǎn)固定數(shù)據(jù)是否被改變。
                          sizeof(scenVertex),       //第五個(gè)參數(shù):“步幅”
                          NULL);                    //第六個(gè)參數(shù):NULL 則說明從當(dāng)前綁定的頂點(diǎn)魂村的開始位置訪問頂點(diǎn)數(shù)據(jù)
    /*步驟六:繪圖
     */
    glDrawArrays(GL_TRIANGLES, // 第一個(gè)參數(shù):怎么處理頂點(diǎn)緩存內(nèi)的頂點(diǎn)數(shù)據(jù)
                 0,            //第一個(gè)頂點(diǎn)的位置
                 3);           //渲染頂點(diǎn)的數(shù)量
    

    

}

-(void)viewDidUnload{
    
    GLKView *view = (GLKView *)self.view;
    [EAGLContext setCurrentContext:view.context];
    
    if (vertexBufferID != 0) {
        glDeleteBuffers(1,
                        &vertexBufferID);
        vertexBufferID = 0;
    }
    
    ((GLKView *)self.view).context = nil;
    [EAGLContext setCurrentContext:nil];
    
    
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,716評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,706評(píng)論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,036評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評(píng)論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,203評(píng)論 0 290
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,725評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,451評(píng)論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,677評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,857評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評(píng)論 1 295
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,407評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,643評(píng)論 2 380

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