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

📄 glm.c

📁 嵌入式GUI OpenGL源代码。OpenGL是嵌入式开发中常用的一种GUI系统。
💻 C
📖 第 1 页 / 共 4 页
字号:
  /* reverse facet normals */  for (i = 1; i <= model->numfacetnorms; i++) {    model->facetnorms[3 * i + 0] = -model->facetnorms[3 * i + 0];    model->facetnorms[3 * i + 1] = -model->facetnorms[3 * i + 1];    model->facetnorms[3 * i + 2] = -model->facetnorms[3 * i + 2];  }  /* reverse vertex normals */  for (i = 1; i <= model->numnormals; i++) {    model->normals[3 * i + 0] = -model->normals[3 * i + 0];    model->normals[3 * i + 1] = -model->normals[3 * i + 1];    model->normals[3 * i + 2] = -model->normals[3 * i + 2];  }}/* glmFacetNormals: Generates facet normals for a model (by taking the * cross product of the two vectors derived from the sides of each * triangle).  Assumes a counter-clockwise winding. * * model - initialized GLMmodel structure */GLvoidglmFacetNormals(GLMmodel* model){  GLuint  i;  GLfloat u[3];  GLfloat v[3];    assert(model);  assert(model->vertices);  /* clobber any old facetnormals */  if (model->facetnorms)    free(model->facetnorms);  /* allocate memory for the new facet normals */  model->numfacetnorms = model->numtriangles;  model->facetnorms = (GLfloat*)malloc(sizeof(GLfloat) *				       3 * (model->numfacetnorms + 1));  for (i = 0; i < model->numtriangles; i++) {    model->triangles[i].findex = i+1;    u[0] = model->vertices[3 * T(i).vindices[1] + 0] -           model->vertices[3 * T(i).vindices[0] + 0];    u[1] = model->vertices[3 * T(i).vindices[1] + 1] -           model->vertices[3 * T(i).vindices[0] + 1];    u[2] = model->vertices[3 * T(i).vindices[1] + 2] -           model->vertices[3 * T(i).vindices[0] + 2];    v[0] = model->vertices[3 * T(i).vindices[2] + 0] -           model->vertices[3 * T(i).vindices[0] + 0];    v[1] = model->vertices[3 * T(i).vindices[2] + 1] -           model->vertices[3 * T(i).vindices[0] + 1];    v[2] = model->vertices[3 * T(i).vindices[2] + 2] -           model->vertices[3 * T(i).vindices[0] + 2];    glmCross(u, v, &model->facetnorms[3 * (i+1)]);    glmNormalize(&model->facetnorms[3 * (i+1)]);  }}/* glmVertexNormals: Generates smooth vertex normals for a model. * First builds a list of all the triangles each vertex is in.  Then * loops through each vertex in the the list averaging all the facet * normals of the triangles each vertex is in.  Finally, sets the * normal index in the triangle for the vertex to the generated smooth * normal.  If the dot product of a facet normal and the facet normal * associated with the first triangle in the list of triangles the * current vertex is in is greater than the cosine of the angle * parameter to the function, that facet normal is not added into the * average normal calculation and the corresponding vertex is given * the facet normal.  This tends to preserve hard edges.  The angle to * use depends on the model, but 90 degrees is usually a good start. * * model - initialized GLMmodel structure * angle - maximum angle (in degrees) to smooth across */GLvoidglmVertexNormals(GLMmodel* model, GLfloat angle){  GLMnode*  node;  GLMnode*  tail;  GLMnode** members;  GLfloat*  normals;  GLuint    numnormals;  GLfloat   average[3];  GLfloat   dot, cos_angle;  GLuint    i, avg;  assert(model);  assert(model->facetnorms);  /* calculate the cosine of the angle (in degrees) */  cos_angle = cos(angle * M_PI / 180.0);  /* nuke any previous normals */  if (model->normals)    free(model->normals);  /* allocate space for new normals */  model->numnormals = model->numtriangles * 3; /* 3 normals per triangle */  model->normals = (GLfloat*)malloc(sizeof(GLfloat)* 3* (model->numnormals+1));  /* allocate a structure that will hold a linked list of triangle     indices for each vertex */  members = (GLMnode**)malloc(sizeof(GLMnode*) * (model->numvertices + 1));  for (i = 1; i <= model->numvertices; i++)    members[i] = NULL;    /* for every triangle, create a node for each vertex in it */  for (i = 0; i < model->numtriangles; i++) {    node = (GLMnode*)malloc(sizeof(GLMnode));    node->index = i;    node->next  = members[T(i).vindices[0]];    members[T(i).vindices[0]] = node;    node = (GLMnode*)malloc(sizeof(GLMnode));    node->index = i;    node->next  = members[T(i).vindices[1]];    members[T(i).vindices[1]] = node;    node = (GLMnode*)malloc(sizeof(GLMnode));    node->index = i;    node->next  = members[T(i).vindices[2]];    members[T(i).vindices[2]] = node;  }  /* calculate the average normal for each vertex */  numnormals = 1;  for (i = 1; i <= model->numvertices; i++) {    /* calculate an average normal for this vertex by averaging the       facet normal of every triangle this vertex is in */    node = members[i];    if (!node)      fprintf(stderr, "glmVertexNormals(): vertex w/o a triangle\n");    average[0] = 0.0; average[1] = 0.0; average[2] = 0.0;    avg = 0;    while (node) {      /* only average if the dot product of the angle between the two         facet normals is greater than the cosine of the threshold         angle -- or, said another way, the angle between the two         facet normals is less than (or equal to) the threshold angle */      dot = glmDot(&model->facetnorms[3 * T(node->index).findex], 		    &model->facetnorms[3 * T(members[i]->index).findex]);      if (dot > cos_angle) {	node->averaged = GL_TRUE;	average[0] += model->facetnorms[3 * T(node->index).findex + 0];	average[1] += model->facetnorms[3 * T(node->index).findex + 1];	average[2] += model->facetnorms[3 * T(node->index).findex + 2];	avg = 1;			/* we averaged at least one normal! */      } else {	node->averaged = GL_FALSE;      }      node = node->next;    }    if (avg) {      /* normalize the averaged normal */      glmNormalize(average);      /* add the normal to the vertex normals list */      model->normals[3 * numnormals + 0] = average[0];      model->normals[3 * numnormals + 1] = average[1];      model->normals[3 * numnormals + 2] = average[2];      avg = numnormals;      numnormals++;    }    /* set the normal of this vertex in each triangle it is in */    node = members[i];    while (node) {      if (node->averaged) {	/* if this node was averaged, use the average normal */	if (T(node->index).vindices[0] == i)	  T(node->index).nindices[0] = avg;	else if (T(node->index).vindices[1] == i)	  T(node->index).nindices[1] = avg;	else if (T(node->index).vindices[2] == i)	  T(node->index).nindices[2] = avg;      } else {	/* if this node wasn't averaged, use the facet normal */	model->normals[3 * numnormals + 0] = 	  model->facetnorms[3 * T(node->index).findex + 0];	model->normals[3 * numnormals + 1] = 	  model->facetnorms[3 * T(node->index).findex + 1];	model->normals[3 * numnormals + 2] = 	  model->facetnorms[3 * T(node->index).findex + 2];	if (T(node->index).vindices[0] == i)	  T(node->index).nindices[0] = numnormals;	else if (T(node->index).vindices[1] == i)	  T(node->index).nindices[1] = numnormals;	else if (T(node->index).vindices[2] == i)	  T(node->index).nindices[2] = numnormals;	numnormals++;      }      node = node->next;    }  }    model->numnormals = numnormals - 1;  /* free the member information */  for (i = 1; i <= model->numvertices; i++) {    node = members[i];    while (node) {      tail = node;      node = node->next;      free(tail);    }  }  free(members);  /* pack the normals array (we previously allocated the maximum     number of normals that could possibly be created (numtriangles *     3), so get rid of some of them (usually alot unless none of the     facet normals were averaged)) */  normals = model->normals;  model->normals = (GLfloat*)malloc(sizeof(GLfloat)* 3* (model->numnormals+1));  for (i = 1; i <= model->numnormals; i++) {    model->normals[3 * i + 0] = normals[3 * i + 0];    model->normals[3 * i + 1] = normals[3 * i + 1];    model->normals[3 * i + 2] = normals[3 * i + 2];  }  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)

⌨️ 快捷键说明

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