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

📄 wave.c

📁 C:Documents and SettingsAdministrator桌面VC++多媒体特效制作百例CHAR20Wave
💻 C
字号:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include "glut.h"#define PI 3.14159265358979323846#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]))GLenum rgb, doubleBuffer;GLint colorIndexes1[3];GLint colorIndexes2[3];GLenum clearMask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;GLenum smooth = GL_FALSE;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,};GLubyte contourTexture2[] = {    255, 255, 255, 255,    255, 127, 127, 127,    255, 127, 127, 127,    255, 127, 127, 127,};static void 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();    }    if (doubleBuffer) {	glutSwapBuffers();    } else {	glFlush();    }}static void SetColorMap(void) {    static float green[3] = {0.2, 1.0, 0.2};    static float red[3] = {1.0, 0.2, 0.2};    float *color, percent;    GLint *indexes, entries, i, j;    entries = glutGet(GLUT_WINDOW_COLORMAP_SIZE);    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]);	    glutSetColor(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]);	    glutSetColor(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.numFacets = 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");	exit(0);    }    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] - pt1[2];		dp2[0] = pt3[0] - pt2[0];		dp2[1] = pt3[1] - pt2[1];		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(0.0, 0.0, 0.0, 0.0);    glShadeModel(GL_FLAT);        glFrontFace(GL_CW);    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 Reshape(int width, int height){    glViewport(0, 0, width, height);}static void Key(unsigned char key, int x, int y){    switch (key) {      case 'c':	contouring++;	if (contouring == 1) {	    static GLfloat map[4] = {0, 0, 20, 0};	    glTexImage2D(GL_TEXTURE_2D, 0, 1, 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);	}	break;      case 's':	smooth = !smooth;	if (smooth) {	    glShadeModel(GL_SMOOTH);	} else {	    glShadeModel(GL_FLAT);	}	break;      case 'l':	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);	    }	}	break;      case 'd':	depth = !depth;	if (depth) {	    glEnable(GL_DEPTH_TEST);	    clearMask |= GL_DEPTH_BUFFER_BIT;	} else {	    glDisable(GL_DEPTH_TEST);	    clearMask &= ~GL_DEPTH_BUFFER_BIT;	}	break;      case ' ':	stepMode = !stepMode;	if (stepMode) {	    glutIdleFunc(0);	    glutDisplayFunc(Animate);	} else {	    glutIdleFunc(Animate);	    glutDisplayFunc(0);	}	break;      case 'n':	if (stepMode) {	    nextFrame = 1;	}	break;      case 'a':	spinMode = !spinMode;	break;      case 27:	exit(0);    }}static void Args(int argc, char **argv){    GLint i;    rgb = GL_TRUE;    doubleBuffer = GL_FALSE;    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");	    } 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");	    } 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");	    } 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");	    } else {		frames = atoi(argv[++i]);	    }	}    }}int main(int argc, char **argv){    GLenum type;    glutInit(&argc, argv);    Args(argc, argv);    type = GLUT_DEPTH;    type |= (rgb) ? GLUT_RGB : GLUT_INDEX;    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;    glutInitDisplayMode(type);    glutInitWindowSize(300, 300);    glutCreateWindow("Wave Demo");    Init();    glutReshapeFunc(Reshape);    glutKeyboardFunc(Key);    glutIdleFunc(Animate);    glutDisplayFunc(Animate);    glutMainLoop();}

⌨️ 快捷键说明

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