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

📄 smooth.c

📁 嵌入式GUI OpenGL源代码。OpenGL是嵌入式开发中常用的一种GUI系统。
💻 C
字号:
/*      smooth.c    Nate Robins, 1998    Model viewer program.  Exercises the glm library. */#include <math.h>#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <stdarg.h>#include <GL/glut.h>#include "gltb.h"#include "glm.h"#include "dirent32.h"#define DATA_DIR "data/"char*      model_file = NULL;		/* name of the obect file */GLuint     model_list = 0;		/* display list for object */GLMmodel*  model;			/* glm model data structure */GLfloat    scale;			/* original scale factor */GLfloat    smoothing_angle = 90.0;	/* smoothing angle */GLfloat    weld_distance = 0.00001;	/* epsilon for welding vertices */GLboolean  facet_normal = GL_FALSE;	/* draw with facet normal? */GLboolean  bounding_box = GL_FALSE;	/* bounding box on? */GLboolean  performance = GL_FALSE;	/* performance counter on? */GLboolean  stats = GL_FALSE;		/* statistics on? */GLuint     material_mode = 0;		/* 0=none, 1=color, 2=material */GLint      entries = 0;			/* entries in model menu */GLdouble   pan_x = 0.0;GLdouble   pan_y = 0.0;GLdouble   pan_z = 0.0;#if defined(_WIN32)#include <sys/timeb.h>#else#include <limits.h>#include <unistd.h>#include <sys/types.h>#include <sys/times.h>#endif#ifndef CLK_TCK
#define CLK_TCK 1000
#endif
floatelapsed(void){    static long begin = 0;    static long finish, difference;#if defined(_WIN32)    static struct timeb tb;    ftime(&tb);    finish = tb.time*1000+tb.millitm;#else    static struct tms tb;    finish = times(&tb);#endif    difference = finish - begin;    begin = finish;    return (float)difference/(float)CLK_TCK;}voidshadowtext(int x, int y, char* s) {    int lines;    char* p;    glDisable(GL_DEPTH_TEST);    glMatrixMode(GL_PROJECTION);    glPushMatrix();    glLoadIdentity();    glOrtho(0, glutGet(GLUT_WINDOW_WIDTH), 	    0, glutGet(GLUT_WINDOW_HEIGHT), -1, 1);    glMatrixMode(GL_MODELVIEW);    glPushMatrix();    glLoadIdentity();    glColor3ub(0, 0, 0);    glRasterPos2i(x+1, y-1);    for(p = s, lines = 0; *p; p++) {	if (*p == '\n') {	    lines++;	    glRasterPos2i(x+1, y-1-(lines*18));	}	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *p);    }    glColor3ub(0, 128, 255);    glRasterPos2i(x, y);    for(p = s, lines = 0; *p; p++) {	if (*p == '\n') {	    lines++;	    glRasterPos2i(x, y-(lines*18));	}	glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *p);    }    glMatrixMode(GL_PROJECTION);    glPopMatrix();    glMatrixMode(GL_MODELVIEW);    glPopMatrix();    glEnable(GL_DEPTH_TEST);}voidlists(void){    GLfloat ambient[] = { 0.2, 0.2, 0.2, 1.0 };    GLfloat diffuse[] = { 0.8, 0.8, 0.8, 1.0 };    GLfloat specular[] = { 0.0, 0.0, 0.0, 1.0 };    GLfloat shininess = 65.0;    glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);    glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);    glMaterialfv(GL_FRONT, GL_SPECULAR, specular);    glMaterialf(GL_FRONT, GL_SHININESS, shininess);    if (model_list)	glDeleteLists(model_list, 1);    /* generate a list */    if (material_mode == 0) { 	if (facet_normal)	    model_list = glmList(model, GLM_FLAT);	else	    model_list = glmList(model, GLM_SMOOTH);    } else if (material_mode == 1) {	if (facet_normal)	    model_list = glmList(model, GLM_FLAT | GLM_COLOR);	else	    model_list = glmList(model, GLM_SMOOTH | GLM_COLOR);    } else if (material_mode == 2) {	if (facet_normal)	    model_list = glmList(model, GLM_FLAT | GLM_MATERIAL);	else	    model_list = glmList(model, GLM_SMOOTH | GLM_MATERIAL);    }}voidinit(void){    gltbInit(GLUT_LEFT_BUTTON);      /* read in the model */    model = glmReadOBJ(model_file);    scale = glmUnitize(model);    glmFacetNormals(model);    glmVertexNormals(model, smoothing_angle);    if (model->nummaterials > 0)	material_mode = 2;    /* create new display lists */    lists();    glEnable(GL_LIGHTING);    glEnable(GL_LIGHT0);    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);    glEnable(GL_DEPTH_TEST);    glEnable(GL_CULL_FACE);}voidreshape(int width, int height){    gltbReshape(width, height);    glViewport(0, 0, width, height);      glMatrixMode(GL_PROJECTION);    glLoadIdentity();    gluPerspective(60.0, (GLfloat)height / (GLfloat)width, 1.0, 128.0);    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();    glTranslatef(0.0, 0.0, -3.0);}#define NUM_FRAMES 5voiddisplay(void){    static char s[256], t[32];    static char* p;    static int frames = 0;    glClearColor(1.0, 1.0, 1.0, 1.0);    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glPushMatrix();    glTranslatef(pan_x, pan_y, 0.0);    gltbMatrix();#if 0   /* glmDraw() performance test */    if (material_mode == 0) { 	if (facet_normal)	    glmDraw(model, GLM_FLAT);	else	    glmDraw(model, GLM_SMOOTH);    } else if (material_mode == 1) {	if (facet_normal)	    glmDraw(model, GLM_FLAT | GLM_COLOR);	else	    glmDraw(model, GLM_SMOOTH | GLM_COLOR);    } else if (material_mode == 2) {	if (facet_normal)	    glmDraw(model, GLM_FLAT | GLM_MATERIAL);	else	    glmDraw(model, GLM_SMOOTH | GLM_MATERIAL);    }#else    glCallList(model_list);#endif    glDisable(GL_LIGHTING);    if (bounding_box) {	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);	glEnable(GL_BLEND);	glEnable(GL_CULL_FACE);	glColor4f(1.0, 0.0, 0.0, 0.25);	glutSolidCube(2.0);	glDisable(GL_BLEND);    }    glPopMatrix();    if (stats) {	/* XXX - this could be done a _whole lot_ faster... */	int height = glutGet(GLUT_WINDOW_HEIGHT);	glColor3ub(0, 0, 0);	sprintf(s, "%s\n%d vertices\n%d triangles\n%d normals\n"		"%d texcoords\n%d groups\n%d materials",	        model->pathname, model->numvertices, model->numtriangles, 		model->numnormals, model->numtexcoords, model->numgroups,		model->nummaterials);	shadowtext(5, height-(5+18*1), s);    }    /* spit out frame rate. */    frames++;    if (frames > NUM_FRAMES) {	sprintf(t, "%g fps", frames/elapsed());	frames = 0;    }    if (performance) {	shadowtext(5, 5, t);    }    glutSwapBuffers();    glEnable(GL_LIGHTING);}voidkeyboard(unsigned char key, int x, int y){    GLint params[2];    switch (key) {    case 'h':	printf("help\n\n");	printf("w         -  Toggle wireframe/filled\n");	printf("c         -  Toggle culling\n");	printf("n         -  Toggle facet/smooth normal\n");	printf("b         -  Toggle bounding box\n");	printf("r         -  Reverse polygon winding\n");	printf("m         -  Toggle color/material/none mode\n");	printf("p         -  Toggle performance indicator\n");	printf("s/S       -  Scale model smaller/larger\n");	printf("t         -  Show model stats\n");	printf("o         -  Weld vertices in model\n");	printf("+/-       -  Increase/decrease smoothing angle\n");	printf("W         -  Write model to file (out.obj)\n");	printf("q/escape  -  Quit\n\n");	break;    case 't':	stats = !stats;	break;    case 'p':	performance = !performance;	break;    case 'm':	material_mode++;	if (material_mode > 2)	    material_mode = 0;	printf("material_mode = %d\n", material_mode);	lists();	break;    case 'd':	glmDelete(model);	init();	lists();	break;    case 'w':	glGetIntegerv(GL_POLYGON_MODE, params);	if (params[0] == GL_FILL)	    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);	else	    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);	break;    case 'c':	if (glIsEnabled(GL_CULL_FACE))	    glDisable(GL_CULL_FACE);	else	    glEnable(GL_CULL_FACE);	break;    case 'b':	bounding_box = !bounding_box;	break;    case 'n':	facet_normal = !facet_normal;	lists();	break;    case 'r':	glmReverseWinding(model);	lists();	break;    case 's':	glmScale(model, 0.8);	lists();	break;    case 'S':	glmScale(model, 1.25);	lists();	break;    case 'o':	printf("Welded %d\n", glmWeld(model, weld_distance));	glmVertexNormals(model, smoothing_angle);	lists();	break;    case 'O':	weld_distance += 0.01;	printf("Weld distance: %.2f\n", weld_distance);	glmWeld(model, weld_distance);	glmFacetNormals(model);	glmVertexNormals(model, smoothing_angle);	lists();	break;    case '-':	smoothing_angle -= 1.0;	printf("Smoothing angle: %.1f\n", smoothing_angle);	glmVertexNormals(model, smoothing_angle);	lists();	break;        case '+':	smoothing_angle += 1.0;	printf("Smoothing angle: %.1f\n", smoothing_angle);	glmVertexNormals(model, smoothing_angle);	lists();	break;        case 'W':	glmScale(model, 1.0/scale);	glmWriteOBJ(model, "out.obj", GLM_SMOOTH | GLM_MATERIAL);	break;    case 'R':	{	    GLuint i;	    GLfloat swap;	    for (i = 1; i <= model->numvertices; i++) {		swap = model->vertices[3 * i + 1];		model->vertices[3 * i + 1] = model->vertices[3 * i + 2];		model->vertices[3 * i + 2] = -swap;	    }	    glmFacetNormals(model);	    lists();	    break;	}    case 27:	exit(0);	break;    }    glutPostRedisplay();}voidmenu(int item){    int i = 0;    DIR* dirp;    char* name;    struct dirent* direntp;    if (item > 0) {	keyboard((unsigned char)item, 0, 0);    } else {	dirp = opendir(DATA_DIR);	while ((direntp = readdir(dirp)) != NULL) {	    if (strstr(direntp->d_name, ".obj")) {		i++;		if (i == -item)		    break;	    }	}	if (!direntp)	    return;	name = (char*)malloc(strlen(direntp->d_name) + strlen(DATA_DIR) + 1);	strcpy(name, DATA_DIR);	strcat(name, direntp->d_name);	model = glmReadOBJ(name);	scale = glmUnitize(model);	glmFacetNormals(model);	glmVertexNormals(model, smoothing_angle);		if (model->nummaterials > 0)	    material_mode = 2;	else	    material_mode = 0;	lists();	free(name);	glutPostRedisplay();    }}static GLint      mouse_state;static GLint      mouse_button;voidmouse(int button, int state, int x, int y){    GLdouble model[4*4];    GLdouble proj[4*4];    GLint view[4];    /* fix for two-button mice -- left mouse + shift = middle mouse */    if (button == GLUT_LEFT_BUTTON && glutGetModifiers() & GLUT_ACTIVE_SHIFT)	button = GLUT_MIDDLE_BUTTON;    gltbMouse(button, state, x, y);    mouse_state = state;    mouse_button = button;    if (state == GLUT_DOWN && button == GLUT_MIDDLE_BUTTON) {	glGetDoublev(GL_MODELVIEW_MATRIX, model);	glGetDoublev(GL_PROJECTION_MATRIX, proj);	glGetIntegerv(GL_VIEWPORT, view);	gluProject((GLdouble)x, (GLdouble)y, 0.0,		   model, proj, view,		   &pan_x, &pan_y, &pan_z);	gluUnProject((GLdouble)x, (GLdouble)y, pan_z,		     model, proj, view,		     &pan_x, &pan_y, &pan_z);	pan_y = -pan_y;    }    glutPostRedisplay();}voidmotion(int x, int y){    GLdouble model[4*4];    GLdouble proj[4*4];    GLint view[4];    gltbMotion(x, y);    if (mouse_state == GLUT_DOWN && mouse_button == GLUT_MIDDLE_BUTTON) {	glGetDoublev(GL_MODELVIEW_MATRIX, model);	glGetDoublev(GL_PROJECTION_MATRIX, proj);	glGetIntegerv(GL_VIEWPORT, view);	gluProject((GLdouble)x, (GLdouble)y, 0.0,		   model, proj, view,		   &pan_x, &pan_y, &pan_z);	gluUnProject((GLdouble)x, (GLdouble)y, pan_z,		     model, proj, view,		     &pan_x, &pan_y, &pan_z);	pan_y = -pan_y;    }    glutPostRedisplay();}intmain(int argc, char** argv){    int buffering = GLUT_DOUBLE;    struct dirent* direntp;    DIR* dirp;    int models;    glutInitWindowSize(512, 512);    glutInit(&argc, argv);    while (--argc) {	if (strcmp(argv[argc], "-sb") == 0)	    buffering = GLUT_SINGLE;	else	    model_file = argv[argc];    }    if (!model_file) {	model_file = "data/dolphins.obj";    }    glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | buffering);    glutCreateWindow("Smooth");      glutReshapeFunc(reshape);    glutDisplayFunc(display);    glutKeyboardFunc(keyboard);    glutMouseFunc(mouse);    glutMotionFunc(motion);    models = glutCreateMenu(menu);    dirp = opendir(DATA_DIR);    if (!dirp) {	fprintf(stderr, "%s: can't open data directory.\n", argv[0]);    } else {	while ((direntp = readdir(dirp)) != NULL) {	    if (strstr(direntp->d_name, ".obj")) {		entries++;		glutAddMenuEntry(direntp->d_name, -entries);	    }	}	closedir(dirp);    }    glutCreateMenu(menu);    glutAddMenuEntry("Smooth", 0);    glutAddMenuEntry("", 0);    glutAddSubMenu("Models", models);    glutAddMenuEntry("", 0);    glutAddMenuEntry("[w]   Toggle wireframe/filled", 'w');    glutAddMenuEntry("[c]   Toggle culling on/off", 'c');    glutAddMenuEntry("[n]   Toggle face/smooth normals", 'n');    glutAddMenuEntry("[b]   Toggle bounding box on/off", 'b');    glutAddMenuEntry("[p]   Toggle frame rate on/off", 'p');    glutAddMenuEntry("[t]   Toggle model statistics", 't');    glutAddMenuEntry("[m]   Toggle color/material/none mode", 'm');    glutAddMenuEntry("[r]   Reverse polygon winding", 'r');    glutAddMenuEntry("[s]   Scale model smaller", 's');    glutAddMenuEntry("[S]   Scale model larger", 'S');    glutAddMenuEntry("[o]   Weld redundant vertices", 'o');    glutAddMenuEntry("[+]   Increase smoothing angle", '+');    glutAddMenuEntry("[-]   Decrease smoothing angle", '-');    glutAddMenuEntry("[W]   Write model to file (out.obj)", 'W');    glutAddMenuEntry("", 0);    glutAddMenuEntry("[Esc] Quit", 27);    glutAttachMenu(GLUT_RIGHT_BUTTON);      init();      glutMainLoop();    return 0;}

⌨️ 快捷键说明

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