⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 飘动的旗.cpp

📁 经典 C++代码
💻 CPP
字号:
#include<windows.h>
#include<stdio.h>
#include<string.h>
#include<stdio.h>
#include<math.h>
#include<GL\glaux.h>
#pragma comment(lib,"opengl32")
#pragma comment(lib,"glu32")
#pragma comment(lib,"glaux")

#define PI 3.141592653589323846
#define GETCOORD(frame,x,y) (&(theMesh.coords[frame*\
	theMesh.numCoords+(x)+(y)*(theMesh.widthX+1)]))
#define GETFACET(frame,x,y) (&(theMesh.facets[frame*\
	theMesh.numFacets+(x)+(y)*theMesh.widthX]))

static void CALLBACK Animate(void);
static void SetColorMap(void);
static void InitMesh(void);
static void InitMaterials(void);
static void Init(void);
static void CALLBACK Resize(int witdth,int height);
static void CALLBACK Key_c(void);
static void CALLBACK Key_s(void);
static void CALLBACK Key_l(void);
static void CALLBACK Key_d(void);
static void CALLBACK Key_SPACE(void);
static void CALLBACK Key_n(void);
static void CALLBACK Key_a(void);
static GLenum Args(int argc,char**argv);

GLenum rgb,doubleBuffer;

GLint colorIndexes1[3];
GLint colorIndexes2[3];
GLenum clearMask=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;

GLenum smooth=GL_TRUE;
GLenum lighting=GL_TRUE;
GLenum depth=GL_TRUE;
GLenum stepMode=GL_FALSE;
GLenum spinMode=GL_FALSE;
GLint contouring=0;

GLint widthX,widthY;
GLint checkerSize;
float height;

GLint frames,curFrame=0,nextFrame=0;

struct facet{
	float color[3];
	float normal[3];
};

struct coord{
	float vertex[3];
	float normal[3];
};

struct mesh{
	GLint widthX,widthY;
	GLint numFacets;
	GLint numCoords;
	GLint frames;
	struct coord* coords;
	struct facet* facets;
}theMesh;

GLubyte contourTexture1[]={
	255,255,255,255,
	255,255,255,255,
	255,255,255,255,
	127,127,127,127,
	255,255,255,255,
	255,127,127,127,
	255,127,127,127,
	255,127,127,127,
};

static void CALLBACK Animate(void)
{
	struct coord* coord;
	struct facet* facet;
	float *lastColor;
	float *thisColor;
	GLint i,j;

	glClear(clearMask);

	if(nextFrame||!stepMode)curFrame++;

	if(curFrame>=theMesh.frames)curFrame=0;

	if((nextFrame||!stepMode)&&spinMode)
		glRotatef(5.0,0.0,0.0,1.0);

	nextFrame=0;

	for(i=0;i<theMesh.widthX;i++)
	{
		glBegin(GL_QUAD_STRIP);
		lastColor=NULL;
		for(j=0;j<theMesh.widthY;j++)
		{
			facet=GETFACET(curFrame,i,j);
			if(!smooth&&lighting)glNormal3fv(facet->normal);

			if(lighting)
			{
				if(rgb)
				{
					thisColor=facet->color;
					glColor3fv(facet->color);
				}
				else
				{
					thisColor=facet->color;
					glMaterialfv(GL_FRONT_AND_BACK,
						GL_COLOR_INDEXES,facet->color);
				}
			}
			else
			{
				if(rgb)
				{
					thisColor=facet->color;
					glColor3fv(facet->color);
				}
				else
				{
					thisColor=facet->color;
					glIndexf(facet->color[1]);
				}
			}
			if(!lastColor||(thisColor[0]!=lastColor[0]&&smooth))
			{
				if(lastColor)
				{
					glEnd();
					glBegin(GL_QUAD_STRIP);
				}
				coord=GETCOORD(curFrame,i,j);
				if(smooth&&lighting)glNormal3fv(coord->normal);
				glVertex3fv(coord->vertex);

				coord=GETCOORD(curFrame,i+1,j);
				if(smooth&&lighting)glNormal3fv(coord->normal);
				glVertex3fv(coord->vertex);
			}
			coord=GETCOORD(curFrame,i,j+1);
			if(smooth&&lighting)glNormal3fv(coord->normal);
			glVertex3fv(coord->vertex);

			coord=GETCOORD(curFrame,i+1,j+1);
			if(smooth&&lighting)glNormal3fv(coord->normal);
			glVertex3fv(coord->vertex);

			lastColor=thisColor;
		}
		glEnd();
	}
	glFlush();
	if(doubleBuffer)auxSwapBuffers();
}

static void SetColorMap(void)
{
	static float green[3]={0.2,1.0,2.0};
	static float red[3]={1.0,0.2,0.2};
	static float *color,percent;
	GLint *indexes,entries,i,j;

	entries=auxGetColorMapSize();

	colorIndexes1[0]=1;
	colorIndexes1[1]=1+(GLint)((entries-1)*0.3);
	colorIndexes1[2]=(GLint)((entries-1)*0.5);
	colorIndexes2[0]=1+(GLint)((entries-1)*0.5);
	colorIndexes2[1]=1+(GLint)((entries-1)*0.8);
	colorIndexes2[2]=entries-1;

	for(i=0;i<2;i++)
	{
		switch(i)
		{
		case 0:
			color=green;
			indexes=colorIndexes1;
			break;
		case 1:
			color=red;
			indexes=colorIndexes2;
			break;
		}

		for(j=indexes[0];j<indexes[1];j++)
		{
			percent=0.2+0.8*(j-indexes[0])/
				(float)(indexes[1]-indexes[0]);
			auxSetOneColor(j,percent*color[0],percent*color[1]
				,percent*color[2]);
		}
		for(j=indexes[1];j<=indexes[2];j++)
		{
			percent=(j-indexes[1])/(float)(indexes[2]-indexes[1]);
			auxSetOneColor(j,percent*(1-color[0])+color[0]
				,percent*(1-color[1])+color[1]
				,percent*(1-color[2])+color[2]);
		}
	}
}

static void InitMesh(void)
{
	struct coord* coord;
	struct facet*facet;
	float dp1[3],dp2[3];
	float *pt1,*pt2,*pt3;
	float angle,d,x,y;
	GLint numFacets,numCoords,frameNum,i,j;

	theMesh.widthX=widthX;
	theMesh.widthY=widthY;
	theMesh.frames=frames;

	numFacets=widthX*widthY;
	numCoords=(widthX+1)*(widthY+1);

	theMesh.numCoords=numCoords;
	theMesh.numCoords=numFacets;

	theMesh.coords=(struct coord*)malloc(frames*numCoords*
		sizeof(struct coord));
	theMesh.facets=(struct facet*)malloc(frames*numFacets*
		sizeof(struct facet));
	if(theMesh.coords==NULL||theMesh.facets==NULL)
	{
		//printf("Out of memory.\n");
		auxQuit();
	}

	for(frameNum=0;frameNum<frames;frameNum++)
	{
		for(i=0;i<=widthX;i++)
		{
			x=i/(float)widthX;
			for(j=0;j<=widthY;j++)
			{
				y=j/(float)widthY;

				d=sqrt(x*x+y*y);
				if(d==0.0)d=0.0001;
				angle=2*PI*d+(2*PI/frames*frameNum);

				coord=GETCOORD(frameNum,i,j);

				coord->vertex[0]=x-0.5;
				coord->vertex[1]=y-0.5;
				coord->vertex[2]=(height-height*d)*cos(angle);

				coord->normal[0]=-(height/d)*x*((1-d)*2*PI*
					sin(angle)+cos(angle));
				coord->normal[1]=-(height/d)*y*((1-d)*2*PI*
					sin(angle)+cos(angle));
				coord->normal[2]=-1;

				d=1.0/sqrt(coord->normal[0]*coord->normal[0]+
					coord->normal[1]*coord->normal[1]+1);
				coord->normal[0]*=d;
				coord->normal[1]*=d;
				coord->normal[2]*=d;
			}
		}
		for(i=0;i<widthX;i++)
		{
			for(j=0;j<widthY;j++)
			{
				facet=GETFACET(frameNum,i,j);
				if(((i/checkerSize)%2)^(j/checkerSize)%2)
				{
					if(rgb)
					{
						facet->color[0]=1.0;
						facet->color[1]=0.2;
						facet->color[2]=0.2;
					}
					else
					{
						facet->color[0]=colorIndexes1[0];
						facet->color[1]=colorIndexes1[1];
						facet->color[2]=colorIndexes1[2];
					}
				}
				else
				{
					if(rgb)
					{
						facet->color[0]=0.2;
						facet->color[1]=1.0;
						facet->color[2]=0.2;
					}
					else
					{
						facet->color[0]=colorIndexes2[0];
						facet->color[1]=colorIndexes2[1];
						facet->color[2]=colorIndexes2[2];
					}
				}
				pt1=GETCOORD(frameNum,i,j)->vertex;
				pt2=GETCOORD(frameNum,i,j+1)->vertex;
				pt3=GETCOORD(frameNum,i+1,j+1)->vertex;

				dp1[0]=pt2[0]-pt1[0];
				dp1[1]=pt2[1]-pt1[1];
				dp1[2]=pt2[2]-pt2[2];

				dp2[0]=pt3[0]-pt2[2];
				dp2[1]=pt3[1]-pt2[2];
				dp2[2]=pt3[2]-pt2[2];

				facet->normal[0]=dp1[1]*dp2[2]-dp1[2]*dp2[1];
				facet->normal[1]=dp1[2]*dp2[0]-dp1[0]*dp2[2];
				facet->normal[2]=dp1[0]*dp2[1]-dp1[1]*dp2[0];

				d=1.0/sqrt(facet->normal[0]*facet->normal[0]+
					facet->normal[1]*facet->normal[1]+
					facet->normal[2]*facet->normal[2]);

				facet->normal[0]*=d;
				facet->normal[1]*=d;
				facet->normal[2]*=d;
			}
		}
	}
}

static void InitMaterials(void)
{
	static float ambient[]={0.1,0.1,0.1,1.0};
	static float diffuse[]={0.5,1.0,1.0,1.0};
	static float position[]={90.0,90.0,150.0,0.0};
	static float front_mat_shininess[]={60.0};
	static float front_mat_specular[]={0.2,0.2,0.2,1.0};
	static float front_mat_diffuse[]={0.5,0.28,0.38,1.0};
	static float back_mat_shininess[]={60.0};
	static float back_mat_specular[]={0.5,0.5,0.2,1.0};
	static float back_mat_diffuse[]={1.0,1.0,0.2,1.0};
	static float lmodel_ambient[]={1.0,1.0,1.0,1.0};
	static float lmodel_twoside[]={GL_TRUE};

	glMatrixMode(GL_PROJECTION);
	gluPerspective(450,1.0,0.5,10.0);

	glLightfv(GL_LIGHT0,GL_AMBIENT,ambient);
	glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse);
	glLightfv(GL_LIGHT0,GL_POSITION,position);
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient);
	glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE,lmodel_twoside);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);

	glMaterialfv(GL_FRONT,GL_SHININESS,front_mat_shininess);
	glMaterialfv(GL_FRONT,GL_SPECULAR,front_mat_specular);
	glMaterialfv(GL_FRONT,GL_DIFFUSE,front_mat_diffuse);
	glMaterialfv(GL_BACK,GL_SHININESS,back_mat_shininess);
	glMaterialfv(GL_BACK,GL_SPECULAR,back_mat_specular);
	glMaterialfv(GL_BACK,GL_DIFFUSE,back_mat_diffuse);
	if(rgb)glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);

	if(rgb)glEnable(GL_COLOR_MATERIAL);
	else SetColorMap();
}

static void InitTexture(void)
{
	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S
		,GL_REPEAT);
	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T
		,GL_REPEAT);
	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER
		,GL_NEAREST);
	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER
		,GL_NEAREST);
	glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE
		,GL_MODULATE);
}

static void Init(void)
{
	glClearColor(1.0,1.0,1.0,0.0);
	glShadeModel(GL_SMOOTH);
	glFrontFace(GL_CW);
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_DEPTH_TEST);

	InitMaterials();
	InitTexture();
	InitMesh();

	glMatrixMode(GL_MODELVIEW);
	glTranslatef(0.0,0.4,-1.8);
	glScalef(2.0,2.0,2.0);
	glRotatef(-35.0,1.0,0.0,0.0);
	glRotatef(35.0,0.0,0.0,1.0);
}

static void CALLBACK Resize(int width,int height)
{
	glViewport(0,0,(GLint)width,(GLint)height);
}

static void CALLBACK Key_c(void)
{
	contouring++;
	if(contouring==1)
	{
		static GLfloat map[4]={0,0,20,0};

		glTexImage2D(GL_TEXTURE_2D,0,3,4,4,0,GL_LUMINANCE,
			GL_UNSIGNED_BYTE,(GLvoid*)contourTexture1);
		glTexGeni(GL_S,GL_TEXTURE_GEN_MODE
			,GL_OBJECT_LINEAR);
		glTexGeni(GL_T,GL_TEXTURE_GEN_MODE
			,GL_OBJECT_LINEAR);
		glTexGenfv(GL_S,GL_OBJECT_PLANE,map);
		glTexGenfv(GL_T,GL_OBJECT_PLANE,map);
		glEnable(GL_TEXTURE_2D);
		glEnable(GL_TEXTURE_GEN_S);
		glEnable(GL_TEXTURE_GEN_T);
	}
	else if(contouring==2)
	{
		static GLfloat map[4]={0,0,20,0};

		glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
		glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
		glPushMatrix();
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glTexGenfv(GL_S,GL_EYE_PLANE,map);
		glTexGenfv(GL_T,GL_EYE_PLANE,map);
		glPopMatrix();
	}
	else
	{
		contouring=0;
		glDisable(GL_TEXTURE_GEN_S);
		glDisable(GL_TEXTURE_GEN_T);
		glDisable(GL_TEXTURE_2D);
	}
}

static void CALLBACK Key_s(void)
{
	smooth=!smooth;
	if(smooth)glShadeModel(GL_SMOOTH);
	else glShadeModel(GL_FLAT);
}

static void CALLBACK Key_l(void)
{
	lighting=!lighting;
	if(lighting)
	{
		glEnable(GL_LIGHTING);
		glEnable(GL_LIGHT0);
		if(rgb)glEnable(GL_COLOR_MATERIAL);
	}
	else
	{
		glDisable(GL_LIGHTING);
		glDisable(GL_LIGHT0);
		if(rgb)glDisable(GL_COLOR_MATERIAL);
	}
}

static void CALLBACK Key_d(void)
{
	depth=!depth;
	if(depth)
	{
		glEnable(GL_DEPTH_TEST);
		clearMask|=GL_DEPTH_BUFFER_BIT;
	}
	else
	{
		glDisable(GL_DEPTH_TEST);
		clearMask&=~GL_DEPTH_BUFFER_BIT;
	}
}

static void CALLBACK Key_SPACE(void)
{
	stepMode=!stepMode;
	if(stepMode)
	{
		auxIdleFunc(0);
		/* tkDisplayFunc(Animate);*/
	}
	else
	{
		auxIdleFunc(Animate);
		/* tkDisplayFunc(0);*/
	}
}

static void CALLBACK Key_n(void)
{
	if(stepMode)nextFrame=1;
}

static void CALLBACK Key_a(void)
{
	spinMode=!spinMode;
}

static GLenum Args(int argc,char **argv)
{
	GLint i;

	rgb=GL_TRUE;
	doubleBuffer=GL_TRUE;

	frames=10;
	widthX=10;
	widthY=10;
	checkerSize=2;
	height=0.2;

	for(i=1;i<argc;i++)
	{
		if(strcmp(argv[i],"-ci")==0)rgb=GL_FALSE;
		else if(strcmp(argv[i],"-rgb")==0)rgb=GL_TRUE;
		else if(strcmp(argv[i],"-sb")==0)doubleBuffer=GL_FALSE;
		else if(strcmp(argv[i],"-db")==0)doubleBuffer=GL_TRUE;
		else if(strcmp(argv[i],"-grid")==0)
		{
			if(i+2>=argc||argv[i+1][0]=='-'||argv[i+2][0]=='-')
			{
				//printf("-grid(No numbers).\n");
				return GL_FALSE;
			}
			else
			{
				widthX=atoi(argv[++i]);
				widthY=atoi(argv[++i]);
			}
		}
		else if(strcmp(argv[i],"-size")==0)
		{
			if(i+1>=argc||argv[i+1][0]=='-')
			{
				//printf("-checker(No number).\n");
				return GL_FALSE;
			}
			else
			{
				checkerSize=atoi(argv[++i]);
			}
		}
		else if(strcmp(argv[i],"-wave")==0)
		{
			if(i+1>=argc||argv[i+1][0]=='-')
			{
				//printf("-wave(No number).\n");
				return GL_FALSE;
			}
			else
			{
				height=atof(argv[++i]);
			}
		}
		else if(strcmp(argv[i],"-frames")==0)
		{
			if(i+1>=argc||argv[i+1][0]=='-')
			{
				//printf("-frames(No number).\n");
				return GL_FALSE;
			}
			else
			{
				frames=atoi(argv[++i]);
			}
		}
		else
		{
			//printf("%s(Bad option).\n",argv[i]);
			return GL_FALSE;
		}
	}
	return GL_TRUE;
}

void main(int argc,char **argv)
{
	GLenum type;

	if(Args(argc,argv)==GL_FALSE)auxQuit();

	auxInitPosition(0,0,300,300);

	type=AUX_DEPTH16;
	type|=(rgb)?AUX_RGB:AUX_INDEX;
	type|=(doubleBuffer)?AUX_DOUBLE:AUX_SINGLE;

	auxInitDisplayMode(type);

	if(auxInitWindow("飘扬的旗帜")==GL_FALSE)auxQuit();

	Init();

	auxExposeFunc((AUXEXPOSEPROC)Resize);
	auxReshapeFunc((AUXRESHAPEPROC)Resize);
	auxKeyFunc(AUX_c,Key_c);
	auxKeyFunc(AUX_s,Key_s);
	auxKeyFunc(AUX_l,Key_l);
	auxKeyFunc(AUX_d,Key_d);
	auxKeyFunc(AUX_SPACE,Key_SPACE);
	auxKeyFunc(AUX_n,Key_n);
	auxKeyFunc(AUX_a,Key_a);
	auxIdleFunc(Animate);
	auxMainLoop(Animate);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -