光栅渲染器(二)画线

这篇着重光栅化2D直线的算法实现

一、数据结构设置

//************************基本数据结构*******************
typedef struct { float x, y; } vector_t;
typedef vector_t point_t;//顶点

typedef struct { float r, g, b,a; } color_t;//颜色

目前还是2d,也不需要3d变换,暂时只需要x,y2个坐标数据

二、DDA画线算法

void DrawLineDDA2d(point_t v1, point_t v2,color_t c)//DDA画线算法
{

    glColor4d(c.r, c.g, c.b,c.a);
    float x1 = v1.x;
    float y1 = v1.y;
    float x2 =v2.x;
    float y2 = v2.y;
    float length = __max(abs(x1 - x2), abs(y1 - y2));
    float dx = (x2 - x1) / length;
    float dy = (y2 - y1) / length;
    float x = x1 + 0.5;
    float y = y1 + 0.5;
    int i = 0;
    while (i <= length)
    {
        glVertex2i((int)x, (int)y);
        x += dx;
        y += dy;
        i++;
    }

}

此算法参考《计算机图形学的算法基础》
这里写图片描述
利用这里写图片描述公式完成绘制

三、中点画线算法

void DrawLineMid(point_t v1, point_t v2,color_t c)//中点画线算法
{

    glColor4d(c.r, c.g, c.b, c.a);
    float x1 = v1.x;
    float y1 = v1.y;
    float x2 = v2.x;
    float y2 = v2.y;
    float dx = x2 - x1;
    float dy = y2 - y1;
    float d = dy - dx;
    int x = x1+0.5;
    int y = y1+0.5;
    glVertex2i((int)x1, (int)y1);
    while (x < x2)
    {
        if (d >= 0)
        {
            glVertex2i(x++, y);
            d -= dy;
        }
        else if (d < 0)
        {
            glVertex2i(x++, y++);
            d += dy - dx;
        }
    }
}

这个算法仅限第一象限
希望扩展到全坐标系,参考无幻博客

http://blog.youkuaiyun.com/akof1314/article/details/5447652

四、Bresenham算法

void DrawLineBre(point_t v1, point_t v2, color_t c)//Bresenham算法
{
    glColor4d(c.r, c.g, c.b, c.a);
    float x1 = v1.x;
    float y1 = v1.y;
    float x2 = v2.x;
    float y2 = v2.y;
    int x = x1;
    int y = y1;
    float dx =abs(x1-x2);
    float dy = abs(y2 - y1);
    int s1 = Sgn(x2 - x1);
    int s2 = Sgn(y2 - y1);
    bool IntChange = false;
    if (dy > dx)
    {
        swap(dy, dx);
        IntChange = true;
    }
    float e = 2 * dy - dx;
    for (int i = 0; i < dx; i++)
    {
        glVertex2i(x, y);
        if(e>0)
        {
            if (IntChange)x += s1;
            else x += s2;
            e =e- 2*dx;
        }
        if (IntChange) y += s2;
        else y += s1;
        e += 2 * dy;
    }
}

五、测试画线案例

void myDisplay(void)
{
    glClear(GL_COLOR_BUFFER_BIT);     // 清屏幕 
    glPointSize(1);
    glBegin(GL_POINTS);
    point_t v1{ 10,15 };
    point_t v2{ 400,405 };
    point_t v3{ 100,405 };
    color_t c{ 1.0,1.0,0,1.0 };//黄色
    DrawLineBre(v1,v2,c);
    glEnd();
    glFlush();                         // 将所有输出到显示屏上 
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值