📄 glm.c
字号:
} free(normals);}/* glmLinearTexture: Generates texture coordinates according to a * linear projection of the texture map. It generates these by * linearly mapping the vertices onto a square. * * model - pointer to initialized GLMmodel structure */GLvoidglmLinearTexture(GLMmodel* model){ GLMgroup *group; GLfloat dimensions[3]; GLfloat x, y, scalefactor; GLuint i; assert(model); if (model->texcoords) free(model->texcoords); model->numtexcoords = model->numvertices; model->texcoords=(GLfloat*)malloc(sizeof(GLfloat)*2*(model->numtexcoords+1)); glmDimensions(model, dimensions); scalefactor = 2.0 / glmAbs(glmMax(glmMax(dimensions[0], dimensions[1]), dimensions[2])); /* do the calculations */ for(i = 1; i <= model->numvertices; i++) { x = model->vertices[3 * i + 0] * scalefactor; y = model->vertices[3 * i + 2] * scalefactor; model->texcoords[2 * i + 0] = (x + 1.0) / 2.0; model->texcoords[2 * i + 1] = (y + 1.0) / 2.0; } /* go through and put texture coordinate indices in all the triangles */ group = model->groups; while(group) { for(i = 0; i < group->numtriangles; i++) { T(group->triangles[i]).tindices[0] = T(group->triangles[i]).vindices[0]; T(group->triangles[i]).tindices[1] = T(group->triangles[i]).vindices[1]; T(group->triangles[i]).tindices[2] = T(group->triangles[i]).vindices[2]; } group = group->next; } #if 0 printf("glmLinearTexture(): generated %d linear texture coordinates\n", model->numtexcoords);#endif}/* glmSpheremapTexture: Generates texture coordinates according to a * spherical projection of the texture map. Sometimes referred to as * spheremap, or reflection map texture coordinates. It generates * these by using the normal to calculate where that vertex would map * onto a sphere. Since it is impossible to map something flat * perfectly onto something spherical, there is distortion at the * poles. This particular implementation causes the poles along the X * axis to be distorted. * * model - pointer to initialized GLMmodel structure */GLvoidglmSpheremapTexture(GLMmodel* model){ GLMgroup* group; GLfloat theta, phi, rho, x, y, z, r; GLuint i; assert(model); assert(model->normals); if (model->texcoords) free(model->texcoords); model->numtexcoords = model->numnormals; model->texcoords=(GLfloat*)malloc(sizeof(GLfloat)*2*(model->numtexcoords+1)); for (i = 1; i <= model->numnormals; i++) { z = model->normals[3 * i + 0]; /* re-arrange for pole distortion */ y = model->normals[3 * i + 1]; x = model->normals[3 * i + 2]; r = sqrt((x * x) + (y * y)); rho = sqrt((r * r) + (z * z)); if(r == 0.0) { theta = 0.0; phi = 0.0; } else { if(z == 0.0) phi = 3.14159265 / 2.0; else phi = acos(z / rho); if(y == 0.0) theta = 3.141592365 / 2.0; else theta = asin(y / r) + (3.14159265 / 2.0); } model->texcoords[2 * i + 0] = theta / 3.14159265; model->texcoords[2 * i + 1] = phi / 3.14159265; } /* go through and put texcoord indices in all the triangles */ group = model->groups; while(group) { for (i = 0; i < group->numtriangles; i++) { T(group->triangles[i]).tindices[0] = T(group->triangles[i]).nindices[0]; T(group->triangles[i]).tindices[1] = T(group->triangles[i]).nindices[1]; T(group->triangles[i]).tindices[2] = T(group->triangles[i]).nindices[2]; } group = group->next; }}/* glmDelete: Deletes a GLMmodel structure. * * model - initialized GLMmodel structure */GLvoidglmDelete(GLMmodel* model){ GLMgroup* group; GLuint i; assert(model); if (model->pathname) free(model->pathname); if (model->mtllibname) free(model->mtllibname); if (model->vertices) free(model->vertices); if (model->normals) free(model->normals); if (model->texcoords) free(model->texcoords); if (model->facetnorms) free(model->facetnorms); if (model->triangles) free(model->triangles); if (model->materials) { for (i = 0; i < model->nummaterials; i++) free(model->materials[i].name); } free(model->materials); while(model->groups) { group = model->groups; model->groups = model->groups->next; free(group->name); free(group->triangles); free(group); } free(model);}/* glmReadOBJ: Reads a model description from a Wavefront .OBJ file. * Returns a pointer to the created object which should be free'd with * glmDelete(). * * filename - name of the file containing the Wavefront .OBJ format data. */GLMmodel* glmReadOBJ(char* filename){ GLMmodel* model; FILE* file; /* open the file */ file = fopen(filename, "r"); if (!file) { fprintf(stderr, "glmReadOBJ() failed: can't open data file \"%s\".\n", filename); exit(1); } /* allocate a new model */ model = (GLMmodel*)malloc(sizeof(GLMmodel)); model->pathname = strdup(filename); model->mtllibname = NULL; model->numvertices = 0; model->vertices = NULL; model->numnormals = 0; model->normals = NULL; model->numtexcoords = 0; model->texcoords = NULL; model->numfacetnorms = 0; model->facetnorms = NULL; model->numtriangles = 0; model->triangles = NULL; model->nummaterials = 0; model->materials = NULL; model->numgroups = 0; model->groups = NULL; model->position[0] = 0.0; model->position[1] = 0.0; model->position[2] = 0.0; /* make a first pass through the file to get a count of the number of vertices, normals, texcoords & triangles */ glmFirstPass(model, file); /* allocate memory */ model->vertices = (GLfloat*)malloc(sizeof(GLfloat) * 3 * (model->numvertices + 1)); model->triangles = (GLMtriangle*)malloc(sizeof(GLMtriangle) * model->numtriangles); if (model->numnormals) { model->normals = (GLfloat*)malloc(sizeof(GLfloat) * 3 * (model->numnormals + 1)); } if (model->numtexcoords) { model->texcoords = (GLfloat*)malloc(sizeof(GLfloat) * 2 * (model->numtexcoords + 1)); } /* rewind to beginning of file and read in the data this pass */ rewind(file); glmSecondPass(model, file); /* close the file */ fclose(file); return model;}/* 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; } if (mode & GLM_COLOR && !model->materials) { printf("glmWriteOBJ() warning: color output requested " "with no colors (materials) defined.\n"); mode &= ~GLM_COLOR; } if (mode & GLM_MATERIAL && !model->materials) { printf("glmWriteOBJ() warning: material output requested " "with no materials defined.\n"); mode &= ~GLM_MATERIAL; } if (mode & GLM_COLOR && mode & GLM_MATERIAL) { printf("glmWriteOBJ() warning: color and material output requested " "outputting only materials.\n"); mode &= ~GLM_COLOR; } /* 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\n"); fprintf(file, "# Nate Robins\n"); fprintf(file, "# ndr@pobox.com\n"); fprintf(file, "# 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->texcoords); 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -