天天看點

IOS OpenGLES2.0 入門03 繪制彩色三角形

接上一篇

上一篇的三角形是紅色, 紅色的代碼是固定死在代碼裡面的, 如果要藍色, 白色, 或者是彩色的, 這樣就行不通了

那麼如何繪制一個彩色的三角形呢

繪制紅色的三角形的Fragment Shader的代碼是這樣的

void main(void) {
    gl_FragColor = vec4(1, 0, 0, 1);
}           

之前說了gl_FragColor是該頂點的輸出顔色, 正常我們不會把代碼寫死, 而應該是傳遞一個變量給它, 想要什麼顔色可以通過這個變量來改.

Vertex Shader可以給Fragment Shader傳遞參數, 使用的就是varying關鍵字

我們将之前的Vertex Shader和Fragment Shader源碼改動一下

Vertex Shader

attribute vec4 position;
    attribute vec4 inputColor;
    varying vec4 fragmentColor;

    void main(void) {
        fragmentColor = inputColor;
        gl_Position = position;
    }           

Fragment Shader

varying lowp vec4 fragmentColor;
    void main(void) {
        gl_FragColor = fragmentColor;
    }           

這樣我們就要傳遞兩個參數給Vertex Shader, 一個position, 一個inputColor.

我們定義Color的資料

static int colorCount = 3;
static GLfloat colorData[] = {
    //RGB格式
    1,  0,  0,
    0,  1,  0,
    0,  0,  1
};           

然後使用跟頂點資料一樣的方式将資料傳遞給OpenGL

_positionPtr = glGetAttribLocation(_program, "position");
_colorPtr = glGetAttribLocation(_program, "inputColor");           
glGenBuffers(1, &_colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _colorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(colorData), colorData, GL_STATIC_DRAW);           

因為顔色和頂點資料都是使用GL_ARRAY_BUFFER這個标志, 是以我們将資料綁定給OpenGL并且告訴它如何使用的時候, 必須馬上将資料繪制出來, 不然會被後面的資料覆寫, 或者再重新綁定一次

glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);

後面的glDrawArrays都是針對_vertexBuffer來操作.

然後在

glBindBuffer(GL_ARRAY_BUFFER, _colorBuffer);

後面的glDrawArrays都是針對_colorBuffer來操作.

這邊不在多次綁定, 直接draw出來

是以建立和繪制頂點和顔色的函數改成這樣

- (void) setupVertexAndColorData {
    //頂點資料
    glGenBuffers(1, &_vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);

    glEnableVertexAttribArray(_positionPtr);
    glVertexAttribPointer(_positionPtr, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, NULL);
    glDrawArrays(GL_TRIANGLES, 0, vertexCount);

    //顔色資料
    glGenBuffers(1, &_colorBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _colorBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(colorData), colorData, GL_STATIC_DRAW);

    glEnableVertexAttribArray(_colorPtr);
    glVertexAttribPointer(_colorPtr, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, NULL);
    glDrawArrays(GL_TRIANGLES, 0, colorCount);
}           

其他的還是給上一篇一樣

修改完後的代碼