windows控制台2D引擎原理解析

如果想要在windows控制台上制作一款软件,我们通常都想到用OpenGL或者
Qt 等等一些图形库新开窗口来导入图片。而提到windows的控制台窗口我们通常都是用来处理一些字符操作,而不是图形化。
然而其实控制台也可以构建2D引擎导入图片(虽然画质很渣)。
下面介绍如何从零构建一个winsdows控制台2D引擎。

首先将控制台的字符转化为像素点

第一步将控制台字符变小

我知道的将字符块变小的方法有两种

手动右键点击控制台窗口

控制台窗口
遗憾的是这样调节字符,最小只能将字符调整到3个屏幕像素宽和7个屏幕像素高,并且手动调节非常的麻烦

代码调节

void SetCellSize(short length, short width, short thick)	//thick range from 100~1000, 400 is normal while >400 is bold
{
	CONSOLE_FONT_INFOEX fontInfo = { 0 };
	GetCurrentConsoleFontEx(hout, FALSE, &fontInfo);
	fontInfo.cbSize = sizeof(fontInfo);
	fontInfo.dwFontSize = { length,width };
	fontInfo.FontWeight = thick;//字体的重量
	SetCurrentConsoleFontEx(hout, FALSE, &fontInfo);
}

其中length是字符块的长度,width是字符块的宽度。
我们可以通过

SetCellSize(1,1, 400);

来将字符块的大小设置为1*1
在这里插入图片描述
就这样将字符变小的操作就完成了。

第二步我们需要为像素点添加颜色

一般来说我们通常使用RGB(256,256,256)来描述字符的颜色
但是控制台窗口是做不到这么多种颜色混合的。
我们可以通过一种很巧妙的方式来模拟出许多种颜色。

首先介绍两个概念:前景色和后景色

#define FOREGROUND_BLUE      0x0001 // text color contains blue.
#define FOREGROUND_GREEN     0x0002 // text color contains green.
#define FOREGROUND_RED       0x0004 // text color contains red.
#define FOREGROUND_INTENSITY 0x0008 // text color is intensified.
#define BACKGROUND_BLUE      0x0010 // background color contains blue.
#define BACKGROUND_GREEN     0x0020 // background color contains green.
#define BACKGROUND_RED       0x0040 // background color contains red.
#define BACKGROUND_INTENSITY 0x0080 // background color is intensified.

前景色:控制台字符的颜色

SetConsoleTextAttribute(hout, FOREGROUND_RED);
cout << "redfeeffeeeee" << endl;

在这里插入图片描述
后景色:字符的背景

SetConsoleTextAttribute(hout, BACKGROUND_RED);
cout << "redfeeffeeeee" << endl;

在这里插入图片描述
思路如下:利用前景色和后景色的混合模拟RGB
其实控制台一共有16种前景色,16种后景色

{ COLOR3(0,0,0),				NULL },
		{ COLOR3(0.5f,0,0),			FOREGROUND_RED },
		{ COLOR3(0,0.5f,0),			FOREGROUND_GREEN },
		{ COLOR3(0,0,0.5f),			FOREGROUND_BLUE },
		{ COLOR3(0.5f,0.5f,0),		FOREGROUND_RED | FOREGROUND_GREEN },
		{ COLOR3(0,0.5f,0.5f),		FOREGROUND_GREEN | FOREGROUND_BLUE },
		{ COLOR3(0.5f,0,0.5f),		FOREGROUND_RED | FOREGROUND_BLUE },
		{ COLOR3(0.5f,0.5f,0.5f),	FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE },
		{ COLOR3(1.0f,0,0),			FOREGROUND_RED | FOREGROUND_INTENSITY },
		{ COLOR3(0,1.0f,0),			FOREGROUND_GREEN | FOREGROUND_INTENSITY },
		{ COLOR3(0,0,1.0f),			FOREGROUND_BLUE | FOREGROUND_INTENSITY },
		{ COLOR3(0,1.0f,1.0f),		FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY },
		{ COLOR3(1.0f,0,1.0f),		FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY },
		{ COLOR3(1.0f,1.0f,0),		FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY },
		{ COLOR3(1.0f,1.0f,1.0f),	FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY },
{ COLOR3(0,0,0),				NULL },
		{ COLOR3(0.5f,0,0),			BACKGROUND_RED },
		{ COLOR3(0,0.5f,0),			BACKGROUND_GREEN },
		{ COLOR3(0,0,0.5f),			BACKGROUND_BLUE },
		{ COLOR3(0.5f,0.5f,0),		BACKGROUND_RED | BACKGROUND_GREEN },
		{ COLOR3(0,0.5f,0.5f),		BACKGROUND_GREEN | BACKGROUND_BLUE },
		{ COLOR3(0.5f,0,0.5f),		BACKGROUND_RED | BACKGROUND_BLUE },
		{ COLOR3(0.5f,0.5f,0.5f),	BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE },
		{ COLOR3(1.0f,0,0),			BACKGROUND_RED | BACKGROUND_INTENSITY },
		{ COLOR3(0,1.0f,0),			BACKGROUND_GREEN | BACKGROUND_INTENSITY },
		{ COLOR3(0,0,1.0f),			BACKGROUND_BLUE | BACKGROUND_INTENSITY },
		{ COLOR3(0,1.0f,1.0f),		BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY },
		{ COLOR3(1.0f,0,1.0f),		BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY },
		{ COLOR3(1.0f,1.0f,0),		BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY },
		{ COLOR3(1.0f,1.0f,1.0f),	BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY },

那么如何将前景色和后景色结合起来呢?
我们其实可以控制字符占整个像素块的大小。

char byte[] ={ ' ',	  '.' ,  '='  ,'&'  ,'#'	,'@'};

例如 ’ ’ 前景色占比为0,’@'前景色占比为1,我们可以通过控制字符的大小来控制前景色的比例。
就这样我们制作了一个 16 ∗ 16 ∗ 6 16*16*6 16166的一个控制台调色板了。
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值