山东大学 图形学 openGL实验一
2016-05-14 19:14
393 查看
根据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 6 static 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.2 static 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; //将鼠标偏移量旋转-theta t_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) { switc 4000 h (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(); }
范例二:
#include <windows.h> #include <GL/glu.h> #include <GL/gl.h> #include <GL/glut.h> //#include <GL/glaux.h> #include <math.h> #include <stdio.h> #define Glass 1 #define Stone 2 #define Eye 3 #define Eye1 4 #define Nose 5 #define Cap 6 #define Crown 7 #define Clothes 8 #define Superman 9 #define PI 3.1416 #define MAX_CHAR 128 static int EYE_COLOR = 0; static int EYE1_COLOR = 0; static int NOSE_COLOR = 0; static int CROWN_COLOR = 6; static int SUPERMAN_COLOR = 3; GLuint texture[4]; GLuint base; BOOL GLASS_STATE; BOOL STONE_STATE; BOOL EYE_STATE; BOOL EYE1_STATE; BOOL NOSE_STATE; BOOL CAP_STATE; BOOL CROWN_STATE; BOOL CLOTHES_STATE; BOOL SUPERMAN_STATE; GLuint GlassCor[2] = { 0,0 }; GLuint StoneCor[2] = { 20,10 }; GLuint EyeCor[2] = { -12,60 }; GLuint EyeCor1[2] = { 12,60 }; GLuint NoseCor[2] = { 0,60 }; GLuint CapCor[2] = { 0,85 }; GLuint CrownCor[2] = { 0 + 118,9 + 70 }; GLuint ClothesCor[2] = { 0 + 110,0 - 50 }; GLuint SupermanCor[2] = { 0,0 }; int Wide = 0; int High = 0; const int N = 40; float xx[50], yy[50] = { 0 }; int select_part = 0; static GLfloat theta = 0; static GLfloat colors[8][3] = { { 0.0, 0.0, 0.0 },{ 1.0, 0.0, 0.0 },{ 0.0, 1.0, 0.0 },{ 0.5,0.5,0.75 }, { 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 paintViewportA(); void drawString(const char* str); void selectFont(int size, int charset, const char* face); void DrawSphereTexture(int x, int y) { glEnable(GL_BLEND); //启用混合功能,将图形颜色同周围颜色相混合 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_POINT_SMOOTH); //点抗锯齿 glEnable(GL_LINE_SMOOTH); //线抗锯齿 glEnable(GL_POLYGON_SMOOTH); //多边形抗锯齿 glLoadIdentity(); glRotatef(-30.0, 0.0, 0.0, 1.0); glRotatef(theta, 0.0, 0.0, 1.0); //第三步 画手臂 左 glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_POLYGON); //用线进行图形连接 for (int i = 0; i<N; i++) { xx[i] = 16 * cos(2 * i*PI / N) - 28; yy[i] = 40 * sin(2 * i*PI / N) - 10; glVertex2f(xx[i], yy[i]); } glEnd(); //再描一遍线 glColor3f(0.0f, 0.0f, 0.0f); glBegin(GL_LINE_LOOP); for (int i = 0; i<N; i++) { xx[i] = 16 * cos(2 * i*PI / N) - 28; yy[i] = 40 * sin(2 * i*PI / N) - 10; glVertex2f(xx[i], yy[i]); } glEnd(); //画手臂 右 glLoadIdentity(); glRotatef(theta, 0.0, 0.0, 1.0); glRotatef(30.0, 0.0, 0.0, 1.0); glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_POLYGON); //用线进行图形连接 for (int i = 0; i<N; i++) { xx[i] = 16 * cos(2 * i*PI / N) + 28; yy[i] = 40 * sin(2 * i*PI / N) - 10; glVertex2f(xx[i], yy[i]); } glEnd(); //再描一遍线 glColor3f(0.0f, 0.0f, 0.0f); glBegin(GL_LINE_LOOP); for (int i = 0; i<N; i++) { xx[i] = 16 * cos(2 * i*PI / N) + 28; yy[i] = 40 * sin(2 * i*PI / N) - 10; glVertex2f(xx[i], yy[i]); } glEnd(); //开始画腿************************************************************************ glLoadIdentity(); glRotatef(theta, 0.0, 0.0, 1.0); glRotatef(8.0, 0.0, 0.0, 1.0); glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_POLYGON); //用线进行图形连接 for (int i = 0; i<N; i++) { xx[i] = 15 * cos(2 * i*PI / N) - 22; yy[i] = 33 * sin(2 * i*PI / N) - 37; glVertex2f(xx[i], yy[i]); } glEnd(); //再描一遍线 glColor3f(0.0f, 0.0f, 0.0f); glBegin(GL_LINE_LOOP); for (int i = 0; i<N; i++) { xx[i] = 15 * cos(2 * i*PI / N) - 22; yy[i] = 33 * sin(2 * i*PI / N) - 37; glVertex2f(xx[i], yy[i]); } glEnd(); //画右腿 glLoadIdentity(); glRotatef(theta, 0.0, 0.0, 1.0); glRotatef(-8.0, 0.0, 0.0, 1.0); glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_POLYGON); //用线进行图形连接 for (int i = 0; i<N; i++) { xx[i] = 15 * cos(2 * i*PI / N) + 22; yy[i] = 33 * sin(2 * i*PI / N) - 37; glVertex2f(xx[i], yy[i]); } glEnd(); //再描一遍线 glColor3f(0.0f, 0.0f, 0.0f); glBegin(GL_LINE_LOOP); for (int i = 0; i<N; i++) { xx[i] = 15 * cos(2 * i*PI / N) + 22; yy[i] = 33 * sin(2 * i*PI / N) - 37; glVertex2f(xx[i], yy[i]); } glEnd(); glLoadIdentity(); glRotatef(theta, 0.0, 0.0, 1.0); //再画身体********************************************************************* glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_POLYGON); //用线进行图形连接 for (int i = 0; i<N; i++) { xx[i] = 40 * cos(2 * i*PI / N); yy[i] = 45 * sin(2 * i*PI / N); glVertex2f(xx[i], yy[i]); } glEnd(); //再描一遍线 glColor3f(0.0f, 0.0f, 0.0f); glBegin(GL_LINE_LOOP); for (int i = 0; i<N; i++) { xx[i] = 40 * cos(2 * i*PI / N); yy[i] = 45 * sin(2 * i*PI / N); glVertex2f(xx[i], yy[i]); } glEnd(); //画头部 glLoadIdentity(); glRotatef(theta, 0.0, 0.0, 1.0); glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_POLYGON); //用线进行图形连接 for (int i = 0; i<N; i++) { xx[i] = 30 * cos(2 * i*PI / N); yy[i] = 20 * sin(2 * i*PI / N) + 60; glVertex2f(xx[i], yy[i]); } glEnd(); //再描一遍线 glColor3f(0.0f, 0.0f, 0.0f); glBegin(GL_LINE_LOOP); for (int i = 0; i<N; i++) { xx[i] = 30 * cos(2 * i*PI / N); yy[i] = 20 * sin(2 * i*PI / N) + 60; glVertex2f(xx[i], yy[i]); } glEnd(); } //胸章 void DrawXiongzhang(int x, int y) { glLoadIdentity(); glRotatef(theta, 0.0, 0.0, 1.0); glTranslatef(0, 0, 30); glColor3f(0.0f, 1.0f, 0.0f); glBegin(GL_POLYGON); //用线进行图形连接 for (int i = 0; i<N; i++) { xx[i] = 10 * cos(2 * i*PI / N) + x; yy[i] = 10 * sin(2 * i*PI / N) + y; glVertex2f(xx[i], yy[i]); } glEnd(); //再内嵌一个三角形 glColor3f(0.0, 0.0, 1.0); glBegin(GL_LINE_LOOP); glVertex2f(-5.0 + x, -2.5 + y); glVertex2f(5.0 + x, -2.5 + y); glVertex2f(0.0 + x, 5.0 + y); glEnd(); } //眼部提取出来 void DrawEye1(int x, int y) { //画眼睛 左 glLoadIdentity(); glRotatef(theta, 0.0, 0.0, 1.0); glTranslatef(0, 0, 30); glColor3f(colors[EYE_COLOR][0], colors[EYE_COLOR][1], colors[EYE_COLOR][2]); //glColor3f(0.0f,0.0f,0.0f); glBegin(GL_POLYGON); //用线进行图形连接 for (int i = 0; i<N; i++) { xx[i] = 6 * cos(2 * i*PI / N) + x; yy[i] = 6 * sin(2 * i*PI / N) + y; glVertex2f(xx[i], yy[i]); } glEnd(); } void DrawEye2(int x, int y) { //画眼睛 右 glLoadIdentity(); glRotatef(theta, 0.0, 0.0, 1.0); glTranslatef(0, 0, 30); glColor3f(colors[EYE1_COLOR][0], colors[EYE1_COLOR][1], colors[EYE1_COLOR][2]); //glColor3f(0.0f,0.0f,0.0f); glBegin(GL_POLYGON); //用线进行图形连接 for (int i = 0; i<N; i++) { xx[i] = 6 * cos(2 * i*PI / N) + x; yy[i] = 6 * sin(2 * i*PI / N) + y; glVertex2f(xx[i], yy[i]); } glEnd(); } void DrawNose(int x, int y) { glLoadIdentity(); glRotatef(theta, 0.0, 0.0, 1.0); glTranslatef(0, 0, 30); //glColor3f(0.0f,0.0f,0.0f); glColor3f(colors[NOSE_COLOR][0], colors[NOSE_COLOR][1], colors[NOSE_COLOR][2]); glLineWidth(2); glBegin(GL_LINES); glVertex2f(-12 + x, y); glVertex2f(12 + x, y); glEnd(); } void DrawCap(int x, int y) { //此处开始绘制帽子 glLoadIdentity(); glRotatef(theta, 0.0, 0.0, 1.0); glTranslatef(0, 0, 30); glBegin(GL_POLYGON); glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(0 + x, y - 5); glVertex2f(-13 + x, y - 10); glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(-25 + x, y - 10); glVertex2f(-12 + x, y - 2); glColor3f(0.0f, 0.0f, 1.0f); glVertex2f(0 + x, y + 20); glVertex2f(12 + x, y - 2); glColor3f(0.5f, 0.5f, 0.5f); glVertex2f(25 + x, y - 10); glVertex2f(13 + x, y - 10); glEnd(); } void DrawCrown(int x, int y) { //开始绘制王冠 glLoadIdentity(); glRotatef(theta, 0.0, 0.0, 1.0); glTranslatef(0, 0, 30); glColor3f(1.0f, 1.0f, 0.0f); glColor3f(colors[CROWN_COLOR][0], colors[CROWN_COLOR][1], colors[CROWN_COLOR][2]); glBegin(GL_POLYGON); glVertex2f(-10 + x, y - 9); glVertex2f(-13 + x, 6 + y); glVertex2f(-5 + x, y - 2); glVertex2f(0 + x, 9 + y); glVertex2f(5 + x, y - 2); glVertex2f(13 + x, 6 + y); glVertex2f(10 + x, y - 9); glEnd(); } void DrawClothes(int x, int y) { //衣服绘制 glLoadIdentity(); glRotatef(theta, 0.0, 0.0, 1.0); glTranslatef(0, 0, 30); glColor3f(0.0f, 0.0f, 0.0f); glBegin(GL_POLYGON); //用线进行图形连接 for (int i = 0; i<8; i++) { xx[i] = 40 * cos(2 * i*PI / N) + x; yy[i] = 45 * sin(2 * i*PI / N) + y; glVertex2f(xx[i], yy[i]); } for (int i = 13; i<20; i++) { xx[i] = 40 * cos(2 * i*PI / N) + x; yy[i] = 45 * sin(2 * i*PI / N) + y; glVertex2f(xx[i], yy[i]); } for (int i = 20; i<N; i++) { xx[i] = 40 * cos(2 * i*PI / N) + x; yy[i] = 45 * sin(2 * i*PI / N) + y; glVertex2f(xx[i], yy[i]); } glEnd(); //衣服上的一些纹理绘制 glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_LINE_LOOP); glVertex2f(-7 + x, 40 + y); glVertex2f(0 + x, 20 + y); glVertex2f(7 + x, 40 + y); glEnd(); glBegin(GL_LINE_LOOP); glVertex2f(-20 + x, 20 + y); glVertex2f(-20 + x, 10 + y); glVertex2f(-10 + x, 10 + y); glVertex2f(-10 + x, 20 + y); glEnd(); glBegin(GL_LINES); glVertex2f(0 + x, 0 + y); glVertex2f(0 + x, -25 + y); glEnd(); glBegin(GL_LINES); glVertex2f(0 + x, -25 + y); glVertex2f(-10 + x, -40 + y); glEnd(); glBegin(GL_LINES); glVertex2f(0 + x, -25 + y); glVertex2f(10 + x, -40 + y); glEnd(); glColor3f(1.0f, 1.0f, 0.0f); glBegin(GL_POLYGON); //用线进行图形连接 for (int i = 0; i<N; i++) { xx[i] = 4 * cos(2 * i*PI / N) + x; yy[i] = 4 * sin(2 * i*PI / N) + y; glVertex2f(xx[i], yy[i]); } glEnd(); } void DrawSuperman(int x, int y) { //绘制超人装 glLoadIdentity(); glRotatef(theta, 0.0, 0.0, 1.0); glTranslatef(0, 0, 20); //glColor3f(0.5f,0.5f,0.75f); glColor3f(colors[SUPERMAN_COLOR][0], colors[SUPERMAN_COLOR][1], colors[SUPERMAN_COLOR][2]); glBegin(GL_POLYGON); //用线进行图形连接 for (int i = 0; i<8; i++) { xx[i] = 40 * cos(2 * i*PI / N) + x; yy[i] = 45 * sin(2 * i*PI / N) + y; glVertex2f(xx[i], yy[i]); } for (int i = 13; i<20; i++) { xx[i] = 40 * cos(2 * i*PI / N) + x; yy[i] = 45 * sin(2 * i*PI / N) + y; glVertex2f(xx[i], yy[i]); } for (int i = 20; i<N; i++) { xx[i] = 40 * cos(2 * i*PI / N) + x; yy[i] = 45 * sin(2 * i*PI / N) + y; glVertex2f(xx[i], yy[i]); } glEnd(); //绘制超人标志 glColor3f(1.0f, 1.0f, 0.0f); glBegin(GL_POLYGON); glVertex2f(-14 + x, 30 + y); glVertex2f(14 + x, 30 + y); glVertex2f(20 + x, 21 + y); glVertex2f(0 + x, 0 + y); glVertex2f(-20 + x, 21 + y); glEnd(); glColor3f(1.0f, 0.0f, 0.0f); glLineWidth(4); glBegin(GL_LINE_LOOP); glVertex2f(-15 + x, 30 + y); glVertex2f(15 + x, 30 + y); glVertex2f(21 + x, 21 + y); glVertex2f(0 + x, -1 + y); glVertex2f(-21 + x, 21 + y); glEnd(); //绘制 S selectFont(80, ANSI_CHARSET, "Comic Sans MS"); glColor3f(1.0f, 0.0f, 0.0f); //设置字体颜色 glRasterPos2i(-6 + x, 10 + y); //起始位置 drawString("S"); //输出的字符串 //绘制衣领 glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POLYGON); glVertex2f(0 + x, 40 + y); glVertex2f(-20 + x, 40 + y); glVertex2f(-17 + x, 45 + y); glEnd(); glBegin(GL_POLYGON); glVertex2f(0 + x, 40 + y); glVertex2f(20 + x, 40 + y); glVertex2f(17 + x, 45 + y); glEnd(); } void RenderScene(void) { // Clear the window with current clearing color glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //旋转 paintViewportA(); // Save the matrix state and do the rotations glMatrixMode(GL_MODELVIEW); glPushMatrix(); // Translate the whole scene out and into view // glTranslatef(150.0f, 0.0f, -50.0f); // Initialize the names stack glInitNames(); glPushName(0); //glLoadIdentity(); glLoadName(Glass); DrawSphereTexture(GlassCor[0], GlassCor[1]); glPushMatrix(); glLoadIdentity(); glLoadName(Stone); DrawXiongzhang(StoneCor[0], StoneCor[1]); glPushMatrix(); glLoadIdentity(); glLoadName(Eye); DrawEye1(EyeCor[0], EyeCor[1]); glPushMatrix(); glLoadIdentity(); glLoadName(Eye1); DrawEye2(EyeCor1[0], EyeCor1[1]); glPushMatrix(); glLoadIdentity(); glLoadName(Nose); DrawNose(NoseCor[0], NoseCor[1]); glPushMatrix(); glLoadIdentity(); glLoadName(Cap); DrawCap(CapCor[0], CapCor[1]); glPopMatrix(); glPushMatrix(); glLoadIdentity(); glLoadName(Crown); DrawCrown(CrownCor[0], CrownCor[1]); glPopMatrix(); glPushMatrix(); glLoadIdentity(); glLoadName(Clothes); DrawClothes(ClothesCor[0], ClothesCor[1]); glPopMatrix(); glPushMatrix(); glLoadIdentity(); glLoadName(Superman); DrawSuperman(SupermanCor[0], SupermanCor[1]); glPopMatrix(); glPopMatrix(); glPopMatrix(); glPopMatrix(); glPopMatrix(); // Restore the matrix state glPopMatrix(); // Modelview matrix glutSwapBuffers(); } //此处开始添加多重视口 此处简化 不采用多重视角 void paintViewportA() { int _width = Wide / 8; int _height = High / 6; glColor3f(1, 1, 1); glBegin(GL_LINES); glVertex2f(_width, -_height); glVertex2f(_width, _height); glEnd(); glBegin(GL_LINES); glVertex2f(_width, _height / 3); glVertex2f(2 * _width, _height / 3); glEnd(); glBegin(GL_LINES); glVertex2f(_width, 2 * _height / 3); glVertex2f(2 * _width, 2 * _height / 3); glEnd(); glBegin(GL_LINES); glVertex2f(_width, 0); glVertex2f(2 * _width, 0); glEnd(); } void ProcessPlanet(GLuint id) { switch (id) { case Glass: // glutSetWindowTitle("You clicked on the Glass!"); GLASS_STATE = TRUE; STONE_STATE = FALSE; EYE_STATE = FALSE; EYE1_STATE = FALSE; NOSE_STATE = FALSE; CAP_STATE = FALSE; CROWN_STATE = FALSE; CLOTHES_STATE = FALSE; SUPERMAN_STATE = FALSE; select_part = Glass; printf("Glass \n"); break; case Stone: // glutSetWindowTitle("You clicked on Stone!"); STONE_STATE = TRUE; GLASS_STATE = FALSE; EYE_STATE = FALSE; EYE1_STATE = FALSE; NOSE_STATE = FALSE; CAP_STATE = FALSE; CROWN_STATE = FALSE; CLOTHES_STATE = FALSE; SUPERMAN_STATE = FALSE; select_part = Stone; printf("Stone \n"); break; case Eye: STONE_STATE = FALSE; GLASS_STATE = FALSE; EYE_STATE = TRUE; EYE1_STATE = FALSE; NOSE_STATE = FALSE; CAP_STATE = FALSE; CROWN_STATE = FALSE; CLOTHES_STATE = FALSE; SUPERMAN_STATE = FALSE; select_part = Eye; printf("Eye \n"); break; case Eye1: STONE_STATE = FALSE; GLASS_STATE = FALSE; EYE_STATE = FALSE; EYE1_STATE = TRUE; NOSE_STATE = FALSE; CAP_STATE = FALSE; CROWN_STATE = FALSE; CLOTHES_STATE = FALSE; SUPERMAN_STATE = FALSE; select_part = Eye1; break; case Nose: STONE_STATE = FALSE; GLASS_STATE = FALSE; EYE_STATE = FALSE; EYE1_STATE = FALSE; NOSE_STATE = TRUE; CAP_STATE = FALSE; CROWN_STATE = FALSE; CLOTHES_STATE = FALSE; SUPERMAN_STATE = FALSE; select_part = Nose; break; case Cap: STONE_STATE = FALSE; GLASS_STATE = FALSE; EYE_STATE = FALSE; EYE1_STATE = FALSE; NOSE_STATE = FALSE; CAP_STATE = TRUE; CROWN_STATE = FALSE; CLOTHES_STAT d6ea E = FALSE; SUPERMAN_STATE = FALSE; select_part = Cap; break; case Crown: STONE_STATE = FALSE; GLASS_STATE = FALSE; EYE_STATE = FALSE; EYE1_STATE = FALSE; NOSE_STATE = FALSE; CAP_STATE = FALSE; CROWN_STATE = TRUE; CLOTHES_STATE = FALSE; SUPERMAN_STATE = FALSE; select_part = Crown; break; case Clothes: STONE_STATE = FALSE; GLASS_STATE = FALSE; EYE_STATE = FALSE; EYE1_STATE = FALSE; NOSE_STATE = FALSE; CAP_STATE = FALSE; CROWN_STATE = FALSE; CLOTHES_STATE = TRUE; SUPERMAN_STATE = FALSE; select_part = Clothes; break; case Superman: STONE_STATE = FALSE; GLASS_STATE = FALSE; EYE_STATE = FALSE; EYE1_STATE = FALSE; NOSE_STATE = FALSE; CAP_STATE = FALSE; CROWN_STATE = FALSE; CLOTHES_STATE = FALSE; SUPERMAN_STATE = TRUE; select_part = Superman; break; } } #define BUFFER_LENGTH 64 void ProcessSelection(int xPos, int yPos) { GLfloat fAspect; // Space for selection buffer static GLuint selectBuff[BUFFER_LENGTH]; // Hit counter and viewport storage GLint hits, viewport[4]; // Setup selection buffer glSelectBuffer(BUFFER_LENGTH, selectBuff); // Get the viewport glGetIntegerv(GL_VIEWPORT, viewport); // Switch to projection and save the matrix glMatrixMode(GL_PROJECTION); glPushMatrix(); // Change render mode glRenderMode(GL_SELECT); // Establish new clipping volume to be unit cube around // mouse cursor point (xPos, yPos) and extending two pixels // in the vertical and horizontal direction glLoadIdentity(); gluPickMatrix(xPos, viewport[3] - yPos, 2, 2, viewport); //应用透视投影矩阵 fAspect = (float)viewport[2] / (float)viewport[3]; if (viewport[2] <= viewport[3]) { glOrtho(-100, 100, -100 * fAspect, 100 * fAspect, -100, 100); } else { glOrtho(-100 * fAspect, 100 * fAspect, -100, 100, -100, 100); } // Draw the scene RenderScene(); // Collect the hits hits = glRenderMode(GL_RENDER); // If a single hit occurred, display the info. if (hits > 0) { int Choose = selectBuff[3]; int depth = selectBuff[1]; printf("1 ************ %d %d ", Choose, depth); for (int loop = 1; loop<hits; loop++) { if (selectBuff[loop * 4 + 1] < GLuint(depth)) { Choose = selectBuff[loop * 4 + 3]; depth = selectBuff[loop * 4 + 1]; } printf(">2 ************ %d %d ", Choose, depth); } printf("************ %d %d \n", hits, Choose); ProcessPlanet(GLuint(Choose)); } // Restore the projection matrix glMatrixMode(GL_PROJECTION); glPopMatrix(); // Go back to modelview for normal rendering glMatrixMode(GL_MODELVIEW); } /////////////////////////////////////////////////////////// // Process the mouse click void MouseCallback(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) ProcessSelection(x, y); if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { GLASS_STATE = FALSE; STONE_STATE = FALSE; EYE_STATE = FALSE; EYE1_STATE = FALSE; NOSE_STATE = FALSE; CAP_STATE = FALSE; CROWN_STATE = FALSE; CLOTHES_STATE = FALSE; SUPERMAN_STATE = FALSE; } } void MouseMoveCallback(int x, int y) { GLint viewport[4]; GLfloat fA; glGetIntegerv(GL_VIEWPORT, viewport); fA = (float)viewport[2] / (float)viewport[3]; if (GLASS_STATE == TRUE) { if (viewport[2] <= viewport[3]) { GlassCor[0] = -100 + 200 * x / viewport[2]; GlassCor[1] = -100 * fA + (viewport[3] - y) * 200 * fA / viewport[3]; } else { GlassCor[0] = -100 * fA + 200 * fA*x / viewport[2]; GlassCor[1] = -100 + (viewport[3] - y) * 200 / viewport[3]; } RenderScene(); } if (STONE_STATE == TRUE) { if (viewport[2] <= viewport[3]) { StoneCor[0] = -100 + 200 * x / viewport[2]; StoneCor[1] = -100 * fA + (viewport[3] - y) * 200 * fA / viewport[3]; } else { StoneCor[0] = -100 * fA + 200 * fA*x / viewport[2]; StoneCor[1] = -100 + (viewport[3] - y) * 200 / viewport[3]; } RenderScene(); } if (EYE_STATE == TRUE) { if (viewport[2] <= viewport[3]) { EyeCor[0] = -100 + 200 * x / viewport[2]; EyeCor[1] = -100 * fA + (viewport[3] - y) * 200 * fA / viewport[3]; } else { EyeCor[0] = -100 * fA + 200 * fA*x / viewport[2]; EyeCor[1] = -100 + (viewport[3] - y) * 200 / viewport[3]; } RenderScene(); } if (EYE1_STATE == TRUE) { if (viewport[2] <= viewport[3]) { EyeCor1[0] = -100 + 200 * x / viewport[2]; EyeCor1[1] = -100 * fA + (viewport[3] - y) * 200 * fA / viewport[3]; } else { EyeCor1[0] = -100 * fA + 200 * fA*x / viewport[2]; EyeCor1[1] = -100 + (viewport[3] - y) * 200 / viewport[3]; } RenderScene(); } if (NOSE_STATE == TRUE) { if (viewport[2] <= viewport[3]) { NoseCor[0] = -100 + 200 * x / viewport[2]; NoseCor[1] = -100 * fA + (viewport[3] - y) * 200 * fA / viewport[3]; } else { NoseCor[0] = -100 * fA + 200 * fA*x / viewport[2]; NoseCor[1] = -100 + (viewport[3] - y) * 200 / viewport[3]; } RenderScene(); } if (CAP_STATE == TRUE) { if (viewport[2] <= viewport[3]) { CapCor[0] = -100 + 200 * x / viewport[2]; CapCor[1] = -100 * fA + (viewport[3] - y) * 200 * fA / viewport[3]; } else { CapCor[0] = -100 * fA + 200 * fA*x / viewport[2]; CapCor[1] = -100 + (viewport[3] - y) * 200 / viewport[3]; } RenderScene(); } if (CROWN_STATE == TRUE) { if (viewport[2] <= viewport[3]) { CrownCor[0] = -100 + 200 * x / viewport[2]; CrownCor[1] = -100 * fA + (viewport[3] - y) * 200 * fA / viewport[3]; } else { CrownCor[0] = -100 * fA + 200 * fA*x / viewport[2]; CrownCor[1] = -100 + (viewport[3] - y) * 200 / viewport[3]; } RenderScene(); } if (CLOTHES_STATE == TRUE) { if (viewport[2] <= viewport[3]) { ClothesCor[0] = -100 + 200 * x / viewport[2]; ClothesCor[1] = -100 * fA + (viewport[3] - y) * 200 * fA / viewport[3]; } else { ClothesCor[0] = -100 * fA + 200 * fA*x / viewport[2]; ClothesCor[1] = -100 + (viewport[3] - y) * 200 / viewport[3]; } RenderScene(); } if (SUPERMAN_STATE == TRUE) { if (viewport[2] <= viewport[3]) { SupermanCor[0] = -100 + 200 * x / viewport[2]; SupermanCor[1] = -100 * fA + (viewport[3] - y) * 200 * fA / viewport[3]; } else { SupermanCor[0] = -100 * fA + 200 * fA*x / viewport[2]; SupermanCor[1] = -100 + (viewport[3] - y) * 200 / viewport[3]; } RenderScene(); } } /////////////////////////////////////////////////////////// // This function does any needed initialization on the // rendering context. void InitGL() { GLASS_STATE = FALSE; STONE_STATE = FALSE; EYE_STATE = FALSE; EYE1_STATE = FALSE; NOSE_STATE = FALSE; CAP_STATE = FALSE; CROWN_STATE = FALSE; CLOTHES_STATE = FALSE; SUPERMAN_STATE = FALSE; // GlassCor[3] = {0,0,0}; // StoneCor[3] = {50,0,-50}; //LoadGLTextures("glass.bmp",0); //LoadGLTextures("glass4.bmp",1); // Gray background glEnable(GL_BLEND); // glColor4f(1.0f, 1.0f, 1.0f, 0.3); // Full Brightness. 50% Alpha glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // glEnable(GL_COLOR_MATERIAL); // glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); } void ChangeSize(int w, int h) { GLfloat fAspect; // Prevent a divide by zero if (h == 0) h = 1; Wide = w; High = h; // Set Viewport to window dimensions glViewport(0, 0, w, h); // Calculate aspect ratio of the window fAspect = (GLfloat)w / (GLfloat)h; // Set the perspective coordinate system glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Field of view of 45 degrees, near and far planes 1.0 and 425 // gluPerspective(0.0f, fAspect, 1.0, 425.0); if (w <= h) { glOrtho(-100, 100, -100 * fAspect, 100 * fAspect, -100, 100); } else { glOrtho(-100 * fAspect, 100 * fAspect, -100, 100, -100, 100); } // Modelview matrix reset 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 drawString(const char* str) //屏幕显示字体 { static int isFirstCall = 1; static GLuint lists; if (isFirstCall) { isFirstCall = 0; // 申请MAX_CHAR个连续的显示列表编号 lists = glGenLists(MAX_CHAR); // 把每个字符的绘制命令都装到对应的显示列表中 wglUseFontBitmaps(wglGetCurrentDC(), 0, MAX_CHAR, lists); } // 调用每个字符对应的显示列表,绘制每个字符 for (; *str != '\0'; ++str) { glCallList(lists + *str); } } void selectFont(int size, int charset, const char* face) { HFONT hFont = CreateFontA(size, 0, 0, 0, FW_MEDIUM, 0, 0, 0, charset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, face); HFONT hOldFont = (HFONT)SelectObject(wglGetCurrentDC(), hFont); DeleteObject(hOldFont); } void menu(int index) { switch (select_part) { case Eye: EYE_COLOR = index; break; case Eye1: EYE1_COLOR = index; break; case Nose: NOSE_COLOR = index; break; case Crown: CROWN_COLOR = index; break; case Superman: SUPERMAN_COLOR = index; break; } //此处解决颜色闪烁问题 glutPostRedisplay(); RenderScene(); } 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) { } } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(800, 600); glutCreateWindow("OpenGL"); InitGL(); glutReshapeFunc(ChangeSize); glutMouseFunc(MouseCallback); glutMotionFunc(MouseMoveCallback); glutKeyboardFunc(myKeyboard); glutSpecialFunc(mySpecial); glutDisplayFunc(RenderScene); glutCreateMenu(menu); glutAddMenuEntry("黑色", 0); glutAddMenuEntry("红色", 1); glutAddMenuEntry("绿色", 2); glutAddMenuEntry("蓝色", 3); glutAddMenuEntry("青色", 4); glutAddMenuEntry("紫色", 5); glutAddMenuEntry("黄色", 6); glutAddMenuEntry("白色", 7); glutAttachMenu(GLUT_RIGHT_BUTTON); glutMainLoop(); return 0; }
相关文章推荐
- Linux 进阶1
- JVM监控工具介绍
- linux驱动模板
- Android系统架构
- [Linux]yum开启rpm包缓存
- Nginx的模块开发指南
- Web性能压力测试工具之ApacheBench(ab)详解
- Linux 系统之Systemd
- 桌面虚拟化之IOPS横向测评PVS vs vSAN
- shell脚本学习02-第一章小结
- shell脚本学习01
- k-近邻算法改进约会网站的配对效果
- centos linux 因别名问题引起的麻烦及解决技巧
- Linux系统之UpStart
- Linux---find命令
- Linux cat命令详解
- Cooperation.GTST团队第一周项目总结
- linux 文件删除过程浅析
- linux svn搭建仓库
- linux常用命令