青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

黎明的剔透里伸出了你沁清的曖昧

Graphics|EngineDev|GameDev|2D&3D Art

  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
  60 隨筆 :: 1 文章 :: 18 評論 :: 0 Trackbacks

üOpenGL提供頂點數組函數
啟用數組:
glEnableClientState(GLenum array);來啟動指定的數組
參數可以為
GL_VERTEX_ARRAY
GL_COLOR_ARRAY
GL_SECOND_COLOR_ARRAY
GL_INDEX_ARRAY
GL_NORMAL_ARRAY
GL_FOG_COORDINATE_ARRAY
GL_TEXTURE_COORD_ARRAY
GL_GLAG_ARRAY
指定數組中的數據:
void glVertexPointer(GLint size,GLenum type,GLsize srtide,cinst GLvoid *pointer);
size 是每個頂點的坐標數目,必須是2,3,4
type 是指定數組每個坐標的數據類型(GL_FLOAT,GL_INT,GL_SHORT,GL_DOUBLE)
stride 是為兩個相鄰頂點之間的偏移量,單位為字節. stride為0 表明頂點是緊密存儲在數組中
pointer是數組中第一個頂點的第一個坐標的內存地址
指定其他數組數據的函數類似:glColorPointer();

解除引用和渲染
對單個數組元素解除引用:
void glArrayElement(GLuint ith);
這個函數對單個數組元素解除引用,參數ith是要獲得啟用數組中數據的下標,如果同時指定了顏色及法線等信息,那么對于每個頂點只調用glArrayElement()一次,減少了函數調用的次數,
對一系列數組元素解除引用:
void glArrayElements(GLenum mode,GLsize count,GLenum type,void *index);
mode取值和glBegin()參數值相同,count為元素個數,type指出了數組index的數據類型:必須為GL_UNSIGNED_BYTE 、GL_UNSIGNED_SHOART 、GL_UNSIGNED_INT
對一系列相鄰數組元素解除引用
void glDrawArrays(GLenum mode,GLint first,GLsize count);
在每個被啟用的數組中,使用從first到first+count-1對應的數組元素,來構建一些列幾何圖元,參數mode指定構建哪種圖元-同glBegin()中的參數一樣
該函數的第一個參數用于指定繪制模式。關于繪制模式我們稍后會有詳細的介紹。
第二個參數用于指定所允許的頂點的起始頂點。比如說,我們之前定義了5個頂點,但是我們在畫正方形的時候想跳過第一個頂點,從第二個頂點開始畫,那么索引就是1(起始索引值為0)。
第三個參數要繪制的頂點的個數。

static struct
{
    GLubyte colours[
4];
    GLfloat vertices[
3];
     
}
vertexInfoList[] = {
    
{2552550255}{1.0f1.0f0.0f} },
    
{25500255}{-0.5f0.5f0.0f} },
    
{02550255}{-0.5f-0.5f0.0f} },
    
{00255255}{0.5f0.5f0.0f} },
    
{2550255255}{0.5f-0.5f0.0f} }
}
;
 
glClear(GL_COLOR_BUFFER_BIT);
 
glVertexPointer(
3, GL_FLOAT, 16, vertexInfoList[0].vertices);
glColorPointer(
4, GL_UNSIGNED_BYTE, 16, vertexInfoList[0].colours);
 
glDrawArrays(GL_TRIANGLE_STRIP, 
04);


GPU的一個特點是擁有大規模的線程以及超大的帶寬。因此,我們用glBegin/glEnd對去一點點繪制圖形的話對GPU而言是非常低效的。GPU喜歡做的是一口氣把所有命令讀上來,然后分派到不同的流處理器去執行。每條流處理器又有很多個線程。GPU的流水線比較長,做的工作也是比較特定的。為了方便GPU來處理主機端的數據,我們通常會把頂點信息以及其相應的顏色信息組成連續存放的數組形式。這樣既有利于存儲器訪問,而且也利于GPU快速加載(比如通過內部的DMA)。
glVertexPointer函數定義了一組頂點數據的一個數組。其原型如下:

1void glVertexPointer(    GLint      size,
2                                     GLenum      type,
3                                     GLsizei      stride,
4                                     const GLvoid *      pointer);

第一個參數指定了每個頂點的坐標分量個數。比如,我們這里一個頂點的坐標有三個分量,分別是:x,y,z。如果只有兩個分量的話,z分量在處理時會被置0;如果有4個分量,那么就會增加w分量。w分量用于線性變換,這將是下一講的話題。這個參數只能是2、3或4。
第二個參數用于指定頂點每個坐標分量的數據類型。可以是:GL_SHORT、GL_INT、GL_FLOAT或GL_DOUBLE。在OpenGL ES中沒有GL_DOUBLE。

這里稍微講一下頂點坐標分量的數據類型。每個頂點的所有坐標分量必須的數據類型必須是一致的,不能定義x分量時用int,然后定義y 的時候就用float。并且每個頂點的坐標分量類型必須相同。
在GPU中,其專門有快速浮點計算,因此提高GPU處理數據的速度往往會使用float類型,而不是int。不過即使是當前主流桌面計算機用的GPU,其對double類型的支持比較弱,因為double需要消耗2倍于float的帶寬。所以就目前而言,不管是OpenGL還是OpenGL ES,往往使用GLfloat類型來定義頂點坐標,以使得做線性變換計算時能充分利用GPU的計算單元的性能。

第三個參數指定相鄰兩個頂點的偏移字節數。上面用的是:glVertexPointer(3, GL_FLOAT, 16, vertexInfoList[0].vertices);
因為第一個頂點的起始地址與第二個頂點的起始地址之間相差16個字節——即sizeof(vertexInfoList[0])。
第四個參數用來指定頂點數組的起始位置。
glColorPointer與glVertexPointer定義一樣。它用來指定一組頂點顏色信息的數組。其原型如下:

1
2
3
4
void glColorPointer(    GLint      size,
                        GLenum      type,
                        GLsizei      stride,
                        const GLvoid *      pointer);


第一個參數是每個顏色信息的分量個數,在OpenGL中可以是3或4;而OpenGL ES1.1中必須是4。如果是3個分量,則依次表示紅(R)、綠(G)、藍(B);如果是4個分量,那么前三個與前面的一樣,第四個分量是alpha,表示透明度。
第二個參數用于指定顏色分量的數據類型,可以是:GL_BYTE、GL_UNSIGNED_BYTE、GL_SHORT、GL_UNSIGNED_SHORT、GL_INT、GL_UNSIGNED_INT、GL_FLOAT、GL_DOUBLE;不過在OpenGL ES1.1中,常常使用GL_UNSIGNED_BYTE或GL_FLOAT。
第三個和第四個參數與glVertexPointer一樣。

通過指定頂點的坐標信息和顏色信息,后面就可以利用glDrawArrays進行繪制了。

glDrawElements來繪制圖形。
glDrawElements用于通過一個用戶自定義的索引數組來繪制圖形。下面看看其原型:

1
2
3
4
void glDrawElements(    GLenum      mode,
                        GLsizei      count,
                        GLenum      type,
                        const GLvoid *      indices);


第一個參數用于指定圖元繪制模式;
第二個參數用于指定所要繪制頂點的個數;
第三個參數用于指定索引的數據類型;
第四個參數用于指定索引的起始地址。
這個函數可以很方便地用于繪制多個圖形。首先,頂點信息往往比較大(由于包括了一個頂點的所有坐標分量信息以及顏色分量信息,甚至還有法線信息等),因此如果我們所要繪制的圖形通過已指定的頂點就能繪制出,就無需重復地定義頂點,而只需要通過一個簡短的索引數組就能解決問題。
其次,調用一條命令繪制圖形往往比調多次效率要高,功耗要小。

在OpenGL中圖元繪制模式有: GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_QUAD_STRIP, GL_QUADS, 以及GL_POLYGON。
在OpenGL ES1.1中,圖元繪制模式有:GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN以及GL_TRIANGLES。
下面我們將逐一介紹。

首先是GL_POINTS,這個模式是僅繪制頂點。當我們使用glDrawArrays時,頂點通過由glVertexPointer和glColorPointer所指定的順序將依次被繪制出。
我們可以嘗試一下:

1
glDrawArrays(GL_POINTS, 0, 4);


將上述代碼替換掉原來的對glDrawArrays的調用。

GL_LINE_STRIP模式:
這個模式用于繪制線段帶。比如現在有頂點v0, v1, v2, v3,那么繪制出的線段為帶由三條線段構成,依次為:(v0, v1), (v1, v2), (v2, v3)。

1
glDrawArrays(GL_LINE_STRIP, 0, 4);


將上述代碼替換掉原來的對glDrawArrays的調用,然后查看結果。


GL_LINE_LOOP模式:
這個模式與GL_LINE_STRIP模式一樣,除了最后一個頂點與第一個頂點仍然連成一條線段。比如,有4個頂點:v0, v1, v2, v3,那么構成的線段帶為:(v0, v1), (v1, v2), (v2, v3), (v3, v0),共4條線段。

1
glDrawArrays(GL_LINE_LOOP, 0, 4);


請將上述代碼替換掉原來對glDrawArrays的調用,觀察結果。

GL_LINES模式:
該模式是對兩個頂點僅繪制一條線段,并且每個頂點在且在一條線段上,由該模式下所繪制出的線段組中,不會有相交的兩條線段。比如有4個頂點:v0, v1, v2, v3,那么繪制出的線段為:(v0, v1), (v2, v3);如果只有三個頂點:(v0, v1, v2),那么將只有(v0, v1)一條線段。

1
glDrawArrays(GL_LINES, 0, 4);

將上述代碼替換掉原來代碼中對glDrawArrays的調用,并觀察結果。然后將4改為3再觀察結果

GL_TRIANGLE_STRIP模式:
這個模式就是示例代碼中所采用的繪制模式。它是將前三個頂點構成一個三角形后,從第四個頂點開始由先前所構成的三角形的某一條邊作為公共邊然后構造后一個三角形。而構造后一個三角形的繪制順序依賴于構造第一個三角形所采用的繪制順序。

GL_TRIANGLE_FAN模式:
這個模式在構造三角形時始終以第一個頂點作為初始頂點,然后與后兩個頂點構成三角形,因此構造順序猶如打開一把折扇。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static struct
{
    GLubyte colours[4];
    GLfloat vertices[3];
 
}vertexInfoList[] = {       
    { {0, 255, 0, 255}, {-0.5f, -0.5f, -5.0f} },
    { {255, 0, 255, 255}, {0.5f, -0.5f, -3.0f} },
    { {0, 0, 255, 255}, {0.5f, 0.5f, -3.0f} },
    { {255, 0, 0, 255}, {-0.5f, 0.5f, -5.0f} }
};
 
// Drawing code here.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
glInterleavedArrays(GL_C4UB_V3F, 0, vertexInfoList);
 
glCullFace(GL_BACK);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);



將上述代碼替換掉1樓中Mac部分代碼片段中的第26到44行,觀察結果。

GL_TRIANGLES模式:
該模式與GL_LINES模式類似,取三個頂點構成一個獨立的三角形,并且頂點數組中每個頂點只對應于一個三角形

ü使用buffer  object
緩存對象
以前頂點數據數組都保存在客戶端的內存中,而有時候理想保存使用頻繁的客戶端數據(例如頂點數組數據)的位置是高性能的服務器內存。GL緩存對象提供了一套機制,使客戶端可以分配,初始化和渲染服務器端內存。
利用緩沖區對象儲存頂點數據分為以下幾個步驟.
①創建緩沖區對象.
void glGenBuffers(GLsizei n, GLuint * buffers);
該函數通過buffers返回n個未被使用的緩沖區表識符(u int).
GLboolean glIsBuffers(GLuint buffer);
確定buffer是否為已經被綁定的緩沖區表識符.

②綁定緩沖區對象.
void glBindBuffer(GLenum target, GLuint buffer);
target為GL_ARRAY_BUFFER或GL_ELEMENT_ARRAY_BUFFER之一.此函數有三種不同的行為模式.
當buffer首次使用時,就創建一個緩沖區,并綁定buffer作為其表識符.當綁定到一個以前創建的緩沖區時,這個緩沖區變成為當前活動的對象.當綁定buffer值為0時,停止使用緩沖區對象.

③使用頂點數據分配初始化緩沖區對象.
void glBufferData(GLenum target, GLsizeiptr size,const GLvoid * data,GLenum usage);
target同上,size表示分配在顯存當中的儲存單位個數.data是一個指向內存的指針,用于初始化緩沖區對象.usage提示數據在分配之后如何進行度取和寫入,根據所指定的值OpenGL實現可能會對其進行針對性的優化,它有以下幾種可能的值:
GL_STREAM_DRAW,GL_STREAM_READ,GL_STREAM_COPY,
GL_STATIC_DRAW,GL_STATIC_READ,GL_STAIC_COPY,
GL_DYNAMIC_DRAW,GL_DYNAMIC_READ,GL_DYNAMIC_COPY.
Draw-數據作為頂點數據,用于渲染.
Read-數據從一個OpenGL緩沖區(楨緩沖區之類的)讀取,并在程序中與渲染并不直接相關的各種計算過程中使用.Copy-數據從一個OpenGL緩沖區讀取,然后作為頂點數據,用于渲染.
Stream-緩沖區的對象需要時常更新,但使用次數很少.
Static-只需要一次指定緩沖區對象中的數據,但使用次數很多.
Dynamic-數據不僅需要時常更新,使用次數也很多.

④更新緩沖區對象內的數據

更新數據有以下兩種方式:

void glBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data);
target同上.由于頂點數組數據的所有格式在緩沖區對象內同樣有效.所以頂點\顏色\法線等相關數據都可以放入緩沖區中,所以需要指定一個offset作為緩沖區對象中數據的偏移量.size為起始下標.data 指向更新的數據.

另一種:

GLvoid * glMapBuffer(GLenum target,GLenum access);
target同上.access為訪問數據的方式,可以為以下幾個值:GL_READ_ONLY,GL_WRITE,GL_READ_WRITE.
這個函數直接獲得一個指向被綁定緩沖區內數據的指針,通過給值的方式讀寫緩沖區對象.在讀寫完畢之后調用GLboolean glUnmapBuffer(GLenum target);表示被綁定的緩沖區對象更新完成,并且可以釋放.

⑤清除緩沖區對象
void glDeleteBuffers(GLsizei n,const GLuint * buffers);
刪除n個緩沖區對象,由buffer表識符數組指定.
操作:

 1static const GLfloat g_vertex_buffer_data[] = {
 2   -0.5f-0.5f0.0f,
 3   0.5f-0.5f0.0f,
 4   0.0f,  0.5f0.0f,
 5}
;
 6
 7void myDispaly(){
 8    glClearColor(0.0f0.0f0.0f0.0f);
 9    glClear(GL_COLOR_BUFFER_BIT);
10      
11    // This will identify our vertex buffer
12    GLuint vertexbuffer;
13    // Generate 1 buffer, put the resulting identifier in vertexbuffer
14    glGenBuffers(1&vertexbuffer);
15    // The following commands will talk about our 'vertexbuffer' buffer
16    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
17    // Give our vertices to OpenGL
18    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
19    // 1rst attribute buffer : vertices
20    glEnableVertexAttribArray(0);
21    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
22    glVertexAttribPointer(
23                      0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
24                      3,                  // size
25                      GL_FLOAT,           // type
26                      GL_FALSE,           // normalized?
27                      0,                  // stride
28                     (void*)0            // array buffer offset
29         
30                 );
31 
32    // Draw the triangle !
33    glDrawArrays(GL_TRIANGLES, 03); // Starting from vertex 0; 3 vertices total -> 1 triangle
34 
35    glDisableVertexAttribArray(0);
36    glutSwapBuffers();
37
38}


glDrawArrays,glDrawElements - [OpenGL]
 

posted on 2012-02-19 14:35 情絕格調(fresmaster) 閱讀(2192) 評論(0)  編輯 收藏 引用 所屬分類: Graphics
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久国产91| 日韩视频亚洲视频| 日韩天天综合| 激情成人亚洲| 国产欧美一区在线| 欧美日韩一区二区三区在线观看免| 久久午夜电影| 久久亚洲综合色一区二区三区| 亚洲欧美激情视频| 久久国产精品99久久久久久老狼 | 欧美高清你懂得| 亚洲激情另类| 在线观看中文字幕不卡| 国外成人网址| 亚洲成色www8888| 在线高清一区| 亚洲精品日韩一| 亚洲老板91色精品久久| 久久久免费精品| 久久婷婷久久| 午夜在线精品| 欧美在线免费| 亚洲国产精品久久91精品| 农夫在线精品视频免费观看| 老司机午夜精品视频| 91久久久亚洲精品| 一区二区三区视频在线观看 | 欧美成ee人免费视频| 欧美激情日韩| 开元免费观看欧美电视剧网站| 久久人人看视频| 亚洲精品美女久久7777777| 亚洲精品欧美日韩| 欧美激情视频一区二区三区不卡| 亚洲欧洲一二三| 亚洲国产裸拍裸体视频在线观看乱了中文 | 亚洲欧洲一区二区天堂久久 | 欧美一级网站| 久久久xxx| 欧美成人免费在线| 91久久精品国产91性色tv| 一区二区日韩伦理片| 午夜精品一区二区三区在线视| 久久精品国产亚洲5555| 欧美激情精品久久久六区热门| 欧美视频不卡中文| 狠狠色狠狠色综合| 国产精品久久久久久久久婷婷 | 国内精品伊人久久久久av一坑| 黄网动漫久久久| 一区二区高清视频| 一区二区三区导航| 久久噜噜噜精品国产亚洲综合| 欧美激情第1页| 亚洲女优在线| 亚洲视频在线免费观看| 亚洲欧美综合另类中字| 亚洲天堂免费观看| 欧美大片网址| 亚洲高清色综合| 久久躁日日躁aaaaxxxx| 夜色激情一区二区| 欧美区日韩区| 亚洲欧美日韩精品久久| 亚洲午夜性刺激影院| 国产精品婷婷| 女生裸体视频一区二区三区| 日韩午夜黄色| 欧美紧缚bdsm在线视频| 99精品视频一区二区三区| 99综合电影在线视频| 精品1区2区3区4区| 在线一区日本视频| 国产日韩精品在线观看| 9色精品在线| 久久精品夜夜夜夜久久| 黄色日韩在线| 欧美在线一二三| 99视频超级精品| 加勒比av一区二区| 国产午夜精品久久久| 亚洲精品日韩在线观看| 激情成人av在线| 亚欧美中日韩视频| 亚洲图色在线| 国产精品大全| 午夜宅男欧美| 欧美美女福利视频| 欧美一区二区日韩一区二区| 免费成人高清| 一区二区免费在线观看| 久久成人这里只有精品| 亚洲国产成人不卡| 欧美日韩不卡合集视频| 亚洲无限乱码一二三四麻| 午夜久久资源| 亚洲激情电影在线| 国产精品激情| 久热国产精品| 亚洲免费在线观看视频| 美女被久久久| 香蕉久久国产| 亚洲九九九在线观看| 国产网站欧美日韩免费精品在线观看| 久热精品在线视频| 一本色道久久综合亚洲精品高清| 久久久青草婷婷精品综合日韩| 亚洲动漫精品| 一区二区在线视频观看| 欧美成人69av| 久久久亚洲欧洲日产国码αv| 欧美暴力喷水在线| 亚洲精品久久在线| 国产欧美一区二区三区另类精品| 久久婷婷激情| 亚洲男人影院| 亚洲精品日日夜夜| 欧美成ee人免费视频| 久久天天狠狠| 性做久久久久久| 亚洲视频一区二区| 亚洲婷婷免费| 一本大道久久a久久综合婷婷| 亚洲国产精品国自产拍av秋霞| 国产综合久久久久久鬼色| 国产乱码精品一区二区三区忘忧草 | 亚洲欧美不卡| 999亚洲国产精| 影音先锋久久精品| 国内自拍视频一区二区三区 | 狠狠网亚洲精品| 欧美午夜精品理论片a级大开眼界| 欧美中在线观看| 亚洲欧美怡红院| 亚洲日韩欧美视频一区| 亚洲美女免费精品视频在线观看| 亚洲大胆女人| 亚洲人成7777| 欧美一区二区三区免费看 | 久久久噜噜噜久噜久久 | 久久亚洲国产成人| 91久久国产精品91久久性色| 国产亚洲成av人片在线观看桃| 国产精品久久久久久久久| 国产日韩专区| 亚洲国产另类 国产精品国产免费| 99riav1国产精品视频| 亚洲摸下面视频| 久久婷婷国产综合精品青草| 久久精品国产一区二区三区免费看| 欧美va天堂va视频va在线| 久久www成人_看片免费不卡| 国产精品视频久久久| 欧美一区2区视频在线观看| 正在播放亚洲| 国产日韩亚洲欧美| 欧美成人精品福利| 久久久久91| 久久九九免费| 欧美一级夜夜爽| 日韩视频在线免费| 亚洲精品在线视频| 国产精品日韩在线观看| 久久精选视频| 欧美精品在线免费| 亚洲一区二区在| 亚洲国产日韩综合一区| 久久久午夜视频| 欧美激情麻豆| 久久gogo国模啪啪人体图| 久久亚洲高清| 午夜欧美视频| 欧美精品1区| 久久夜色精品国产欧美乱| 国产精品久久久久久妇女6080| 免费在线观看日韩欧美| 国产精品夜夜夜| 另类激情亚洲| 久久国产精品毛片| 亚洲福利免费| 一区二区精品国产| 国产美女精品免费电影| 蜜臀99久久精品久久久久久软件| 久久国内精品视频| 亚洲另类自拍| 久久久久国产成人精品亚洲午夜| 亚洲日本在线观看| 亚洲欧美怡红院| 先锋影音国产一区| 欧美成人精品高清在线播放| 亚洲欧美日韩专区| 久久人人爽人人爽爽久久| 亚洲视频精品| 欧美精品免费视频| 玖玖玖国产精品| 国产香蕉97碰碰久久人人| 久久久久久穴| 国产乱肥老妇国产一区二| 99精品国产99久久久久久福利| 国产亚洲精品自拍|