?? glm.cpp
字號:
if(y == 0.0)
theta = 3.141592365f / 2.0f;
else
theta = fasin(y / r) + (3.14159265f / 2.0f);
}
model->texcoords[2 * i + 0] = theta / 3.14159265f;
model->texcoords[2 * i + 1] = phi / 3.14159265f;
}
/* 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
*/
GLvoid glmDelete(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;
}
/* 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.
*/
GLvoid glmDraw(GLMmodel* model, GLuint mode)
{
static GLuint i;
static GLMgroup* group;
static GLMtriangle* triangle;
static GLMmaterial* material;
assert(model);
assert(model->vertices);
/* do a bit of warning */
if (mode & GLM_FLAT && !model->facetnorms) {
mode &= ~GLM_FLAT;
}
if (mode & GLM_SMOOTH && !model->normals) {
mode &= ~GLM_SMOOTH;
}
if (mode & GLM_TEXTURE && !model->texcoords) {
mode &= ~GLM_TEXTURE;
}
if (mode & GLM_FLAT && mode & GLM_SMOOTH) {
mode &= ~GLM_FLAT;
}
if (mode & GLM_COLOR && !model->materials) {
mode &= ~GLM_COLOR;
}
if (mode & GLM_MATERIAL && !model->materials) {
mode &= ~GLM_MATERIAL;
}
if (mode & GLM_COLOR && mode & GLM_MATERIAL) {
mode &= ~GLM_COLOR;
}
if (mode & GLM_COLOR)
glEnable(GL_COLOR_MATERIAL);
else if (mode & GLM_MATERIAL)
glDisable(GL_COLOR_MATERIAL);
/* perhaps this loop should be unrolled into material, color, flat,
smooth, etc. loops? since most cpu's have good branch prediction
schemes (and these branches will always go one way), probably
wouldn't gain too much? */
group = model->groups;
while (group) {
if (mode & GLM_MATERIAL) {
material = &model->materials[group->material];
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material->ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material->diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material->specular);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material->shininess);
}
if (mode & GLM_COLOR) {
material = &model->materials[group->material];
glColor3fv(material->diffuse);
}
glBegin(GL_TRIANGLES);
for (i = 0; i < group->numtriangles; i++) {
triangle = &T(group->triangles[i]);
if (mode & GLM_FLAT)
glNormal3fv(&model->facetnorms[3 * triangle->findex]);
if (mode & GLM_SMOOTH)
glNormal3fv(&model->normals[3 * triangle->nindices[0]]);
if (mode & GLM_TEXTURE)
glTexCoord2fv(&model->texcoords[2 * triangle->tindices[0]]);
glVertex3fv(&model->vertices[3 * triangle->vindices[0]]);
if (mode & GLM_SMOOTH)
glNormal3fv(&model->normals[3 * triangle->nindices[1]]);
if (mode & GLM_TEXTURE)
glTexCoord2fv(&model->texcoords[2 * triangle->tindices[1]]);
glVertex3fv(&model->vertices[3 * triangle->vindices[1]]);
if (mode & GLM_SMOOTH)
glNormal3fv(&model->normals[3 * triangle->nindices[2]]);
if (mode & GLM_TEXTURE)
glTexCoord2fv(&model->texcoords[2 * triangle->tindices[2]]);
glVertex3fv(&model->vertices[3 * triangle->vindices[2]]);
}
glEnd();
group = group->next;
}
}
/* 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. */
GLuint glmList(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)
*
*/
GLuint glmWeld(GLMmodel* model, GLfloat epsilon)
{
GLfloat* vectors;
GLfloat* copies;
GLuint numvectors;
GLuint i, welded;
/* vertices */
numvectors = model->numvertices;
vectors = model->vertices;
copies = glmWeldVectors(vectors, &numvectors, epsilon);
welded = 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);
return welded;
}
#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
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -