📄 glm.c
字号:
}/* glmWriteOBJ: Writes a model description in Wavefront .OBJ format to * a file. * * model - initialized GLMmodel structure * filename - name of the file to write the Wavefront .OBJ format data to * mode - a bitwise or of values describing what is written to the file * GLM_NONE - render with only vertices * GLM_FLAT - render with facet normals * GLM_SMOOTH - render with vertex normals * GLM_TEXTURE - render with texture coords * GLM_COLOR - render with colors (color material) * GLM_MATERIAL - render with materials * GLM_COLOR and GLM_MATERIAL should not both be specified. * GLM_FLAT and GLM_SMOOTH should not both be specified. */GLvoidglmWriteOBJ(GLMmodel* model, char* filename, GLuint mode){ GLuint i; FILE* file; GLMgroup* group; assert(model); /* do a bit of warning */ if (mode & GLM_FLAT && !model->facetnorms) { printf("glmWriteOBJ() warning: flat normal output requested " "with no facet normals defined.\n"); mode &= ~GLM_FLAT; } if (mode & GLM_SMOOTH && !model->normals) { printf("glmWriteOBJ() warning: smooth normal output requested " "with no normals defined.\n"); mode &= ~GLM_SMOOTH; } if (mode & GLM_TEXTURE && !model->texcoords) { printf("glmWriteOBJ() warning: texture coordinate output requested " "with no texture coordinates defined.\n"); mode &= ~GLM_TEXTURE; } if (mode & GLM_FLAT && mode & GLM_SMOOTH) { printf("glmWriteOBJ() warning: flat normal output requested " "and smooth normal output requested (using smooth).\n"); mode &= ~GLM_FLAT; } /* open the file */ file = fopen(filename, "w"); if (!file) { fprintf(stderr, "glmWriteOBJ() failed: can't open file \"%s\" to write.\n", filename); exit(1); } /* spit out a header */ fprintf(file, "# \n"); fprintf(file, "# Wavefront OBJ generated by GLM library\n"); fprintf(file, "# \n"); fprintf(file, "# GLM library copyright (C) 1997 by Nate Robins\n"); fprintf(file, "# email: ndr@pobox.com\n"); fprintf(file, "# www: http://www.pobox.com/~ndr\n"); fprintf(file, "# \n"); if (mode & GLM_MATERIAL && model->mtllibname) { fprintf(file, "\nmtllib %s\n\n", model->mtllibname); _glmWriteMTL(model, filename, model->mtllibname); } /* spit out the vertices */ fprintf(file, "\n"); fprintf(file, "# %d vertices\n", model->numvertices); for (i = 1; i <= model->numvertices; i++) { fprintf(file, "v %f %f %f\n", model->vertices[3 * i + 0], model->vertices[3 * i + 1], model->vertices[3 * i + 2]); } /* spit out the smooth/flat normals */ if (mode & GLM_SMOOTH) { fprintf(file, "\n"); fprintf(file, "# %d normals\n", model->numnormals); for (i = 1; i <= model->numnormals; i++) { fprintf(file, "vn %f %f %f\n", model->normals[3 * i + 0], model->normals[3 * i + 1], model->normals[3 * i + 2]); } } else if (mode & GLM_FLAT) { fprintf(file, "\n"); fprintf(file, "# %d normals\n", model->numfacetnorms); for (i = 1; i <= model->numnormals; i++) { fprintf(file, "vn %f %f %f\n", model->facetnorms[3 * i + 0], model->facetnorms[3 * i + 1], model->facetnorms[3 * i + 2]); } } /* spit out the texture coordinates */ if (mode & GLM_TEXTURE) { fprintf(file, "\n"); fprintf(file, "# %d texcoords\n", model->numtexcoords); for (i = 1; i <= model->numtexcoords; i++) { fprintf(file, "vt %f %f\n", model->texcoords[2 * i + 0], model->texcoords[2 * i + 1]); } } fprintf(file, "\n"); fprintf(file, "# %d groups\n", model->numgroups); fprintf(file, "# %d faces (triangles)\n", model->numtriangles); fprintf(file, "\n"); group = model->groups; while(group) { fprintf(file, "g %s\n", group->name); if (mode & GLM_MATERIAL) fprintf(file, "usemtl %s\n", model->materials[group->material].name); for (i = 0; i < group->numtriangles; i++) { if (mode & GLM_SMOOTH && mode & GLM_TEXTURE) { fprintf(file, "f %d/%d/%d %d/%d/%d %d/%d/%d\n", T(group->triangles[i]).vindices[0], T(group->triangles[i]).nindices[0], T(group->triangles[i]).tindices[0], T(group->triangles[i]).vindices[1], T(group->triangles[i]).nindices[1], T(group->triangles[i]).tindices[1], T(group->triangles[i]).vindices[2], T(group->triangles[i]).nindices[2], T(group->triangles[i]).tindices[2]); } else if (mode & GLM_FLAT && mode & GLM_TEXTURE) { fprintf(file, "f %d/%d %d/%d %d/%d\n", T(group->triangles[i]).vindices[0], T(group->triangles[i]).findex, T(group->triangles[i]).vindices[1], T(group->triangles[i]).findex, T(group->triangles[i]).vindices[2], T(group->triangles[i]).findex); } else if (mode & GLM_TEXTURE) { fprintf(file, "f %d/%d %d/%d %d/%d\n", T(group->triangles[i]).vindices[0], T(group->triangles[i]).tindices[0], T(group->triangles[i]).vindices[1], T(group->triangles[i]).tindices[1], T(group->triangles[i]).vindices[2], T(group->triangles[i]).tindices[2]); } else if (mode & GLM_SMOOTH) { fprintf(file, "f %d//%d %d//%d %d//%d\n", T(group->triangles[i]).vindices[0], T(group->triangles[i]).nindices[0], T(group->triangles[i]).vindices[1], T(group->triangles[i]).nindices[1], T(group->triangles[i]).vindices[2], T(group->triangles[i]).nindices[2]); } else if (mode & GLM_FLAT) { fprintf(file, "f %d//%d %d//%d %d//%d\n", T(group->triangles[i]).vindices[0], T(group->triangles[i]).findex, T(group->triangles[i]).vindices[1], T(group->triangles[i]).findex, T(group->triangles[i]).vindices[2], T(group->triangles[i]).findex); } else { fprintf(file, "f %d %d %d\n", T(group->triangles[i]).vindices[0], T(group->triangles[i]).vindices[1], T(group->triangles[i]).vindices[2]); } } fprintf(file, "\n"); group = group->next; } fclose(file);}/* glmDraw: Renders the model to the current OpenGL context using the * mode specified. * * model - initialized GLMmodel structure * mode - a bitwise OR of values describing what is to be rendered. * GLM_NONE - render with only vertices * GLM_FLAT - render with facet normals * GLM_SMOOTH - render with vertex normals * GLM_TEXTURE - render with texture coords * GLM_COLOR - render with colors (color material) * GLM_MATERIAL - render with materials * GLM_COLOR and GLM_MATERIAL should not both be specified. * GLM_FLAT and GLM_SMOOTH should not both be specified. */GLvoidglmDraw(GLMmodel* model, GLuint mode){ GLuint i; GLMgroup* group; assert(model); assert(model->vertices); /* do a bit of warning */ if (mode & GLM_FLAT && !model->facetnorms) { printf("glmDraw() warning: flat render mode requested " "with no facet normals defined.\n"); mode &= ~GLM_FLAT; } if (mode & GLM_SMOOTH && !model->normals) { printf("glmDraw() warning: smooth render mode requested " "with no normals defined.\n"); mode &= ~GLM_SMOOTH; } if (mode & GLM_TEXTURE && !model->texcoords) { printf("glmDraw() warning: texture render mode requested " "with no texture coordinates defined.\n"); mode &= ~GLM_TEXTURE; } if (mode & GLM_FLAT && mode & GLM_SMOOTH) { printf("glmDraw() warning: flat render mode requested " "and smooth render mode requested (using smooth).\n"); mode &= ~GLM_FLAT; } if (mode & GLM_COLOR && !model->materials) { printf("glmDraw() warning: color render mode requested " "with no materials defined.\n"); mode &= ~GLM_COLOR; } if (mode & GLM_MATERIAL && !model->materials) { printf("glmDraw() warning: material render mode requested " "with no materials defined.\n"); mode &= ~GLM_MATERIAL; } if (mode & GLM_COLOR && mode & GLM_MATERIAL) { printf("glmDraw() warning: color and material render mode requested " "using only material mode\n"); mode &= ~GLM_COLOR; } if (mode & GLM_COLOR) glEnable(GL_COLOR_MATERIAL); if (mode & GLM_MATERIAL) glDisable(GL_COLOR_MATERIAL); glPushMatrix(); glTranslatef(model->position[0], model->position[1], model->position[2]); glBegin(GL_TRIANGLES); group = model->groups; while (group) { if (mode & GLM_MATERIAL) { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, model->materials[group->material].ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, model->materials[group->material].diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, model->materials[group->material].specular); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, model->materials[group->material].shininess); } if (mode & GLM_COLOR) { glColor3fv(model->materials[group->material].diffuse); } for (i = 0; i < group->numtriangles; i++) { if (mode & GLM_FLAT) glNormal3fv(&model->facetnorms[3 * T(group->triangles[i]).findex]); if (mode & GLM_SMOOTH) glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[0]]); if (mode & GLM_TEXTURE) glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[0]]); glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[0]]);#if 0 printf("%f %f %f\n", model->vertices[3 * T(group->triangles[i]).vindices[0] + X], model->vertices[3 * T(group->triangles[i]).vindices[0] + Y], model->vertices[3 * T(group->triangles[i]).vindices[0] + Z]);#endif if (mode & GLM_SMOOTH) glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[1]]); if (mode & GLM_TEXTURE) glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[1]]); glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[1]]);#if 0 printf("%f %f %f\n", model->vertices[3 * T(group->triangles[i]).vindices[1] + X], model->vertices[3 * T(group->triangles[i]).vindices[1] + Y], model->vertices[3 * T(group->triangles[i]).vindices[1] + Z]);#endif if (mode & GLM_SMOOTH) glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[2]]); if (mode & GLM_TEXTURE) glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[2]]); glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[2]]);#if 0 printf("%f %f %f\n", model->vertices[3 * T(group->triangles[i]).vindices[2] + X], model->vertices[3 * T(group->triangles[i]).vindices[2] + Y], model->vertices[3 * T(group->triangles[i]).vindices[2] + Z]);#endif } group = group->next; } glEnd(); glPopMatrix();}/* glmList: Generates and returns a display list for the model using * the mode specified. * * model - initialized GLMmodel structure * mode - a bitwise OR of values describing what is to be rendered. * GLM_NONE - render with only vertices * GLM_FLAT - render with facet normals * GLM_SMOOTH - render with vertex normals * GLM_TEXTURE - render with texture coords * GLM_COLOR - render with colors (color material) * GLM_MATERIAL - render with materials * GLM_COLOR and GLM_MATERIAL should not both be specified. * GLM_FLAT and GLM_SMOOTH should not both be specified. */GLuintglmList(GLMmodel* model, GLuint mode){ GLuint list; list = glGenLists(1); glNewList(list, GL_COMPILE); glmDraw(model, mode); glEndList(); return list;}/* glmWeld: eliminate (weld) vectors that are within an epsilon of * each other. * * model - initialized GLMmodel structure * epsilon - maximum difference between vertices * ( 0.00001 is a good start for a unitized model) * */GLvoidglmWeld(GLMmodel* model, GLfloat epsilon){ GLfloat* vectors; GLfloat* copies; GLuint numvectors; GLuint i; /* vertices */ numvectors = model->numvertices; vectors = model->vertices; copies = _glmWeldVectors(vectors, &numvectors, epsilon); printf("glmWeld(): %d redundant vertices.\n", model->numvertices - numvectors - 1); for (i = 0; i < model->numtriangles; i++) { T(i).vindices[0] = (GLuint)vectors[3 * T(i).vindices[0] + 0]; T(i).vindices[1] = (GLuint)vectors[3 * T(i).vindices[1] + 0]; T(i).vindices[2] = (GLuint)vectors[3 * T(i).vindices[2] + 0]; } /* free space for old vertices */ free(vectors); /* allocate space for the new vertices */ model->numvertices = numvectors; model->vertices = (GLfloat*)malloc(sizeof(GLfloat) * 3 * (model->numvertices + 1)); /* copy the optimized vertices into the actual vertex list */ for (i = 1; i <= model->numvertices; i++) { model->vertices[3 * i + 0] = copies[3 * i + 0]; model->vertices[3 * i + 1] = copies[3 * i + 1]; model->vertices[3 * i + 2] = copies[3 * i + 2]; } free(copies);}#if 0 /* normals */ if (model->numnormals) { numvectors = model->numnormals; vectors = model->normals; copies = _glmOptimizeVectors(vectors, &numvectors); printf("glmOptimize(): %d redundant normals.\n", model->numnormals - numvectors); for (i = 0; i < model->numtriangles; i++) { T(i).nindices[0] = (GLuint)vectors[3 * T(i).nindices[0] + 0]; T(i).nindices[1] = (GLuint)vectors[3 * T(i).nindices[1] + 0]; T(i).nindices[2] = (GLuint)vectors[3 * T(i).nindices[2] + 0]; } /* free space for old normals */ free(vectors); /* allocate space for the new normals */ model->numnormals = numvectors; model->normals = (GLfloat*)malloc(sizeof(GLfloat) * 3 * (model->numnormals + 1)); /* copy the optimized vertices into the actual vertex list */ for (i = 1; i <= model->numnormals; i++) { model->normals[3 * i + 0] = copies[3 * i + 0]; model->normals[3 * i + 1] = copies[3 * i + 1]; model->normals[3 * i + 2] = copies[3 * i + 2]; } free(copies); } /* texcoords */ if (model->numtexcoords) { numvectors = model->numtexcoords; vectors = model->texcoords; copies = _glmOptimizeVectors(vectors, &numvectors); printf("glmOptimize(): %d redundant texcoords.\n", model->numtexcoords - numvectors); for (i = 0; i < model->numtriangles; i++) { for (j = 0; j < 3; j++) { T(i).tindices[j] = (GLuint)vectors[3 * T(i).tindices[j] + 0]; } } /* free space for old texcoords */ free(vectors); /* allocate space for the new texcoords */ model->numtexcoords = numvectors; model->texcoords = (GLfloat*)malloc(sizeof(GLfloat) * 2 * (model->numtexcoords + 1)); /* copy the optimized vertices into the actual vertex list */ for (i = 1; i <= model->numtexcoords; i++) { model->texcoords[2 * i + 0] = copies[2 * i + 0]; model->texcoords[2 * i + 1] = copies[2 * i + 1]; } free(copies); }#endif#if 0 /* look for unused vertices */ /* look for unused normals */ /* look for unused texcoords */ for (i = 1; i <= model->numvertices; i++) { for (j = 0; j < model->numtriangles; i++) { if (T(j).vindices[0] == i || T(j).vindices[1] == i || T(j).vindices[1] == i) break; } }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -