glBegin(GL_LINES); //这个是用来显示要输出的图元的类型
glVertex2i(10,20);
glVertex2i(10,40);
glVertex2i(20,20);
glVertex2i(20,40);
glVertex2i(30,20);
glEnd();
GL_LINES 模式
2个 2个成一条线 线线之间是没有关系的 如果是奇数 最后一个点将不被绘制 如图1
GL_LINE_STRIP 模式
这个是从开始点一个点连接每一个点 最后一个点不跟第一个点连接 如图2
GL_LINE_LOOP 模式
这个是开始点连接每一个点 最后一个点连接第一个点 如图3
那么它是怎么画的呢
屏幕是由像素点构成 他是没有浮点数的 所以绘图时候会受到像素间距限制
在低的分辨率下你会看到明显的抗锯齿效果
现在熟悉下直线方程 y = m * x + b m:是斜率 b:是在Y轴上的截距
画线有2个点 p1(x1,y1) p2(x2,y2)
m = (y2 - y1)/(x2 - x1)这样就可以求的斜率
斜率你知道之后 就可以的 x1 - x2 之间所有点对应的 Y值
通过x 取得y : y = m* x;
通过y 取得x : x = y / m
为什么要写这2个呢?
因为|m| < 1 说明 线在水平上有点偏 所以求Y 才用 y = m* x;
|m| > 1 说明 线很斜他比较跟Y轴靠近 所以求X 采用 x = y / m
为什么要用2个不同的呢
因为屏幕绘图收到像素的间距的限制 所以我们会采用最靠近像素的点为
这个线的点 那么比如当斜率很大 我们才用y = m* x;
x会单位递增 m 值是比较大的 那么Y 相对的值是不是比较大 那么这像素点看起来就不光滑
如果采用x = y / m 那么 y单位递增 m值是大的 对应的x值比较小 那么就比较好了
知道怎么绘制2个点之间的值之后我们来看看他用的算法
DDA算法 是一种线段扫描转换算法 基于 y = m* x; x = y / m 计算对应的 X Y 值
在一个坐标轴上以单位间隔对线段取样(x++ 这样的 X是整形哦屏幕坐标都是整形) 从而确定另一个
坐标轴上最靠近线段对应的整数值
也就是 当正斜率 m <= 1 我们就要从用y = m* x
y值 = y的上一个值 + m (为什么加上m呢 y=mx 这个东西因为是x是1 所以Y 每次递增 m)
当正斜率 m > 1 我们就要从用x = y / m
x值 = x的上一个值 + (1/m) (x = y / m 这个东西因为是y是1 所以X 每次递增 1/m)
那负的斜率了一样的主要是用哪一个方程 y = m* x; x = y / m 当斜率绝对值小于1 说明比较靠近X轴就用y = m* x
y值 = y的上一个值 + m 来求值 m 是负的他会自己减
DDA算法函数:
//这个是为了计算偏差 看看a 向哪一个值靠近
inline int round(const float a)
{
return int(a + 0.5);
}
void lineDDA(int x0,int y0,int xEnd,int yEnd )
{
int dx = xEnd - x0;
int dy = yEnd - y0;
int steps , k;
float xIncrement,yIncrement,x = x0, y = y0;
if (fabs((float)dx) > fabs((float)dy))//取绝对值
{
steps = fabs((float)dx);
}
else
{
steps = fabs((float)dy);
}
//假设 X比较大 也就是说斜率小于 1 xIncrement = 1 yIncrement = m = (yEnd - y0)/(xEnd - x0)
// X比较小 也就是说斜率大于 1 xIncrement = (xEnd - x0)/(xEnd - x0) = 1/m
xIncrement = float(dx)/float(steps);
yIncrement = float(dy)/float(steps);
//setPixed(round(x),round(y));
for (int i = 0; i < steps; i++)
{
x += xIncrement;
y += yIncrement;
//setPixed(round(x),round(y));
}
}