EGE专栏:EGE专栏
上一篇:EGE基本介绍(5):窗口操作简单
下一篇:EGE基础介绍(7):组合图形
一、EGE提供的基本图形
EGE绘制图形相关库函数文档 https://xege.org/manual/api/draw/index.htm
??EGE包括下图所示的一些基本图形,包括 和 。

图中列出了图形对应的函数,其中函数分为和。
- 可以画出更高质量的图形,可以反过来,减少图形边缘的锯齿感,图形使用 ,透明度可以设置。
- 会忽略颜色透明度,只能使用,没有抗锯齿功能,图形边缘有明显的锯齿。
??透明度和反走样也会带来更大的计算成本,同时带来更美观的图形。对于相同大小的图形,高级绘图函数所需的时间可能是普通绘图函数的1~三倍。一般绘图时间小,影响小,不会降低帧率。如果是极其复杂的界面绘图,可能会有一些影响。
??通常,还是,为了获得高质量的图形。现在的图形界面基本都是反走样的。
二、 绘制基本图形
1. 设置图形样式
??绘图前需要设置、、线宽、线型等相关设置,因为这些设置只对后续的图形绘制有效。如果先绘制图形,然后设置样式,已绘制的图形不会改变样式。
1.1 设置颜色
??可分别通过 、 和 来设置、和。
?? 在绘图之前,如果您不确定以前的颜色,您可以在此时设置颜色。设置后,当前的颜色设置已经明确。如果后面的连续绘图是相同的颜色,则无需设置。
setbkcolor(WHITE); //设置背景色 setcolor(EGERGB(0x30, 0x80, 0xFF); //设置前景色 setfillcolor(EGEARGB(0x80, 0xB0, 0xB0, 0x20)); //设置填充颜色
#include <graphics.h> int main() {
initgraph(600, 600, INIT_RENDERMANUAL); setbkcolor(EGERGB(0xFF, 0xFF, 0xFF)); ///设置背景色为纯白色 ege_enable_aa(true); //打开抗锯齿 //填充椭圆
setfillcolor(EGEACOLOR(0xA0, BLUE));
ege_fillellipse(200, 100, 200, 200);
//填充矩形
setfillcolor(EGEARGB(0xFF, 0xFF, 0x20, 0xA0));
ege_fillrect(100, 200, 400, 200);
//直线
setcolor(EGEACOLOR(0xFF, RED));
ege_line(50, 50, 500, 500);
//多边形顶点数和顶点坐标
int numPoints = 3;
ege_point polyPoints[3] = {
{
560, 460}, {
560, 100}, {
100, 460} };
//填充多边形
setfillcolor(EGEARGB(0x50, 0x00, 0x20, 0xFF));
ege_fillpoly(numPoints, polyPoints);
getch();
closegraph();
return 0;
}
1.2 设置线宽
调用 可以设置线条宽度。(EGE19.01及之前的版本需要在setlinewidth()之后调用一次setcolor()才会生效)
void setlinewidth(float width, PIMAGE pimg = NULL);// 设置当前线宽
#include <graphics.h>
int main()
{
initgraph(600, 600, INIT_RENDERMANUAL);
setbkcolor(EGERGB(0xFF, 0xFF, 0xFF)); //设置背景色为纯白
ege_enable_aa(true); //开启抗锯齿
setcolor(EGEACOLOR(0xFF, BLACK)); //设置线条颜色
//绘制线宽为1的直线
setlinewidth(1);
ege_line(20, 20, 300, 200);
//绘制线宽为2的直线
setlinewidth(2);
ege_line(200, 300, 400, 40);
//绘制线宽为3的直线
setlinewidth(3);
ege_line(40, 400, 500, 400);
//绘制线宽为4的直线
setlinewidth(4);
ege_line(300, 300, 400, 300);
getch();
closegraph();
return 0;
}
2. 普通绘图函数与高级绘图函数
就是,。这样绘制出来的图形都是不透明的,并且图形边缘有明显的锯齿感,图形很不美观。 在绘图时会根据与,可以有透明效果。并且可以开启抗锯齿,边缘变得平滑,绘图效果较好。
2.1 普通绘图函数的使用
详细内容请阅读: EGE基础:基础绘图篇 EGE基础:光栅操作篇
普通绘图函数在使用前,需要设置好相应的填充颜色,线条颜色等等。即使不设置,也可以画出图形,只是图形颜色可能不符合。此外,还可以设置线宽等,还有光栅操作码等等设置。
2.1.1 普通绘图函数示例:色光三原色图
色光三原色是红绿蓝三种色光,其余色光都是这三种色光按不同的比例线性叠加而成。 发光的物体所发出的光的颜色, 是将所有颜色光进行叠加,称为 。而屏幕也是发光物体,所以屏幕每一个像素的颜色,是红绿蓝三个分量的简单线性叠加。 如: # F F 0000 + # 00 F F 00 = # F F F F 00 \text{如:}\mathrm{\#FF0000+\#00FF00=\#FFFF00} 如:#FF0000+#00FF00=#FFFF00 如果以原来的设置来进行绘图,那么会以覆盖的方式进行,是得不到混合的效果的,所以应该先用 把绘图时像素的位操作改为,而不是直接赋值,这样就能使颜色叠加。 通过计算三个色圆中心位置,调用 绘图即可。
#include <graphics.h>
#include <cmath>
double angleToRadian(double angle)
{
return angle * PI / 180.0;
}
int main() {
//定义窗口大小,以及窗口中心
int winWidth = 640, winHeight = 640;
int xCenter = winWidth / 2, yCenter = winHeight / 2;
initgraph(winWidth, winHeight, INIT_RENDERMANUAL);
setbkcolor(EGERGB(0x00, 0x00, 0x00));
setwritemode(R2_MERGEPEN); //光栅操作码:使用位或的方式计算目标像素
//定义红绿蓝三原色
color_t colors[3] = {
EGERGB(0xFF, 0x00, 0x00), //红
EGERGB(0x00, 0xFF, 0x00), //绿
EGERGB(0x00, 0x00, 0xff), //蓝
};
float circleRadius = 180;
float rotationRadius = circleRadius * sqrt(3) / 3;
float startAngle = -90;
for (int i = 0; i < 3; i++) {
float angle = startAngle - i * 360.0 / 3; //计算圆心角度, 因为y轴向下,逆时针是角度减小
float radian = angleToRadian(angle); //计算弧度
//计算圆中心坐标: x1 = x0 + r * cos(radian), y1 = y0 + r * sin(radian)
float cx = xCenter + rotationRadius * cos(radian);
float cy = yCenter + rotationRadius * sin(radian);
//设置边框和填充颜色
setcolor(colors[i]);
setfillcolor(colors[i]);
fillellipse(cx, cy, circleRadius, circleRadius);
}
getch();
closegraph();
return 0;
}
2.1.2 普通绘图函数示例:色料三原色图
一般用于颜料,印刷品等,也叫印刷三原色(CMY),分别是、 和 三种颜色。 颜料本身不发出颜色光,所呈现的颜色是光源中的颜色光被颜料吸收后所剩余的部分,是。反光物体表现出来的颜色,与照射光的颜色和所吸收的光的颜色有关。 如黄颜料是颜料吸收了白光中的蓝色光,剩余的出来,看到的就是黄色。所以如果色料三种颜色的颜料混合,那么三种色光都会被吸收,显现出来的就是黑色。 所以色料三原色的绘图是将相应的色光除去,因此只要先对应颜色值,再和底色即可。 通过将色光三原色示例代码中的光栅操作码改为,背景色改为纯白,再调整一下角度,即可得到色料三原色代码。
#include <graphics.h>
#include <cmath>
double angleToRadian(double angle)
{
return angle * PI / 180.0;
}
int main() {
//定义窗口大小,以及窗口中心
int winWidth = 640, winHeight = 640;
int xCenter = winWidth / 2, yCenter = winHeight / 2;
initgraph(winWidth, winHeight, INIT_RENDERMANUAL);
setbkcolor(EGERGB(0xFF, 0xFF, 0xFF));
//光栅操作码:使用先取反再位与的方式计算目标像素
setwritemode(R2_MASKNOTPEN);
//定义红绿蓝三原色
color_t colors[3] = {
EGERGB(0xFF, 0x00, 0x00), //红
EGERGB(0x00, 0xFF, 0x00), //绿
EGERGB(0x00, 0x00, 0xff), //蓝
};
float circleRadius = 180;
float rotationRadius = circleRadius * sqrt(3) / 3;
float startAngle = 90;
for (int i = 0; i < 3; i++) {
float angle = startAngle - i * 360.0 / 3; //计算圆心角度, 因为y轴向下,逆时针是角度减小
float radian = angleToRadian(angle); //计算弧度
//计算圆中心坐标: x1 = x0 + r * cos(radian), y1 = y0 + r * sin(radian)
float cx = xCenter + rotationRadius * cos(radian);
float cy = yCenter + rotationRadius * sin(radian);
//设置边框和填充颜色
setcolor(colors[i]);
setfillcolor(colors[i]);
fillellipse(cx, cy, circleRadius, circleRadius);
}
getch();
closegraph();
return 0;
}
2.1.3 普通绘图函数示例:Poly Code图标
图标由同一个平行四边形以60°为旋转角旋转6次而成。我们可以以中心为原点建立坐标系,然后计算出每个平行四边形的顶点坐标。
运行结果如图:
#include <graphics.h> #include <cmath> //角度转弧度 double angleToRadian(double angle) { return angle * PI / 180.0; } //自定义一个Point类,方便运算 typedef struct Point { float x, y; Point(float x = 0.0f, float y = 0.0f) :x(x), y(y) { } Point operator+ (const Point& point) { return Point(x + point.x, y + point.y); } Point operator- (const Point& point) { return Point(x - point.x, y - point.y); } Point operator* (const float factor) { return Point(x * factor, y * factor); } Point operator/ (const float div) { return Point(x / div, y / div); } }; int main() { //定义窗口大小,以及窗口中心 int winWidth = 640, winHeight = 640; int xCenter = winWidth / 2, yCenter = winHeight / 2; initgraph(winWidth, winHeight, INIT_RENDERMANUAL); setbkcolor(EGERGB(0xFF, 0xFF, 0xFF)); //设置边框线条不绘制 setlinestyle(NULL_LINE); //暗色圆底 float circleRadius = 180; setfillcolor(EGERGB(70, 60, 60)); fillellipse(xCenter, yCenter, circleRadius, circleRadius); double lenOfSide = circleRadius / 2.0; //六边形边长取底圆半径的一半 float rotationAngle = 60; double offsetAngle = rotationAngle / 2; int numPoints = 4; int pointsCoord[4 * 2]; color_t colors[6] = { HSVtoRGB(0, 0.84, 0.92), HSVtoRGB(35, 0.87, 0.96), HSVtoRGB(55, 1.0, 1.0), HSVtoRGB(100, 0.62, 0.74), HSVtoRGB(210, 0.65, 0.75), HSVtoRGB(300, 0.48, 0.62), }; Point p[5]; //计算第一次需要利用的到的历史坐标点 p[0] = Point(lenOfSide * cos(angleToRadian(-rotationAngle - offsetAngle)), lenOfSide * sin(angleToRadian(-rotationAngle - offsetAngle))); p[4] = Point(lenOfSide * cos(angleToRadian(-rotationAngle + offsetAngle)), lenOfSide * sin(angleToRadian(-rotationAngle + offsetAngle))); p[3] = p[0] + (p[4] - p[0]) * 4.0f / 3.0f; for (int i = 0; i < 6; i++) { double angle = i * rotationAngle; //直接取上次计算好的坐标。(利用到上次的P0,P3,P4) Point lastP4 = p[4]; p[4] = lastP4 - p[0]; p[0] = lastP4; p[1] = p[3]; //利用现有点计算P2, P3新坐标 p[2] = p[1] + (p[4] - p[0]) * 4.0 / 3; p[3] = p[2] + (p[0] - p[1]); //转换到窗口坐标系 for (int i = 0; i < numPoints; i++) { pointsCoord[2 * i] = roundf(xCenter + p[i].x); pointsCoord[2 * i + 1] = roundf(yCenter - p[i].y); } //设置颜色 setfillcolor(colors[i]); fillpoly(numPoints, pointsCoord); } //恢复线条绘制 setlinestyle(SOLID_LINE); getch(); closegraph(); return 0; }
2.2 高级绘图函数的使用
详细内容请阅读: EGE基础:高级绘图篇
是一系列命名带有 前缀的绘图函数。 普通绘图函数的使用很简单,传入正确的参数调用即可。而高级绘图函数有抗锯齿的功能,这个是默认不开启的,需要进行设置。
流程如下图所示,相比普通绘图函数仅仅多了一个抗锯齿的设置,并且抗锯齿设置并不是必需的,可以不设置,这时就如果普通绘图函数一样的使用方法。
但是有一个需要注意, 使用前确保颜色的透明度不为0。
由于EGE19.01及之前的版本,将定义为,所以直接设置为RGB颜色时,高级绘图函数绘制出的图形是看不到的,需要使用 为其设置透明度。或者使用 直接定义ARGB颜色。
setfillcolor(EGEACOLOR(0xFF, BLUE)); //设置ARGB填充颜色,利用EGEACOLOR设置RGB颜色透明度
setcolor(EGEARGB(0x80, 0xFF, 0x80, 0xA0)); //设置ARGB前景色