使用OpenGL实现基于鼠标交互的卡通人物和其它环境物体的设计与绘制。使用颜色填充与反走样技术对卡通人物外貌以及衣着进行绘制。实现对卡通人物或物体轮廓的交互控制,点击鼠标左键可以对人物或者物体进行拖拽移动调整。按“↑”按键能够实现卡通人物绕坐标原点(或指定点)进行旋转,按“z”键可实现对选中的人物或者物体进行放缩。选中其中的一个多边形区域,点击鼠标右键,弹出一个菜单,可以对该区域进行不同颜色的选择。
首先设计图形,选择简单的卡通人物可以简化设计过程、加快渲染速度。这里选择机器猫作为绘制的对象,并对其形象进行简化,通过绘制圆、半圆、椭圆、线等简单图形,组合成一个整体的人物形象:
//绘制身体
void DrawBody(int x, int y) {
/*
glEnable(GL_BLEND);//启用颜色混合
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//接受源颜色并将这个颜色(RGB)与alpha值相乘,
//然后把这个结果加上目标颜色乘“1减去源颜色的alpha值”的结果
*/
//启用防走样
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
//左胳膊
{
glLoadIdentity();
glRotatef(theta, 0.0, 0.0, 1.0);
glTranslatef(-38.0, 10.0, 0.0);
glRotatef(45.0, 0.0, 0.0, 1.0);
glColor3f(ColorChoose[BODY_COLOR][0], ColorChoose[BODY_COLOR][1], ColorChoose[BODY_COLOR][2]);
glBegin(GL_POLYGON);
for (int i = 0; i < N; i++) {
tempX = 20 * cos(2 * PI*i / N);
tempY = 10 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
glEnd();
//描边
glColor3f(ColorChoose[LINE_COLOR][0], ColorChoose[LINE_COLOR][1], ColorChoose[LINE_COLOR][2]);
glLineWidth(1.0);//线条粗细设置
glBegin(GL_LINE_LOOP);
for (int i = 0; i < N; i++) {
tempX = 20 * cos(2 * PI*i / N);
tempY = 10 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
glEnd();
}
//左手
{
glLoadIdentity();
glRotatef(theta, 0.0, 0.0, 1.0);
glTranslatef(-50.0, 0.0, 0.0);
glColor3f(ColorChoose[HAND_COLOR][0], ColorChoose[HAND_COLOR][1], ColorChoose[HAND_COLOR][2]);
glBegin(GL_POLYGON);
for (int i = 0; i < N; i++) {
tempX = 8 * cos(2 * PI*i / N);
tempY = 8 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
glEnd();
glColor3f(ColorChoose[LINE_COLOR][0], ColorChoose[LINE_COLOR][1], ColorChoose[LINE_COLOR][2]);
glLineWidth(1.0);//线条粗细设置
glBegin(GL_LINE_LOOP);
for (int i = 0; i < N; i++) {
tempX = 8 * cos(2 * PI*i / N);
tempY = 8 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
glEnd();
}
//右胳膊
{
glLoadIdentity();
glRotatef(theta, 0.0, 0.0, 1.0);
glTranslatef(38.0, 10.0, 0.0);
glRotatef(-45.0, 0.0, 0.0, 1.0);
glColor3f(ColorChoose[BODY_COLOR][0], ColorChoose[BODY_COLOR][1], ColorChoose[BODY_COLOR][2]);
glBegin(GL_POLYGON);
for (int i = 0; i < N; i++) {
tempX = 20 * cos(2 * PI*i / N);
tempY = 10 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
glEnd();
glColor3f(ColorChoose[LINE_COLOR][0], ColorChoose[LINE_COLOR][1], ColorChoose[LINE_COLOR][2]);
glLineWidth(1.0);//线条粗细设置
glBegin(GL_LINE_LOOP);
for (int i = 0; i < N; i++) {
tempX = 20 * cos(2 * PI*i / N);
tempY = 10 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
glEnd();
}
//右手
{
glLoadIdentity();
glRotatef(theta, 0.0, 0.0, 1.0);
glTranslatef(50.0, 0.0, 0.0);
glColor3f(ColorChoose[HAND_COLOR][0], ColorChoose[HAND_COLOR][1], ColorChoose[HAND_COLOR][2]);
glBegin(GL_POLYGON);
for (int i = 0; i < N; i++) {
tempX = 8 * cos(2 * PI*i / N);
tempY = 8 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
glEnd();
glColor3f(ColorChoose[LINE_COLOR][0], ColorChoose[LINE_COLOR][1], ColorChoose[LINE_COLOR][2]);
glLineWidth(1.0);//线条粗细设置
glBegin(GL_LINE_LOOP);
for (int i = 0; i < N; i++) {
tempX = 8 * cos(2 * PI*i / N);
tempY = 8 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
glEnd();
}
//身体
{
glLoadIdentity();
glRotatef(theta, 0.0, 0.0, 1.0);
glColor3f(ColorChoose[BODY_COLOR][0], ColorChoose[BODY_COLOR][1], ColorChoose[BODY_COLOR][2]);
glBegin(GL_POLYGON);
for (int i = 0; i <= N / 8; i++) {
tempX = 40 * cos(2 * PI*i / N);
tempY = 42 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
for (int i = 3 * N / 8; i <= 5 * N / 8; i++) {
tempX = 40 * cos(2 * PI*i / N);
tempY = 42 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
for (int i = 7 * N / 8; i < N; i++) {
tempX = 40 * cos(2 * PI*i / N);
tempY = 42 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
glEnd();
//描边
glColor3f(ColorChoose[LINE_COLOR][0], ColorChoose[LINE_COLOR][0], ColorChoose[LINE_COLOR][0]);
glLineWidth(1.0);//线条粗细设置
glBegin(GL_LINE_LOOP);
for (int i = 0; i <= N / 8; i++) {
tempX = 40 * cos(2 * PI*i / N);
tempY = 42 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
for (int i = 3 * N / 8; i <= 5 * N / 8; i++) {
tempX = 40 * cos(2 * PI*i / N);
tempY = 42 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
for (int i = 7 * N / 8; i < N; i++) {
tempX = 40 * cos(2 * PI*i / N);
tempY = 42 * sin(2 * PI*i / N);
glVertex2f(tempX, tempY);
}
glEnd();
}
//项圈
{
glLoadIdentity();
glRotatef(theta, 0.0, 0.0, 1.0);
glColor3f(ColorChoose[NECKLACE_COLOR][0], ColorChoose[NECKLACE_COLOR][1], ColorChoose[NECKLACE_COLOR][2]);
glBegin(GL_POLYGON);
tempX = 40 * cos(2 * PI * 5 / N);
tempY = 42 * sin(2 * PI * 5 / N);
glVertex2f(tempX, tempY);
tempX = 40 * cos(2 * PI * 15 / N);
//tempY= 40 * sin(2 * PI*15 / N);
glVertex2f(tempX, tempY);
tempY = 40 * sin(2 * PI * 15 / N) + 5;
glVertex2f(tempX, tempY);
tempX = 40 * cos(2 * PI * 5 / N);
glVertex2f(tempX, tempY);
glEnd();
glColor3f(ColorChoose[LINE_COLOR][0], ColorChoose[LINE_COLOR][0], ColorChoose[LINE_COLOR][0]);