#include // 引入 GLUT/OpenGL 头文件,用于创建窗口和绘图。 #include // 引入输入输出流库,用于在控制台输出点坐标。 #include // 引入通用工具库,用于 abs 函数。 const int WIDTH = 640; // 定义窗口宽度。 const int HEIGHT = 480; // 定义窗口高度。 void drawPoint(int x, int y) { // 定义绘制单个像素点的辅助函数。 glVertex2i(x, y); // 向 OpenGL 提交一个二维整数坐标点。 std::cout << x << ", " << y << std::endl; // 在控制台输出当前点坐标。 } // 绘制点函数结束。 void drawBresenhamLine(int x1, int y1, int x2, int y2) { // 定义 Bresenham 直线算法函数。 int dx = std::abs(x2 - x1); // 计算 x 方向距离的绝对值。 int dy = std::abs(y2 - y1); // 计算 y 方向距离的绝对值。 int sx = (x1 < x2) ? 1 : -1; // 判断 x 坐标每一步应该增加还是减少。 int sy = (y1 < y2) ? 1 : -1; // 判断 y 坐标每一步应该增加还是减少。 int err = dx - dy; // 初始化误差项。 int x = x1; // 初始化当前点的 x 坐标。 int y = y1; // 初始化当前点的 y 坐标。 glBegin(GL_POINTS); // 开始按点方式绘制直线。 while (true) { // 不断生成直线上的像素点,直到到达终点。 drawPoint(x, y); // 绘制当前点。 if (x == x2 && y == y2) { // 判断当前点是否已经到达终点。 break; // 到达终点后结束循环。 } // 终点判断结束。 int e2 = 2 * err; // 将误差项扩大 2 倍,便于和 dx、dy 比较。 if (e2 > -dy) { // 如果误差允许在 x 方向前进一步。 err -= dy; // 更新 x 方向移动后的误差项。 x += sx; // x 坐标向终点方向移动一步。 } // x 方向判断结束。 if (e2 < dx) { // 如果误差允许在 y 方向前进一步。 err += dx; // 更新 y 方向移动后的误差项。 y += sy; // y 坐标向终点方向移动一步。 } // y 方向判断结束。 } // 像素点生成循环结束。 glEnd(); // 结束点绘制。 } // Bresenham 直线算法函数结束。 void display() { // 定义显示回调函数。 glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓冲区。 glColor3f(0.0f, 0.0f, 1.0f); // 设置绘图颜色为蓝色。 glPointSize(3.0f); // 设置点的大小。 drawBresenhamLine(50, 50, 500, 300); // 调用 Bresenham 算法绘制一条直线。 glFlush(); // 强制执行所有 OpenGL 绘图命令。 } // 显示函数结束。 void init() { // 定义 OpenGL 初始化函数。 glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // 设置背景颜色为白色。 glMatrixMode(GL_PROJECTION); // 切换到投影矩阵模式。 glLoadIdentity(); // 将当前投影矩阵重置为单位矩阵。 gluOrtho2D(0.0, WIDTH, 0.0, HEIGHT); // 设置二维正交投影范围。 } int main(int argc, char** argv) { // 程序入口函数。 glutInit(&argc, argv); // 初始化 GLUT。 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // 设置显示模式为单缓冲和 RGB。 glutInitWindowSize(WIDTH, HEIGHT); // 设置窗口大小。 glutInitWindowPosition(100, 100); // 设置窗口初始位置。 glutCreateWindow("Bresenham"); // 创建窗口并设置标题。 init(); // 调用初始化函数。 glutDisplayFunc(display); // 注册显示回调函数。 glutMainLoop(); // 进入 GLUT 事件循环。 return 0; }