读书人

[OpenGL]图形学课程设计:二维动画人脸

发布时间: 2013-10-17 17:26:17 作者: rapoo

[OpenGL]图形学课程设计:二维卡通人脸交互设计与控制

实验名称:二维卡通人脸交互设计与控制

实验要求:

    根据OpenGL提供的直线,多边形绘制算法,实现基于鼠标交互的卡通人物设计与绘制。使用颜色填充与反走样技术对人脸进行绘制。实现对卡通人脸的交互控制,点击鼠标左键可以对人脸进行拖拽移动。按“↑”按键能够实现卡通人脸绕坐标原点进行旋转。附加要求:选中其中的一个多边形区域,点击鼠标右键,弹出一个菜单,可以对该区域进行不同颜色的选择。

实验步骤:左击选择对象,右击染色。按住向上箭头逆时针旋转,按住向下箭头顺时针旋转。



#include <Windows.h>#include <gl\glut.h>#include <stdio.h>  #include<math.h>#define PI 3.14#define SIZE 512  #define FACE 1#define NOSE 2#define MOUTH 3#define HAIR 4#define BROW 5#define EYES 6static int FACE_COLOR = 7;static int NOSE_COLOR = 6;static int MOUTH_COLOR = 1;static int HAIR_COLOR = 4;static int BROW_COLOR = 5;static int EYES_COLOR = 0;static GLfloat theta = 0;  static GLfloat t_x = 0;static GLfloat t_y = 0;int select_part = 0;static int o_x = 0;static int o_y = 0;#define WIN_WIDTH 500#define WIN_HEIGHT 500#define VIEW_WIDTH 2.2#define VIEW_HEIGHT 2.2static GLfloat colors[8][3] = { { 0.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0 },  { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 }, { 0.0, 1.0, 1.0 }, { 1.0, 0.0, 1.0 }, { 1.0, 1.0, 0.0 }, { 1.0, 1.0, 1.0 } };  //画眼睛void drawEyes(){glBegin(GL_POLYGON); glVertex2f( -0.27, 0.12);glVertex2f( -0.27, 0.18);glVertex2f( -0.33, 0.18);glVertex2f( -0.33, 0.12);glEnd();glBegin(GL_POLYGON); glVertex2f( 0.27, 0.12);glVertex2f( 0.27, 0.18);glVertex2f( 0.33, 0.18);glVertex2f( 0.33, 0.12);glEnd();}//画眉毛void drawBrow(){glLineWidth(5); glBegin(GL_LINES); glVertex2f( -0.4, 0.3);glVertex2f( -0.2, 0.2);glVertex2f( 0.2, 0.2);glVertex2f( 0.4, 0.3);glEnd();}//画头发void drawHair(){glBegin( GL_TRIANGLE_FAN);  glVertex2f( 0.4, 0.9);glVertex2f( -0.5, 0.8);glVertex2f( -0.8, 0.3);glVertex2f( 0.1, 0.5);glVertex2f( 0.2, 0.3);glVertex2f( 0.5, 0.5);glVertex2f( 0.8, 0.4);glEnd();}//画脸void drawFace(){glBegin(GL_POLYGON);glVertex2f( -0.5 , 0.5);glVertex2f( -0.4 , -0.5);glVertex2f( 0.0 , -0.8);glVertex2f( 0.4 , -0.5);glVertex2f( 0.5 , 0.5);glEnd();}//画嘴巴void drawMouth(){glBegin( GL_POLYGON);glVertex2f( -0.2, -0.4);glVertex2f( -0.1, -0.6);glVertex2f( 0.1, -0.6);glVertex2f( 0.2, -0.4);glEnd();}//画鼻子void drawNose(){glBegin( GL_TRIANGLES);glVertex2f( 0, 0.1);glVertex2f( -0.1, -0.3);glVertex2f( 0.1, -0.3);glEnd();}//绘制函数void drawObjects(GLenum mode)  {  if(mode == GL_SELECT) glLoadName(FACE);//画脸glColor3f(colors[FACE_COLOR][0],colors[FACE_COLOR][1],colors[FACE_COLOR][2]);drawFace();if(mode == GL_SELECT) glLoadName(NOSE);//画鼻子glColor3f(colors[NOSE_COLOR][0],colors[NOSE_COLOR][1],colors[NOSE_COLOR][2]);drawNose();if(mode == GL_SELECT) glLoadName(MOUTH);//画嘴巴glColor3f(colors[MOUTH_COLOR][0],colors[MOUTH_COLOR][1],colors[MOUTH_COLOR][2]);drawMouth();if(mode == GL_SELECT) glLoadName(HAIR);//画头发glColor3f(colors[HAIR_COLOR][0],colors[HAIR_COLOR][1],colors[HAIR_COLOR][2]);drawHair();if(mode == GL_SELECT) glLoadName(BROW);//画眉毛glColor3f(colors[BROW_COLOR][0],colors[BROW_COLOR][1],colors[BROW_COLOR][2]);drawBrow();if(mode == GL_SELECT) glLoadName(EYES);//画眼睛glColor3f(colors[EYES_COLOR][0],colors[EYES_COLOR][1],colors[EYES_COLOR][2]);drawEyes();}  void myDisplay(){//清除缓存glClear(GL_COLOR_BUFFER_BIT);//旋转glLoadIdentity(); //如果是绕人脸原点//glTranslatef(t_x, t_y, 0.0); //glRotatef(theta, 0.0, 0.0, 1.0);//如果是绕系统原点glRotatef(theta, 0.0, 0.0, 1.0);glTranslatef(t_x, t_y, 0.0); //RANDER模式绘制物体drawObjects(GL_RENDER);//绘制glFlush(); }void myInit(){glClearColor(0.0, 0.0, 0.0, 1.0);}void myRreshape(int w, int h){glViewport(0, 0, w, h);  glMatrixMode(GL_PROJECTION);  glLoadIdentity();  gluOrtho2D(-VIEW_WIDTH/2,VIEW_WIDTH/2,-VIEW_HEIGHT/2,VIEW_HEIGHT/2);glMatrixMode(GL_MODELVIEW);  glLoadIdentity();//开启反走样glEnable( GL_BLEND);glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST);glEnable( GL_POLYGON_SMOOTH);glEnable( GL_POINT_SMOOTH);glEnable( GL_LINE_SMOOTH);}//处理点击事件void processHits (GLint hits, GLuint buffer[])  {  unsigned int i, j;  GLuint names, *ptr;  printf("一共打中%d个!\n", hits);  ptr=(GLuint *) buffer;  for (i = 0; i < hits; i++) {/*  for each hit  */  names = *ptr;ptr+=3;for (j = 0; j < names; j++)  { /*  for each name */  if(*ptr==1){printf ("打脸\n");}else if(*ptr==2){printf ("鼻子\n");  select_part = NOSE;}else if(*ptr==3){printf ("嘴巴\n");  select_part = MOUTH;}else if(*ptr==4){printf ("头发\n"); select_part = HAIR;}else if(*ptr==5){printf ("眉毛\n");  select_part = BROW;}else if(*ptr==6){printf ("眼睛\n");  select_part = EYES;}ptr++;  }  }  printf ("select_part:%d\n",select_part);  }  static bool left_down = false;//脸移动void myMouseMove(int x,int y){if(left_down){GLfloat d_x = (x - o_x) * VIEW_WIDTH / WIN_WIDTH;GLfloat d_y  = (o_y - y) * VIEW_HEIGHT / WIN_HEIGHT;//如果绕着脸中心转//t_x += d_x;//t_y += d_y;//将鼠标偏移量旋转-thetat_x += d_x*cos(-2*PI*theta/360)-d_y*sin(-2*PI*theta/360);t_y += d_x*sin(-2*PI*theta/360)+d_y*cos(-2*PI*theta/360);//记录下鼠标的坐标o_x = x;o_y = y;glutPostRedisplay();}}//鼠标响应void myMouse(int button, int state, int x, int y){GLuint selectBuf[SIZE];  GLint hits;  GLint viewport[4];if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {left_down = true;o_x = x;o_y = y;}if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {left_down = false;}if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {  printf ("select_part:%d\n",select_part);  glGetIntegerv(GL_VIEWPORT, viewport);  glSelectBuffer (SIZE, selectBuf);  glRenderMode(GL_SELECT);  glInitNames();  glPushName(0);  glMatrixMode(GL_PROJECTION);  glPushMatrix();  glLoadIdentity();  gluPickMatrix((GLdouble) x, (GLdouble) (viewport[3] - y),3.0, 3.0, viewport);  gluOrtho2D(-VIEW_WIDTH/2,VIEW_WIDTH/2,-VIEW_HEIGHT/2,VIEW_HEIGHT/2);drawObjects(GL_SELECT);  glMatrixMode(GL_PROJECTION);  glPopMatrix();  hits = glRenderMode(GL_RENDER);  processHits(hits, selectBuf); }  }void mySpecial(int key, int x, int y){switch (key)  {  case GLUT_KEY_UP:  theta = (theta+10);glutPostRedisplay();break;case GLUT_KEY_DOWN:  theta = (theta-10);glutPostRedisplay();break;} }void myKeyboard(unsigned char key, int x, int y){switch (key)  {  }}void main_menu(int index) {  if(index == -1)return;switch (select_part) {  case FACE:FACE_COLOR = index;break;  case NOSE:NOSE_COLOR = index;break;    case MOUTH:MOUTH_COLOR = index;break;    case HAIR:HAIR_COLOR = index;break;case BROW:BROW_COLOR = index;break;    case EYES:EYES_COLOR = index;break;   }glutPostRedisplay();}void main(int argc,char** argv){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(500,500);glutInitWindowPosition(0,0);glutCreateWindow("OpenGL_01");myInit();glutReshapeFunc(myRreshape);  glutDisplayFunc(myDisplay);  glutMouseFunc(myMouse);  glutKeyboardFunc(myKeyboard);glutSpecialFunc(mySpecial);glutMotionFunc(myMouseMove);//右击事件glutCreateMenu(main_menu);  glutAddMenuEntry("左击选择染色对象", -1);  glutAddMenuEntry("黑色", 0);      glutAddMenuEntry("红色", 1);      glutAddMenuEntry("绿色", 2);      glutAddMenuEntry("蓝色", 3);      glutAddMenuEntry("青色", 4);      glutAddMenuEntry("紫色", 5);      glutAddMenuEntry("黄色", 6);      glutAddMenuEntry("白色", 7);    glutAttachMenu(GLUT_RIGHT_BUTTON);  glutMainLoop();}


读书人网 >图形图像

热点推荐