色をつけるには、頂点シェーダにattribute変数を追加してプログラムから頂点ごとに色を渡すようにし、さらに頂点シェーダとフラグメントシェーダにvarying変数を追加して頂点シェーダからフラグメントシェーダに線形補間された色を渡します。
display program = do clear [ColorBuffer] currentProgram $= Just program positionLoc <- get $ attribLocation program "a_position" colorLoc <- get $ attribLocation program "a_color" positions <- newListArray (0, 5) ([0.0, 0.9, -0.9, -0.9, 0.9, -0.9] :: [GLfloat]) colors <- newListArray (0, 9) ([1, 0, 0, 0, 1, 0, 0, 0, 1] :: [GLfloat]) withStorableArray positions $ \positionsPtr -> withStorableArray colors $ \colorsPtr -> do vertexAttribPointer positionLoc $= (ToFloat, VertexArrayDescriptor 2 Float 0 positionsPtr) vertexAttribArray positionLoc $= Enabled vertexAttribPointer colorLoc $= (ToFloat, VertexArrayDescriptor 3 Float 0 colorsPtr) vertexAttribArray colorLoc $= Enabled drawArrays Triangles 0 3 flush vertexShaderSource = "attribute vec4 a_position; \ \attribute vec4 a_color; \ \varying vec4 v_color; \ \void main() { \ \ gl_Position = a_position; \ \ v_color = a_color; \ \}" fragmentShaderSource = "varying vec4 v_color; \ \void main() { \ \ gl_FragColor = v_color; \ \}"
属性は先のように二つの配列で渡すこともできますが、一つにまとめることもできます。この場合、VertexArrayDescriptorのStrideに頂点間のバイト数を指定する必要があります。
display program = do clear [ColorBuffer] currentProgram $= Just program attributes <- newListArray (0, 15) ([ 0.0, 0.9, 1.0, 0.0, 0.0, -0.9, -0.9, 0.0, 1.0, 0.0, 0.9, -0.9, 0.0, 0.0, 1.0] :: [GLfloat]) positionLoc <- get $ attribLocation program "a_position" colorLoc <- get $ attribLocation program "a_color" withStorableArray attributes $ \ptr -> do vertexAttribPointer positionLoc $= (ToFloat, VertexArrayDescriptor 2 Float (toEnum (5*sizeOf(0 :: GLfloat))) ptr) vertexAttribArray positionLoc $= Enabled vertexAttribPointer colorLoc $= (ToFloat, VertexArrayDescriptor 3 Float (toEnum (5*sizeOf(0 :: GLfloat))) (plusPtr ptr (toEnum (2*sizeOf(0 :: GLfloat))))) vertexAttribArray colorLoc $= Enabled drawArrays Triangles 0 3 flush