hesam_hma
جمعه 16 شهریور 1386, 00:41 صبح
با استفاده از کد زیر عکس بالا تولید میشه (البته درC :ناراحت:)
/*
smooth.c
Nate Robins, 1997
Model viewer program. Excercises the glm library.
*/
#include<math.h>
#include<stdio.h>
#include<assert.h>
#include<stdarg.h>
#include<GL/glut.h>
#include"trackball.h"
#include"glm.h"
GLuint model_list = 0; /* display list for object */
char* model_file = NULL; /* name of the obect file */
GLboolean facet_normal = GL_FALSE; /* draw with facet normal? */
GLMmodel* model;
GLfloat smoothing_angle = 90.0; /* smoothing angle */
GLfloat scale; /* scaling factor */
GLdouble pan_x = 0.0;
GLdouble pan_y = 0.0;
GLdouble pan_z = 0.0;
GLint mouse_state = -1;
GLint mouse_button = -1;
GLboolean bounding_box = GL_FALSE;
GLboolean performance = GL_FALSE;
GLboolean stats = GL_FALSE;
GLfloat weld_distance = 0.00001;
GLuint material_mode = 0;
/* text: general purpose text routine. draws a string according to
* format in a stroke font at x, y after scaling it by the scale
* specified (scale is in window-space (lower-left origin) pixels).
*
* x - position in x (in window-space)
* y - position in y (in window-space)
* scale - scale in pixels
* format - as in printf()
*/
void
text(GLuint x, GLuint y, GLfloat scale, char* format, ...)
{
va_list args;
char buffer[255], *p;
GLfloat font_scale = 119.05 + 33.33;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, glutGet(GLUT_WINDOW_WIDTH), 0, glutGet(GLUT_WINDOW_HEIGHT));
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glTranslatef(x, y, 0.0);
glScalef(scale/font_scale, scale/font_scale, scale/font_scale);
for(p = buffer; *p; p++)
glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
glPopAttrib();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void
lists(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;
if (model_list)
glDeleteLists(model_list, 1);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
/* generate a list */
if (material_mode == 0) {
if (facet_normal)
model_list = glmList(model, GLM_FLAT);
else
model_list = glmList(model, GLM_SMOOTH);
} elseif (material_mode == 1) {
if (facet_normal)
model_list = glmList(model, GLM_FLAT | GLM_COLOR);
else
model_list = glmList(model, GLM_SMOOTH | GLM_COLOR);
} elseif (material_mode == 2) {
if (facet_normal)
model_list = glmList(model, GLM_FLAT | GLM_MATERIAL);
else
model_list = glmList(model, GLM_SMOOTH | GLM_MATERIAL);
}
}
void
init(void)
{
tbInit(GLUT_MIDDLE_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);
}
void
reshape(int width, int height)
{
tbReshape(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);
}
void
display(void)
{
staticint start, end, last;
start = glutGet(GLUT_ELAPSED_TIME);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (performance) {
glColor3f(1.0, 1.0, 1.0);
text(5, 5, 20, "%.2f fps", 1.0 / ((end - last) / 1000.0));
last = start;
}
glPushMatrix();
glTranslatef(pan_x, pan_y, 0.0);
tbMatrix();
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glColor3f(0.5, 0.5, 0.5);
glCallList(model_list);
if (bounding_box) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_CULL_FACE);
glColor4f(1.0, 0.0, 0.0, 0.25);
glutSolidCube(2.0);
}
glPopMatrix();
if (stats) {
glColor3f(1.0, 1.0, 1.0);
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*1), 20, "%s",
model->pathname);
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*2), 20, "%d vertices",
model->numvertices);
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*3), 20, "%d triangles",
model->numtriangles);
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*4), 20, "%d normals",
model->numnormals);
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*5), 20, "%d texcoords",
model->numtexcoords);
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*6), 20, "%d groups",
model->numgroups);
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*7), 20, "%d materials",
model->nummaterials);
}
glutSwapBuffers();
end = glutGet(GLUT_ELAPSED_TIME);
}
void
keyboard(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':
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'q':
case 27:
exit(0);
break;
}
glutPostRedisplay();
}
void
menu(int item)
{
keyboard((unsignedchar)item, 0, 0);
}
void
mouse(int button, int state, int x, int y)
{
GLdouble model[4*4];
GLdouble proj[4*4];
GLint view[4];
tbMouse(button, state, x, y);
mouse_state = state;
mouse_button = button;
if (state == GLUT_DOWN && button == GLUT_LEFT_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();
}
void
motion(int x, int y)
{
GLdouble model[4*4];
GLdouble proj[4*4];
GLint view[4];
tbMotion(x, y);
if (mouse_state == GLUT_DOWN && mouse_button == GLUT_LEFT_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();
}
int
main(int argc, char** argv)
{
glutInitWindowSize(512, 512);
glutInit(&argc, argv);
model_file = argv[1];
if (!model_file) {
fprintf(stderr, "usage: smooth model_file.obj\n");
exit(1);
}
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow("smooth");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutCreateMenu(menu);
glutAddMenuEntry("Smooth", 0);
glutAddMenuEntry("", 0);
glutAddMenuEntry("[w] Toggle wireframe/filled", 'w');
glutAddMenuEntry("[c] Toggle culling on/off", 'c');
glutAddMenuEntry("[n] Toggle facet/smooth normals", 'n');
glutAddMenuEntry("[b] Toggle bounding box on/off", 'b');
glutAddMenuEntry("[r] Reverse polygon winding", 'r');
glutAddMenuEntry("[m] Toggle color/material/none mode", 'm');
glutAddMenuEntry("[s] Scale model smaller", 's');
glutAddMenuEntry("[S] Scale model larger", 'S');
glutAddMenuEntry("[p] Toggle performance indicator", 'c');
glutAddMenuEntry("[o] Weld redundant vertices", 'c');
glutAddMenuEntry("[t] Show model stats", 'c');
glutAddMenuEntry("[+] Increase smoothing angle", '+');
glutAddMenuEntry("[-] Decrease smoothing angle", '-');
glutAddMenuEntry("[W] Write model to file (out.obj)", 'W');
glutAddMenuEntry("", 0);
glutAddMenuEntry("[q] Quit", 27);
glutAttachMenu(GLUT_RIGHT_BUTTON);
init();
glutMainLoop();
return 0;
}
vBulletin® v4.2.5, Copyright ©2000-1403, Jelsoft Enterprises Ltd.