接上一篇
上一篇的三角形是紅色, 紅色的代碼是固定死在代碼裡面的, 如果要藍色, 白色, 或者是彩色的, 這樣就行不通了
那麼如何繪制一個彩色的三角形呢
繪制紅色的三角形的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);
}
其他的還是給上一篇一樣
修改完後的代碼