http://blog.csdn.net/zhy199336/article/details/45367835
先来个要求吧:
根据OpenGL提供的直线,多边形绘制算法(橡皮筋效果),实现基于鼠标交互的卡通人物设计与绘制。使用颜色填充与反走样技术对卡通人物外貌以及衣着进行绘制。实现对卡通人物轮廓的交互控制,点击鼠标左键可以对人物五官位置进行拖拽移动调整。按“↑”按键能够实现卡通人物绕坐标原点(或指定点)进行旋转。
附加要求:选中其中的一个多边形区域,点击鼠标右键,弹出一个菜单,可以对该区域进行不同颜色的选择。可以设计发型、衣服的模版,当作文件进行存储,可以在窗口最右边设计一个模板库,显示保存的发型与衣服,拖拽到卡通人物上可以为卡通人物进行发型或者衣服的替换。
以下是代码:
#include "stdafx.h" #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> #pragma comment(lib,"glaux.lib") #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 "); 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 "); 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 "); 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_STATE=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 ",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 != ' '; ++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; }
再贴张图吧- -