在指定位置绘制像素点

该系列文章并非严谨的的计算机图形学教程,仅作为学习记录。

在C++的学习过程中,我们认识了转义字符,如\n,\t等。通过这些转义字符,我们可以控制输出的格式。为了实现彩色绘制,我们将使用另一种转义序列:ANSI转义序列。

ANSI转义序列

ANSI转义序列通常以ESC(ASCII码为27,对应八进制为033, 16进制为1b)作为开头,后面跟随左方括号[与一系列参数,结尾的字母代表不同的命令。

参数间以分号分隔,例如:

1
2
3
4
5
6
\033[{y};{x}H   // 将光标移动到(x,y)位置
\033[2J // 清屏
\033[?25l // 隐藏光标
\033[3J //清除滚动缓冲区
\033[38;2;{r};{g};{b}m // 设置前景色(rgb色彩)
\033[48;2;{r};{g};{b}m // 设置背景色(rgb色彩)

更多信息可参考:ANSI 转义序列(ANSI Escape Sequences)

旧版本终端(如cmd)不完全支持ANSI转义序列,但是在更新后的Windows系统中,我们可以通过开启虚拟终端(Windows Terminal)来实现对ANSI转义序列的支持:

1
2
3
4
5
6
7
// 不理解这段代码并不会影响后续内容,故不再对Windows API进行详细介绍,后文也几乎不会涉及
// #include <Windows.h>
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode;
GetConsoleMode(hOut, &mode);
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
SetConsoleMode(hOut, mode);

绘制像素点

现在我们可以使用”\033[{y};{x}H”与”\033[48;2;{r};{g};{b}m”来绘制像素点了。

例如:

1
2
// 下面的代码将(2,3)处的背景设置为红色
std::cout << "\033[3;2H" << "\033[48;2;255;0;0m";

这时你会发现(2,3)之后的所有字符的背景都变成了红色。这是因为我们没有重置颜色。可以通过”\033[m”来重置颜色。

更改后:

1
std::cout << "\033[3;2H" << "\033[48;2;255;0;0m "<<"\033[m"; // 输出一个空格后再重置颜色

完整代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<iostream>
#include<Windows.h>

int main() {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode;
GetConsoleMode(hOut, &mode);
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
SetConsoleMode(hOut, mode);

std::cout << "\033[3;2H" << "\033[48;2;255;0;0m " << "\033[m";
return 0;
}