Subversion Repositories gelsvn

Rev

Rev 357 | Rev 365 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 357 Rev 363
1
// ----------------------------------------
1
// ----------------------------------------
2
// A simple OBJ viewer.
2
// A simple OBJ viewer.
3
//
3
//
4
// Controls:
4
// Controls:
5
// - left mouse down + mouse motion : rotate
5
// - left mouse down + mouse motion : rotate
6
// - Scroll button and +- buttons   : zoom
6
// - Scroll button and +- buttons   : zoom
7
// - right mouse click              : centre trackball
7
// - right mouse click              : centre trackball
8
// - esc                            : exits
8
// - esc                            : exits
9
// - x,y,z buttons                  : switch trackball up axis
9
// - x,y,z buttons                  : switch trackball up axis
10
// ----------------------------------------
10
// ----------------------------------------
11
 
11
 
12
#if (_MSC_VER >= 1200)
12
#if (_MSC_VER >= 1200)
13
#pragma warning (disable: 4786)
13
#pragma warning (disable: 4786)
14
#endif
14
#endif
15
 
15
 
16
#include <list>
16
#include <list>
17
#include <vector>
17
#include <vector>
18
 
18
 
19
#include <assert.h>
19
#include <assert.h>
20
#include <stdio.h>
20
#include <stdio.h>
21
#ifdef WIN32
21
#ifdef WIN32
22
#include <windows.h>
22
#include <windows.h>
23
#include <io.h>
23
#include <io.h>
24
#endif
24
#endif
25
#include <string.h>
25
#include <string.h>
26
#include <stdlib.h>
26
#include <stdlib.h>
27
 
27
 
28
#include <iostream>
28
#include <iostream>
29
 
29
 
30
#include <IL/il.h>
30
#include <IL/il.h>
31
#include <IL/ilu.h>
31
#include <IL/ilu.h>
32
 
32
 
33
#include <CGLA/Vec2i.h>
33
#include <CGLA/Vec2i.h>
34
#include <CGLA/Vec2f.h>
34
#include <CGLA/Vec2f.h>
35
#include <CGLA/Vec3f.h>
35
#include <CGLA/Vec3f.h>
36
#include <CGLA/Mat4x4f.h>
36
#include <CGLA/Mat4x4f.h>
37
#include "glsl_shader.h"
37
#include "glsl_shader.h"
38
#include "GLGraphics/gel_glut.h"
38
#include "GLGraphics/gel_glut.h"
39
#include "GLGraphics/QuatTrackBall.h"
39
#include "GLGraphics/QuatTrackBall.h"
40
#include "GLGraphics/draw.h"
40
#include "GLGraphics/draw.h"
41
#include "Geometry/TriMesh.h"
41
#include "Geometry/TriMesh.h"
42
#include "Geometry/obj_load.h"
42
#include "Geometry/obj_load.h"
43
 
43
 
44
#include "ply_load.h"
44
#include "ply_load.h"
45
 
45
 
46
using namespace std;
46
using namespace std;
47
using namespace CGLA;
47
using namespace CGLA;
48
using namespace Geometry;
48
using namespace Geometry;
49
using namespace GLGraphics;
49
using namespace GLGraphics;
50
 
50
 
51
namespace
51
namespace
52
{
52
{
53
	int win_size_x = 800;
53
	int win_size_x = 800;
54
	int win_size_y = 800;
54
	int win_size_y = 800;
-
 
55
	bool per_vertex_normals = 1;
-
 
56
	bool redo_display_list = 1;
55
	QuatTrackBall* ball;
57
	QuatTrackBall* ball;
56
	int spin_timer = 20;
58
	int spin_timer = 20;
57
	void spin(int x);
59
	void spin(int x);
58
	int main_window;
60
	int main_window;
59
	TriMesh mesh;
61
	TriMesh mesh;
60
	
62
	
61
	
63
	
62
	bool load_image_into_texture(const std::string& name, GLuint& id)
64
	bool load_image_into_texture(const std::string& name, GLuint& id)
63
	{
65
	{
64
		unsigned char* image = 0;
66
		unsigned char* image = 0;
65
		unsigned int bpp = 0;
67
		unsigned int bpp = 0;
66
		unsigned int size_x = 0;
68
		unsigned int size_x = 0;
67
		unsigned int size_y = 0;
69
		unsigned int size_y = 0;
68
		unsigned int load_size_x = 0;
70
		unsigned int load_size_x = 0;
69
		unsigned int load_size_y = 0;
71
		unsigned int load_size_y = 0;
70
		
72
		
71
		
73
		
72
		ILenum Error;
74
		ILenum Error;
73
		ILuint  ImgId;
75
		ILuint  ImgId;
74
		
76
		
75
		static bool washere = false;
77
		static bool washere = false;
76
		if(!washere)
78
		if(!washere)
77
		{
79
		{
78
			ilInit();
80
			ilInit();
79
			iluInit();
81
			iluInit();
80
			washere=true;
82
			washere=true;
81
		}
83
		}
82
		ilEnable(IL_CONV_PAL);
84
		ilEnable(IL_CONV_PAL);
83
		ilEnable(IL_ORIGIN_SET);
85
		ilEnable(IL_ORIGIN_SET);
84
		ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
86
		ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
85
		ilGenImages(1, &ImgId);
87
		ilGenImages(1, &ImgId);
86
		ilBindImage(ImgId);
88
		ilBindImage(ImgId);
87
		char* name_cstr = const_cast<char*>(name.c_str());
89
		char* name_cstr = const_cast<char*>(name.c_str());
88
		if(!ilLoadImage(name_cstr))
90
		if(!ilLoadImage(name_cstr))
89
		{
91
		{
90
			cout << "could not load <" << name_cstr  << ">" << endl;
92
			cout << "could not load <" << name_cstr  << ">" << endl;
91
			return false;
93
			return false;
92
		}
94
		}
93
		
95
		
94
		load_size_x = ilGetInteger(IL_IMAGE_WIDTH);
96
		load_size_x = ilGetInteger(IL_IMAGE_WIDTH);
95
		load_size_y = ilGetInteger(IL_IMAGE_HEIGHT);
97
		load_size_y = ilGetInteger(IL_IMAGE_HEIGHT);
96
		bpp = ilGetInteger(IL_IMAGE_BITS_PER_PIXEL);
98
		bpp = ilGetInteger(IL_IMAGE_BITS_PER_PIXEL);
97
		
99
		
98
		if (bpp==24)
100
		if (bpp==24)
99
			ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);
101
			ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);
100
		else if (bpp==32)
102
		else if (bpp==32)
101
			ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
103
			ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
102
		else if (bpp==8)
104
		else if (bpp==8)
103
			ilConvertImage(IL_LUMINANCE, IL_UNSIGNED_BYTE);
105
			ilConvertImage(IL_LUMINANCE, IL_UNSIGNED_BYTE);
104
		else
106
		else
105
			assert(0);
107
			assert(0);
106
		
108
		
107
		unsigned int i;
109
		unsigned int i;
108
		for (i=2;i<=4096 ;i*=2)
110
		for (i=2;i<=4096 ;i*=2)
109
			if (i>=load_size_x)
111
			if (i>=load_size_x)
110
				break;
112
				break;
111
		size_x = i;
113
		size_x = i;
112
		for (i=2;i<=4096 ;i*=2)
114
		for (i=2;i<=4096 ;i*=2)
113
			if (i>=load_size_y)
115
			if (i>=load_size_y)
114
				break;
116
				break;
115
		size_y = i;
117
		size_y = i;
116
		
118
		
117
		if(size_x != load_size_x || size_y != load_size_y)
119
		if(size_x != load_size_x || size_y != load_size_y)
118
		{
120
		{
119
			iluImageParameter(ILU_FILTER, ILU_BILINEAR);
121
			iluImageParameter(ILU_FILTER, ILU_BILINEAR);
120
			iluScale(size_x, size_y, 1);
122
			iluScale(size_x, size_y, 1);
121
		}
123
		}
122
		
124
		
123
		const int image_size =size_x*size_y*ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);
125
		const int image_size =size_x*size_y*ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);
124
		image = new unsigned char[image_size];
126
		image = new unsigned char[image_size];
125
		memcpy(image, ilGetData(), image_size);
127
		memcpy(image, ilGetData(), image_size);
126
		ilDeleteImages(1, &ImgId);
128
		ilDeleteImages(1, &ImgId);
127
		
129
		
128
		bool any_errors=false;
130
		bool any_errors=false;
129
		while ((Error = ilGetError())) {
131
		while ((Error = ilGetError())) {
130
			cout << __LINE__ << "Error: " << iluErrorString(Error) << endl;
132
			cout << __LINE__ << "Error: " << iluErrorString(Error) << endl;
131
			any_errors = true;
133
			any_errors = true;
132
		}
134
		}
133
		if(any_errors) return false;
135
		if(any_errors) return false;
134
		
136
		
135
		GLint internalFormat=0;
137
		GLint internalFormat=0;
136
		GLenum format=0;
138
		GLenum format=0;
137
		
139
		
138
		glGenTextures(1, &id);
140
		glGenTextures(1, &id);
139
		switch (bpp)
141
		switch (bpp)
140
		{
142
		{
141
			case 8:
143
			case 8:
142
				internalFormat =  GL_LUMINANCE;
144
				internalFormat =  GL_LUMINANCE;
143
				format = GL_LUMINANCE;
145
				format = GL_LUMINANCE;
144
				break;
146
				break;
145
			case 24:
147
			case 24:
146
				internalFormat =  GL_RGB;
148
				internalFormat =  GL_RGB;
147
				format = GL_RGB;
149
				format = GL_RGB;
148
				break;
150
				break;
149
			case 32:
151
			case 32:
150
				internalFormat =  GL_RGBA;
152
				internalFormat =  GL_RGBA;
151
				format = GL_RGBA;
153
				format = GL_RGBA;
152
				break;
154
				break;
153
			default:
155
			default:
154
				return false;
156
				return false;
155
		}
157
		}
156
		
158
		
157
		glBindTexture(GL_TEXTURE_2D, id);
159
		glBindTexture(GL_TEXTURE_2D, id);
158
		glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, size_x, size_y, 0,
160
		glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, size_x, size_y, 0,
159
					 format, GL_UNSIGNED_BYTE, image);
161
					 format, GL_UNSIGNED_BYTE, image);
160
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
162
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
161
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
163
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
162
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
164
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
163
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
165
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
164
		
166
		
165
		return true;
167
		return true;
166
	}
168
	}
167
	
169
	
168
	void enable_textures(TriMesh& tm)
170
	void enable_textures(TriMesh& tm)
169
	{
171
	{
170
		for(unsigned int i=0;i<tm.materials.size(); ++i)
172
		for(unsigned int i=0;i<tm.materials.size(); ++i)
171
		{
173
		{
172
			Material& mat = tm.materials[i];
174
			Material& mat = tm.materials[i];
173
			if(mat.tex_name != "")
175
			if(mat.tex_name != "")
174
			{
176
			{
175
				string name = mat.tex_path + mat.tex_name;
177
				string name = mat.tex_path + mat.tex_name;
176
				
178
				
177
				GLuint tex_id;
179
				GLuint tex_id;
178
				if(load_image_into_texture(name, tex_id))
180
				if(load_image_into_texture(name, tex_id))
179
					mat.tex_id = tex_id;
181
					mat.tex_id = tex_id;
180
			}
182
			}
181
		}
183
		}
182
	}
184
	}
183
	
185
	
184
	void toggle_wire()
186
	void toggle_wire()
185
	{
187
	{
186
		static bool wire= false;
188
		static bool wire= false;
187
		static string shader_path = "/Users/jab/SrcTree/Appsrc/wireframepaper/";
189
		static string shader_path = "/Users/jab/SrcTree/Appsrc/wireframepaper/";
188
		static GLhandleARB prog_P0;
190
		static GLhandleARB prog_P0;
189
		
191
		
190
		wire = !wire;
192
		wire = !wire;
191
		static bool washere = false;
193
		static bool washere = false;
192
		if(!washere)
194
		if(!washere)
193
		{
195
		{
194
			washere = true;
196
			washere = true;
195
			
197
			
196
			// Create s	haders directly from file
198
			// Create s	haders directly from file
197
			GLuint vs = create_glsl_shader(GL_VERTEX_SHADER, shader_path, "tri.vert");
199
			GLuint vs = create_glsl_shader(GL_VERTEX_SHADER, shader_path, "tri.vert");
198
			GLuint gs = create_glsl_shader(GL_GEOMETRY_SHADER_EXT, shader_path, "tri.geom");
200
			GLuint gs = create_glsl_shader(GL_GEOMETRY_SHADER_EXT, shader_path, "tri.geom");
199
			GLuint fs = create_glsl_shader(GL_FRAGMENT_SHADER, shader_path, "tri.frag");
201
			GLuint fs = create_glsl_shader(GL_FRAGMENT_SHADER, shader_path, "tri.frag");
200
			
202
			
201
			// Create the program
203
			// Create the program
202
			prog_P0 = glCreateProgram();
204
			prog_P0 = glCreateProgram();
203
			
205
			
204
			// Attach all shaders
206
			// Attach all shaders
205
			if(vs) glAttachShader(prog_P0, vs);
207
			if(vs) glAttachShader(prog_P0, vs);
206
			if(gs) glAttachShader(prog_P0, gs);
208
			if(gs) glAttachShader(prog_P0, gs);
207
			if(fs) glAttachShader(prog_P0, fs);
209
			if(fs) glAttachShader(prog_P0, fs);
208
			
210
			
209
			// Specify input and output for the geometry shader. Note that this must be
211
			// Specify input and output for the geometry shader. Note that this must be
210
			// done before linking the program.
212
			// done before linking the program.
211
			glProgramParameteriEXT(prog_P0,GL_GEOMETRY_INPUT_TYPE_EXT,GL_TRIANGLES);
213
			glProgramParameteriEXT(prog_P0,GL_GEOMETRY_INPUT_TYPE_EXT,GL_TRIANGLES);
212
			glProgramParameteriEXT(prog_P0,GL_GEOMETRY_VERTICES_OUT_EXT,3);
214
			glProgramParameteriEXT(prog_P0,GL_GEOMETRY_VERTICES_OUT_EXT,3);
213
			glProgramParameteriEXT(prog_P0,GL_GEOMETRY_OUTPUT_TYPE_EXT,GL_TRIANGLE_STRIP);
215
			glProgramParameteriEXT(prog_P0,GL_GEOMETRY_OUTPUT_TYPE_EXT,GL_TRIANGLE_STRIP);
214
			
216
			
215
			// Link the program object and print out the info log
217
			// Link the program object and print out the info log
216
			glLinkProgram(prog_P0);
218
			glLinkProgram(prog_P0);
217
		}
219
		}
218
		if(wire)
220
		if(wire)
219
		{
221
		{
220
			glUseProgram(prog_P0);
222
			glUseProgram(prog_P0);
221
			// Set the value of a uniform
223
			// Set the value of a uniform
222
			glUniform2f(glGetUniformLocation(prog_P0,"WIN_SCALE"), win_size_x/2.0, win_size_y/2.0);
224
			glUniform2f(glGetUniformLocation(prog_P0,"WIN_SCALE"), win_size_x/2.0, win_size_y/2.0);
223
		}
225
		}
224
		else
226
		else
225
			glUseProgram(0);		
227
			glUseProgram(0);		
226
	}
228
	}
227
	
229
	
228
	bool depth_pick(int x, int y,Vec3f& wp)
230
	bool depth_pick(int x, int y,Vec3f& wp)
229
	{
231
	{
230
		// Enquire about the viewport dimensions
232
		// Enquire about the viewport dimensions
231
		GLint viewport[4];
233
		GLint viewport[4];
232
		glGetIntegerv(GL_VIEWPORT, viewport);
234
		glGetIntegerv(GL_VIEWPORT, viewport);
233
		
235
		
234
		// Get the minimum and maximum depth values.
236
		// Get the minimum and maximum depth values.
235
		float minmax_depth[2];
237
		float minmax_depth[2];
236
		glGetFloatv(GL_DEPTH_RANGE, minmax_depth);
238
		glGetFloatv(GL_DEPTH_RANGE, minmax_depth);
237
		
239
		
238
		// Read a single pixel at the position of the mouse cursor.
240
		// Read a single pixel at the position of the mouse cursor.
239
		float depth;
241
		float depth;
240
		glReadPixels(x, viewport[3]-y, 1,1, GL_DEPTH_COMPONENT,
242
		glReadPixels(x, viewport[3]-y, 1,1, GL_DEPTH_COMPONENT,
241
					 GL_FLOAT, (void*) &depth);
243
					 GL_FLOAT, (void*) &depth);
242
		
244
		
243
		// If the depth corresponds to the far plane, we clicked on the
245
		// If the depth corresponds to the far plane, we clicked on the
244
		// background.
246
		// background.
245
		if(depth == minmax_depth[1])
247
		if(depth == minmax_depth[1])
246
			return false;
248
			return false;
247
		
249
		
248
		// The lines below copy the viewing transformation from OpenGL
250
		// The lines below copy the viewing transformation from OpenGL
249
		// to local variables. The call to gluLookAt must have exactly
251
		// to local variables. The call to gluLookAt must have exactly
250
		// the same parameters as when the scene is drawn.
252
		// the same parameters as when the scene is drawn.
251
		glLoadIdentity();
253
		glLoadIdentity();
252
		ball->set_gl_modelview();
254
		ball->set_gl_modelview();
253
		double mvmat[16];
255
		double mvmat[16];
254
		glGetDoublev(GL_MODELVIEW_MATRIX, mvmat);
256
		glGetDoublev(GL_MODELVIEW_MATRIX, mvmat);
255
		
257
		
256
		// Copy the projection matrix. We assume it is unchanged.
258
		// Copy the projection matrix. We assume it is unchanged.
257
		double prjmat[16];
259
		double prjmat[16];
258
		glGetDoublev(GL_PROJECTION_MATRIX, prjmat);
260
		glGetDoublev(GL_PROJECTION_MATRIX, prjmat);
259
		
261
		
260
		// Now unproject the point from screen to world coordinates.
262
		// Now unproject the point from screen to world coordinates.
261
		double ox, oy, oz;
263
		double ox, oy, oz;
262
		gluUnProject(x,viewport[3]-y,depth,
264
		gluUnProject(x,viewport[3]-y,depth,
263
					 mvmat,prjmat,viewport,
265
					 mvmat,prjmat,viewport,
264
					 &ox, &oy, &oz);
266
					 &ox, &oy, &oz);
265
		
267
		
266
		wp = Vec3f(ox,oy,oz);
268
		wp = Vec3f(ox,oy,oz);
267
		
269
		
268
		return true;
270
		return true;
269
	}
271
	}
270
	
272
	
271
 
273
 
272
 
274
 
273
void mouse_motion(int x, int y)
275
void mouse_motion(int x, int y)
274
{
276
{
275
    ball->roll_ball(Vec2i(x,y));
277
    ball->roll_ball(Vec2i(x,y));
276
}
278
}
277
 
279
 
278
void mouse(int btn, int state, int x, int y)
280
void mouse(int btn, int state, int x, int y)
279
{
281
{
280
	if(state == GLUT_DOWN) 
282
	if(state == GLUT_DOWN) 
281
	{
283
	{
282
		if(btn == GLUT_LEFT_BUTTON) 
284
		if(btn == GLUT_LEFT_BUTTON) 
283
			ball->grab_ball(ROTATE_ACTION, Vec2i(x,y));
285
			ball->grab_ball(ROTATE_ACTION, Vec2i(x,y));
284
		else if(btn == GLUT_MIDDLE_BUTTON) 
286
		else if(btn == GLUT_MIDDLE_BUTTON) 
285
			ball->grab_ball(ZOOM_ACTION, Vec2i(x, y));
287
			ball->grab_ball(ZOOM_ACTION, Vec2i(x, y));
286
		else if(btn == GLUT_RIGHT_BUTTON) 
288
		else if(btn == GLUT_RIGHT_BUTTON) 
287
			ball->grab_ball(PAN_ACTION, Vec2i(x, y));
289
			ball->grab_ball(PAN_ACTION, Vec2i(x, y));
288
	}
290
	}
289
	else if(state == GLUT_UP)
291
	else if(state == GLUT_UP)
290
		ball->release_ball();	
292
		ball->release_ball();	
291
}
293
}
292
 
294
 
293
void spin(int x)
295
void spin(int x)
294
{
296
{
295
	ball->do_spin();
297
	ball->do_spin();
296
	glutTimerFunc(spin_timer, spin, 0);  
298
	glutTimerFunc(spin_timer, spin, 0);  
297
	glutPostRedisplay();
299
	glutPostRedisplay();
298
}
300
}
299
 
301
 
300
void display()
302
void display()
301
{
303
{
302
    static bool washere = false;
-
 
303
    static unsigned int l;
304
	static unsigned int l;
304
    if(!washere)
305
    if(redo_display_list)
305
    {
306
    {
306
        cout << "Creating display list" << endl;
307
        cout << "Creating display list" << endl;
307
        l = glGenLists(1);
308
        l = glGenLists(1);
308
        glNewList(l, GL_COMPILE);
309
        glNewList(l, GL_COMPILE);
309
        draw(mesh);
310
        draw(mesh, per_vertex_normals);
310
        glEndList();
311
        glEndList();
311
        washere = true;
312
        redo_display_list = false;
312
		glutTimerFunc(spin_timer, spin, 0);	
313
		glutTimerFunc(spin_timer, spin, 0);	
313
	}
314
	}
314
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
315
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
315
    glLoadIdentity();
316
    glLoadIdentity();
316
    ball->set_gl_modelview();
317
    ball->set_gl_modelview();
317
    glCallList(l);
318
    glCallList(l);
318
    glutSwapBuffers();
319
    glutSwapBuffers();
319
}
320
}
320
 
321
 
321
void keyboard(unsigned char key, int x, int y)
322
void keyboard(unsigned char key, int x, int y)
322
{
323
{
323
    switch(key)
324
    switch(key)
324
    {
325
    {
325
		case '\033': exit(0); break;
326
		case '\033': exit(0); break;
326
		case 'w': toggle_wire(); break;
327
		case 'w': toggle_wire(); break;
-
 
328
		case 'f': per_vertex_normals = !per_vertex_normals; redo_display_list = true; break;
327
    }
329
    }
328
}
330
}
329
}
331
}
330
 
332
 
331
int main(int argc, char** argv)
333
int main(int argc, char** argv)
332
{
334
{
333
    // GLUT INIT
335
    // GLUT INIT
334
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
336
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
335
    glutInitWindowSize(win_size_x, win_size_y);
337
    glutInitWindowSize(win_size_x, win_size_y);
336
    glutInit(&argc, argv);
338
    glutInit(&argc, argv);
337
    main_window = glutCreateWindow("OBJ Viewer");
339
    main_window = glutCreateWindow("OBJ Viewer");
338
    glutDisplayFunc(display);
340
    glutDisplayFunc(display);
339
    glutKeyboardFunc(keyboard);
341
    glutKeyboardFunc(keyboard);
340
    glutMotionFunc(mouse_motion);
342
    glutMotionFunc(mouse_motion);
341
    glutMouseFunc(mouse);
343
    glutMouseFunc(mouse);
342
    //glutIdleFunc(idle);
344
    //glutIdleFunc(idle);
343
	
345
	
344
	glewInit();
346
	glewInit();
345
	
347
	
346
    // GL INIT
348
    // GL INIT
347
    glClearColor(.8f, 0.9f, 1.0f, 0.f);
349
    glClearColor(.8f, 0.9f, 1.0f, 0.f);
348
    glEnable(GL_DEPTH_TEST);
350
    glEnable(GL_DEPTH_TEST);
349
    glEnable(GL_LIGHTING);
351
    glEnable(GL_LIGHTING);
350
    glEnable(GL_LIGHT0);
352
    glEnable(GL_LIGHT0);
351
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
353
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
352
    glShadeModel(GL_SMOOTH);
354
    glShadeModel(GL_SMOOTH);
353
	
355
	
354
    // LOAD OBJ
356
    // LOAD OBJ
355
    string fn;
357
    string fn;
356
    if(argc>1)
358
    if(argc>1)
357
        fn = argv[1];
359
        fn = argv[1];
358
    else
360
    else
359
        fn = "../../data/head.obj";
361
        fn = "../../data/head.obj";
360
		
362
		
361
	if(fn.substr(fn.length()-4,fn.length())==".obj")
363
	if(fn.substr(fn.length()-4,fn.length())==".obj")
362
	{
364
	{
363
		obj_load(fn, mesh);
365
		obj_load(fn, mesh);
364
	}
366
	}
365
	else if(fn.substr(fn.length()-4,fn.length())==".ply")
367
	else if(fn.substr(fn.length()-4,fn.length())==".ply")
366
	{
368
	{
367
		ply_load(fn, mesh);
369
		ply_load(fn, mesh);
368
	}	
370
	}	
369
	else
371
	else
370
	{
372
	{
371
		cout << "Either the format was unrecognized or the file did not have the appropriate extension" << endl;
373
		cout << "Either the format was unrecognized or the file did not have the appropriate extension" << endl;
372
		exit(0);
374
		exit(0);
373
	}		
375
	}		
374
    enable_textures(mesh);	
376
    enable_textures(mesh);	
375
    if(!mesh.has_normals())
377
    if(!mesh.has_normals())
376
    {
378
    {
377
        cout << "Computing normals" << endl;
379
        cout << "Computing normals" << endl;
378
        mesh.compute_normals();
380
        mesh.compute_normals();
379
    }
381
    }
380
 
382
 
381
    // Initialize Trackball
383
    // Initialize Trackball
382
    Vec3f c;
384
    Vec3f c;
383
    float r;
385
    float r;
384
    mesh.get_bsphere(c,r);
386
    mesh.get_bsphere(c,r);
385
    r *= 1.5;
387
    r *= 1.5;
386
    ball = new QuatTrackBall(c,r,800,800);
388
    ball = new QuatTrackBall(c,r,800,800);
387
	
389
	
388
    // Setup projection
390
    // Setup projection
389
    glMatrixMode(GL_PROJECTION);
391
    glMatrixMode(GL_PROJECTION);
390
    glLoadIdentity();
392
    glLoadIdentity();
391
    gluPerspective(53,1.0f,r/100.0,r*3.0);
393
    gluPerspective(53,1.0f,r/100.0,r*3.0);
392
    glMatrixMode(GL_MODELVIEW);
394
    glMatrixMode(GL_MODELVIEW);
393
	
395
	
394
    // Pass control to GLUT
396
    // Pass control to GLUT
395
    glutMainLoop();
397
    glutMainLoop();
396
	
398
	
397
    return 0;
399
    return 0;
398
}
400
}
399
 
401