Console Project/2. 출력 버퍼
문자 출력이 가능한 콘솔 창에서 2D 이미지를 출력하기 위해서는 이미지를 ASCII Art로 변환하여 출력해야 한다. 하지만 이미지의 픽셀 개수 만큼의 길이를 가진 문자열을 printf 혹은 std::cout 등으로 출력하는 방식은 대체로 느리다. 여러 이미지를 하나하나 화면에 그리다 보면 그려지는 순서가 보일 지경이 될 것이다.
이를 개선하기 위해 출력 버퍼에 여러장의 이미지를 그린 후, 버퍼에 바뀜이 있을 때 화면을 갱신(출력)하면 보다 깔끔하게 출력이 가능할 것이다.
출력 버퍼
ASCII Art는 텍스트로 이루어져 있으므로 char 배열로 buffer를 만든다.
int width = 200;
int height = 200;
char *buffer = new char[width * height];
// clear
for (int i = 0; i < width * height; i++) {
buffer[i] = ' ';
}
// output to console
gotoXY(0, 0);
for (int i = 0; i < height; i++) {
char line[width + 1];
for (int j = 0; j < width; j++) {
line[j] = buffer[i * width + j];
}
line[width] = '/0'; // end of string
std::cout << line << std::endl;
}
이제 원하는 위치에 이미지를 버퍼에 그려 화면에 출력 할 수 있다. 아래는 이미지를 버퍼에 쓰는 작업을 하는 코드이다.
int posX = 10;
int posY = 25;
int imageWidth = image.width;
int imageHeight = image.height;
char* asciiArt = imageToAscii(image);
// draw image to buffer
for (int y = 0; y < iamgeHeight; y++) {
for (int x = 0; x < imageWidth; x++) {
// 이미지 픽셀에 대한 버퍼의 위치를 구한다.
int bufferX = x + posX;
int bufferY = y + posY;
// 버퍼 밖으로 그리게 될 경우는 무시한다.
if (bufferX < 0 || bufferX >= bufferWidth || bufferY < 0 || bufferY >= bufferHeight) {
continue;
}
// 이미지의 픽셀 위치와 버퍼의 픽셀 위치를 구한다.
int imageIndex = y * imageWidth + x;
int bufferIndex = bufferY * bufferWidth + bufferX;
// 이미지의 픽셀을 버퍼의 픽셀에 대입한다.
buffer[bufferIndex] = asciiArt[imageIndex];
}
}
// Output to Console
...
WriteConsoleOutput
위의 코드로 이미지를 그릴 경우 초당 몇 ~ 십몇 프레임이상 그리지 못할 것이다. 이때 빠르게 콘솔에 출력하는 함수가 WriteConsoleOutput이다. 자세한 내용은 링크 참조.
2019/12/09 - [C++] - WriteConsoleOutput - Console 화면에 빠르게 출력하는 함수.
WriteConsoleOutput를 사용하려면 CHAR_INFO 배열이 필요한데 버퍼를 아예 CHAR_INFO 배열로 사용할 수 있다.
...
CHAR_INFO* buffer = new CHAR_INFO[width * height];
// clear
for (int i = 0; i < width * height; i++) {
buffer[i].Char.AsciiChar = ' ';
buffer[i].Attribute = 7; // white
}
// output to console
COORD pos = { 0, 0 }, size = { width, height };
SMALL_RECT rect = { 0, 0, width, height };
WriteConsoleOutput(GetStdHandle(STD_OUTPUT_HANDLE), buffer, size, pos, &rect);
클래스
기능을 클래스화하여 사용한다. 자세한 내용은 링크.
https://github.com/wakeup5/Console-Project/blob/master/Project/RenderBuffer.h
https://github.com/wakeup5/Console-Project/blob/master/Project/RenderBuffer.cpp
'C++' 카테고리의 다른 글
Console Project/4. GameLoop (0) | 2019.12.10 |
---|---|
Console Project/3. 이미지 (0) | 2019.12.10 |
Console Project/1. 화면 (0) | 2019.12.09 |
Console Project (0) | 2019.12.09 |
WriteConsoleOutput - Console 화면에 빠르게 출력하는 함수. (0) | 2019.12.09 |