opengl es入門---常見代碼解析


轉自:http://blog.csdn.net/wangyuchun_799/article/details/7736928,尊重原創!

 

3.1創建渲染緩沖區

    GLuint m_renderbuffer;//創建一個渲染緩沖區對象

    glGenRenderbuffers(1, &m_renderbuffer);//創建一個渲染緩沖區對象
    glBindRenderbuffer(GL_RENDERBUFFER, m_renderbuffer);//將該渲染緩沖區對象綁定到管線上

 

3.2創建幀緩沖區

   GLuint m_framebuffer;//創建一個幀緩沖區對象

    glGenFramebuffers(1, &m_framebuffer);//創建一個幀染緩沖區對象
    glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);//將該幀染緩沖區對象綁定到管線上
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_renderbuffer);//將創建的渲染緩沖區綁定到幀緩沖區上,並使用顏色填充

 

3.3設置視口

glViewport(0, 0, width, height);//定義視口大小,說白了就是OpenGL ES窗口大小

 

3.4創建着色器

3.4.1創建一個空着色器

GLuint shaderHandle = glCreateShader(shaderType);//shaderType代表着色器的類型,可以是GL_VERTEX_SHADER(頂點着色器)或GL_FRAGMENT_SHADER(片元着色器)

3.4.2指定着色器源代碼
    glShaderSource(shaderHandle, 1, &source, 0);// source代表要執行的源代碼字符串數組,1表示源代碼字符串數組的字符串個數是一個,0表示源代碼字符串長度數組的個數為0個

3.4.3編譯着色器
    glCompileShader(shaderHandle);//編譯着色器

3.4.4檢查編譯是否成功
    GLint compileSuccess;
    glGetShaderiv(shaderHandle, GL_COMPILE_STATUS, &compileSuccess);//查看編譯着色器是否成功,可選的查詢狀態有L_DELETE_STATUS,GL_COMPILE_STATUS, GL_INFO_LOG_LENGTH, GL_SHADER_SOURCE_LENGTH

//如果編譯出錯,則記錄出錯信息
    if (compileSuccess == GL_FALSE) {
        GLchar messages[256];
        glGetShaderInfoLog(shaderHandle, sizeof(messages), 0, &messages[0]);
        std::cout << messages;
        exit(1);
    }

 

3.5創建渲染源程序

3.5.1創建一個空源程序

     GLuint programHandle = glCreateProgram();//創建一個渲染程序

3.5.2向源程序中添加着色器
    glAttachShader(programHandle, shaderHandle);//將着色器添加到程序中

3.5.3鏈接源程序
    glLinkProgram(programHandle);//你可能添加了多個着色器,鏈接程序

3.5.4檢查鏈接程序是否成功
    GLint linkSuccess;
    glGetProgramiv(programHandle, GL_LINK_STATUS, &linkSuccess);//查看連接是否成功

//鏈接失敗記錄失敗信息

    if (linkSuccess == GL_FALSE) {
        GLchar message[256];
        glGetProgramInfoLog(programHandle, sizeof(message), 0, &message[0]);
        std::cout << message;
        exit(1);
    }

3.6頂點結構體

//此處定義了一個代表頂點的結構體,內部包含一個有兩個點(x,y)組成的頂點的位置信息,和一個四個值(r, g, b, a)表示的顏色信息

struct Vertex{
    float Position[2];
    float Color[4];
};
//創建頂點數組,里面有6個頂點信息
const Vertex vertices[] = {
    {{-0.5, -0.866}, {0.5, 1, 0.5, 1}},
    {{0.5, -0.866}, {0.2, 0.6, 0.5, 1}},
    {{0, 1}, {0.6, 0.1, 0.8, 1}},
    {{0.5, -0.866}, {0.5, 0.5, 0.5, 1}},
    {{1.5, -0.866}, {0.5, 0.5, 0.5, 1}},
    {{1, 0.4}, {0.5, 0.5, 0.5, 1}}
};

 

3.7着色器

3.7.1頂點着色器

#define STRINGIFY(A) #A

const char *SimpleVertexShader = STRINGIFY(
attribute vec4 Position;//位置,vec4說明有4個點組成,attribute表示屬性,由程序提供輸入值
attribute vec4 SourceColor;//源顏色,RGBA
varying vec4 DestinationColor;//目標顏色,輸出值,用來傳遞到片元着色器,vary表示可變傳出變量
uniform mat4 Projection;//投影矩陣,mat4表示一個4*4的矩陣,uniform表示統一的,不變的,每個頂點都是固定的這個值
uniform mat4 Modelview;//模型矩陣
void main(void){
    DestinationColor = SourceColor;//簡單的將源顏色賦給目標顏色
    gl_Position = Projection * Modelview * Position;//通過矩陣乘法獲得目標位置,gl_Position是OpenGL ES內定的值,必須指定
}
);

 

3.7.2片元着色器

const char *SimpleFragmentShader = STRINGIFY(
varying lowp vec4 DestinationColor;//由頂點着色器傳入,lowp表示低精度
void main(void){
    gl_FragColor = DestinationColor;//片元顏色,gl_FragColor也是OpenGL ES內定的,必須指定
}
);

 

3.8開始渲染

3.8.1填充(清理)屏幕

glClearColor(0.1f, 0.9f, 0.5f, 1);//指定填充屏幕的RGBA值
glClear(GL_COLOR_BUFFER_BIT);//指定要清除哪些緩沖區,GL_COLOR_BUFFER_BIT表示顏色緩沖區,GL_DEPTH_BUFFER_BIT表示深度緩沖區,GL_STENCIL_BUFFER_BIT表示模板緩沖區

 

3.8.2從着色器代碼中獲取屬性信息

    GLuint m_simpleProgram = programHandle;    

    GLuint positionSlot = glGetAttribLocation(m_simpleProgram, "Position");//從着色器源程序中的頂點着色器中獲取Position屬性
    GLuint colorSlot = glGetAttribLocation(m_simpleProgram, "SourceColor");//從着色器源程序中的頂點着色器中獲取SourceColor屬性

 

3.8.3開啟頂點屬性數組
    glEnableVertexAttribArray(positionSlot);
    glEnableVertexAttribArray(colorSlot);

 

3.8.4為着色器屬性賦值
    GLsizei stride = sizeof(Vertex);//單個頂點的數據長度
    const GLvoid *pCoords = &vertices[0].Position[0];//頂點數組中的位置數組首地址
    const GLvoid *pColors = &vertices[0].Color[0];/頂點數組中的顏色數組首地址
    glVertexAttribPointer(positionSlot, 2, GL_FLOAT, GL_FALSE, stride, pCoords);//為頂點着色器位置信息賦值,positionSlot表示頂點着色器位置屬性(即,Position);2表示每一個頂點信息由幾個值組成,這個值必須位1,2,3或4;GL_FLOAT表示頂點信息的數據類型;GL_FALSE表示不要將數據類型標准化(即fixed-point);stride表示數組中每個元素的長度;pCoords表示數組的首地址
    glVertexAttribPointer(colorSlot, 4, GL_FLOAT, GL_FALSE, stride, pColors);//同上

3.8.5渲染頂點
    GLsizei vertexCount = sizeof(vertices)/sizeof(Vertex);//頂點個數
    glDrawArrays(GL_TRIANGLES, 0, vertexCount);//將頂點數組使用三角形渲染,GL_TRIANGLES表示三角形, 0表示數組第一個值的位置,vertexCount表示數組長度

3.8.6渲染完畢,關閉頂點屬性數組
    glDisableVertexAttribArray(positionSlot);
    glDisableVertexAttribArray(colorSlot);

 

4.OpenGL 1.1和2.0在編程上的區別

4.1函數命名上的區別

1.1版API函數和宏末尾通常都為加上OES(即OpenglES的縮寫),2.0版本基本上都把這個后綴名給去掉了,如:

1.1API函數和宏:glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_renderbuffer);

2.0API函數和宏:glBindRenderbuffer(GL_RENDERBUFFER, m_renderbuffer);

 

4.2渲染方式不同

1.1版是基於不可編程管線,2.0版是基於可編程管線的,明顯的差別是1.1不支持着色器而2.0支持着色器,如下:

在1.1版將頂點渲染到屏幕上一般這樣寫:

    glMatrixMode(GL_PROJECTION);
    const float maxX = 2;
    const float maxY = 3;
    glOrthof(-maxX, maxX, -maxY, maxY, -1, 1);
    glMatrixMode(GL_MODELVIEW);

2.0版支持着色器,就不再這么渲染頂點了。將頂點屬性和變換方式全部放在頂點着色器和片元着色器中,然后程序中通過着色器來渲染

 

4.3編寫同樣的程序API不同

如,同樣是激活和關閉頂點數組,在1.1中是glEnableClientState(GL_VERTEX_ARRAY);和glDisableClientState(GL_VERTEX_ARRAY);

但在2.0中,就變成了:glEnableVertexAttribArray(*);和glDisableVertexAttribArray(*);

差別的來源就在於1.1不使用着色器,而2.0使用着色器。

 

4.4編程難易程度不同。

1.1是基於不可編程管線的,因此,管線的各個組件都是寫好的,我們僅需要調用即可。而2.0是基於可編程管線的,靈活性大大增加了,但是編寫的難度和復雜度也增加了,因為什么功能都得自己寫了。

 

5.着色器的使用流程

剛開始學習OpenGL ES2.0,對其着色器十分不感冒,什么是着色器,着色器該怎么使用,着色器包含哪些內容呢?

着色器就是一段包含着色信息的源代碼字符串。通常着色器分為頂點着色器(Vertex Shader)和片元着色器(Fragment Shader),兩個着色器分別寫在不同的文件中,文件沒有固定的后綴名,可以根據你自己的愛好寫,但是最好能區別文件中寫的是頂點着色器還是片元着色器,不然時間長了自己都不知道哪個文件中寫的是什么信息了。如你可以給你的頂點着色器后綴名命名為:vert, ver, v, vsh等,給你的片元着色器后綴名命名為:frag, fra, f, fsh等。

着色器源代碼和OpenGL源代碼不是一起編譯的,所以要特別強調我剛才說的“着色器是一段包含着色信息的源代碼字符串”。所以,OpenGL源代碼肯定是和工程一起編譯的,但是着色器源代碼是在運行期編譯的。你可能會問,着色器的源代碼是一個字符串怎么編譯呢?所以OpenGL ES提供了一套運行期動態編譯的流程:

(1)創建着色器:glCreateShader

(2)指定着色器源代碼字符串:glShaderSource

(3)編譯着色器:glCompileShader

(4)創建着色器可執行程序:glCompileShader

(5)向可執行程序中添加着色器:glAttachShader

(6)鏈接可執行程序:glLinkProgram


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM