zoukankan      html  css  js  c++  java
  • 图形学卡通人物绘制以及交互操作

    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;
    	}
    
    


    再贴张图吧- -

  • 相关阅读:
    LeetCode
    LeetCode
    LeetCode
    LeetCode
    codevs 2977 二叉堆练习1x
    codevs 2010 求后序遍历x
    二叉树的序遍历x(内含结构体与非结构体版x)
    医院设置x
    求后序遍历x
    [LightOJ1017]Brush (III)(dp)
  • 原文地址:https://www.cnblogs.com/jukan/p/7814682.html
Copyright © 2011-2022 走看看