# 一、怎么绘制曲线

``````glDrawArrays(GL_POINTS, 0, self.vertexCount);

``````attribute vec4 Position;

uniform float Size;

void main (void) {
gl_Position = Position;
gl_PointSize = Size;
}

``````precision highp float;

uniform float R;
uniform float G;
uniform float B;
uniform float A;

uniform sampler2D Texture;

void main (void) {
vec4 mask = texture2D(Texture, vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y));
gl_FragColor = A * vec4(R, G, B, 1.0) * mask;
}

``````- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesMoved:touches withEvent:event];

}

# 三、怎么使曲线变平滑

1. 不同贝塞尔曲线的长度不一样，使用同一个 `n` 值，算出来的点的疏密程度肯定不同。
2. 由于贝塞尔曲线随着 `t` 增长，曲线长度的增长并不是线性的。按照我们上面的算法，最终会得到的结果是 两头比较稀疏，中间比较密集

# 四、怎么生成均匀的点序列

``````+ (NSArray <NSValue *>*)pointsWithFrom:(CGPoint)from
to:(CGPoint)to
control:(CGPoint)control
pointSize:(CGFloat)pointSize;

# 五、绘画板功能实现

1、颜色混合

``````glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

2、笔触调整

3、橡皮擦

`GLPaintView` 在初始化的时候，需要传入一个背景色参数，当用户切换到橡皮擦功能的时候，内部只是单纯地将画笔的颜色切换成背景色，于是就产生了橡皮擦的效果。

4、撤销重做

``````@interface MFPaintModel : NSObject

/// 笔刷尺寸
@property (nonatomic, assign) CGFloat brushSize;
/// 笔刷颜色
@property (nonatomic, strong) UIColor *brushColor;
/// 笔刷模式
@property (nonatomic, assign) GLPaintViewBrushMode brushMode;
/// 笔触纹理图片文件名
@property (nonatomic, copy) NSString *brushImageName;
/// 点序列
@property (nonatomic, copy) NSArray<NSValue *> *points;

@end

``````- (void)undo {
if ([self.operationStack isEmpty]) {
return;
}
MFPaintModel *model = self.operationStack.topModel;
[self.operationStack popModel];
[self.undoOperationStack pushModel:model];

[self reDraw];
}

- (void)redo {
if ([self.undoOperationStack isEmpty]) {
return;
}
MFPaintModel *model = self.undoOperationStack.topModel;
[self.undoOperationStack popModel];
[self.operationStack pushModel:model];

[self drawModel:model];
}

iOS