图形学卡通人物绘制以及交互操作

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


再贴张图吧- -

 

posted @ 2017-11-10 14:51  mydddfly  阅读(1309)  评论(0编辑  收藏  举报