Subversion Repositories gelsvn

Rev

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

Rev 370 Rev 374
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
// - w                              : toggle wireframe on/off
-
 
11
// - t                              : toggle texture on/off
-
 
12
// - f                              : switch between vertex and face normals
10
// ----------------------------------------
13
// ----------------------------------------
11
 
14
 
12
#if (_MSC_VER >= 1200)
15
#if (_MSC_VER >= 1200)
13
#pragma warning (disable: 4786)
16
#pragma warning (disable: 4786)
14
#endif
17
#endif
15
 
18
 
16
#include <list>
19
#include <list>
17
#include <vector>
20
#include <vector>
18
 
21
 
19
#include <assert.h>
22
#include <assert.h>
20
#include <stdio.h>
23
#include <stdio.h>
21
#ifdef WIN32
24
#ifdef WIN32
22
#include <windows.h>
25
#include <windows.h>
23
#include <io.h>
26
#include <io.h>
24
#endif
27
#endif
25
#include <string.h>
28
#include <string.h>
26
#include <stdlib.h>
29
#include <stdlib.h>
27
 
30
 
28
#include <iostream>
31
#include <iostream>
-
 
32
#include <vector>
29
 
33
 
30
#include <Util/ArgExtracter.h>
34
#include <Util/ArgExtracter.h>
31
#include <CGLA/Vec2i.h>
35
#include <CGLA/Vec2i.h>
32
#include <CGLA/Vec2f.h>
36
#include <CGLA/Vec2f.h>
33
#include <CGLA/Vec3f.h>
37
#include <CGLA/Vec3f.h>
34
#include <CGLA/Mat4x4f.h>
38
#include <CGLA/Mat4x4f.h>
35
#include "GLGraphics/glsl_shader.h"
39
#include "GLGraphics/glsl_shader.h"
36
#include "GLGraphics/gel_glut.h"
40
#include "GLGraphics/gel_glut.h"
37
#include "GLGraphics/QuatTrackBall.h"
41
#include "GLGraphics/QuatTrackBall.h"
38
#include "GLGraphics/draw.h"
42
#include "GLGraphics/draw.h"
39
#include "GLGraphics/SOIL.h"
43
#include "GLGraphics/SOIL.h"
40
#include "Geometry/TriMesh.h"
44
#include "Geometry/TriMesh.h"
41
#include "Geometry/obj_load.h"
45
#include "Geometry/obj_load.h"
42
#include "Geometry/ply_load.h"
46
#include "Geometry/ply_load.h"
43
#include "HMesh/x3d_load.h"
47
#include "HMesh/x3d_load.h"
44
#include "HMesh/FaceCirculator.h"
48
#include "HMesh/FaceCirculator.h"
45
#include "wireframe.h"
49
#include "wireframe.h"
46
 
50
 
47
using namespace std;
51
using namespace std;
48
using namespace CGLA;
52
using namespace CGLA;
49
using namespace Geometry;
53
using namespace Geometry;
50
using namespace HMesh;
54
using namespace HMesh;
51
using namespace GLGraphics;
55
using namespace GLGraphics;
52
 
56
 
53
int win_size_x = 800;
57
int win_size_x = 800;
54
int win_size_y = 800;
58
int win_size_y = 800;
55
bool per_vertex_normals = 1;
59
bool per_vertex_normals = 1;
56
bool redo_display_list = 1;
60
bool redo_display_list = 1;
57
bool do_wireframe = false;
61
bool do_wireframe = false;
58
Vec3f line_col = Vec3f(1,0,0);
62
Vec3f line_col = Vec3f(1,0,0);
59
QuatTrackBall* ball;
63
QuatTrackBall* ball;
60
int spin_timer = 20;
64
int spin_timer = 20;
61
void spin(int x);
65
void spin(int x);
62
int main_window;
66
int main_window;
63
TriMesh mesh;
67
TriMesh mesh;
-
 
68
bool do_textures = true;
-
 
69
vector<bool> has_texture;
64
 
70
 
65
void enable_textures(TriMesh& tm)
71
void enable_textures(TriMesh& tm)
66
{
72
{
-
 
73
	for(unsigned int i=0;i<has_texture.size(); ++i)
-
 
74
		tm.materials[i].has_texture = has_texture[i];
-
 
75
}
-
 
76
 
-
 
77
void disable_textures(TriMesh& tm)
-
 
78
{
-
 
79
	for(unsigned int i=0;i<has_texture.size(); ++i)
-
 
80
		tm.materials[i].has_texture = false;
-
 
81
}
-
 
82
 
-
 
83
void load_textures(TriMesh& tm)
-
 
84
{
-
 
85
  has_texture.resize(tm.materials.size());
67
	for(unsigned int i=0;i<tm.materials.size(); ++i)
86
	for(unsigned int i=0;i<tm.materials.size(); ++i)
68
	{
87
	{
69
		Material& mat = tm.materials[i];
88
		Material& mat = tm.materials[i];
70
		if(mat.tex_name != "")
89
		if(mat.tex_name != "")
71
		{
90
		{
72
			string name = mat.tex_path + mat.tex_name;
91
			string name = mat.tex_path + mat.tex_name;
73
			mat.tex_id = SOIL_load_OGL_texture(name.data(), 0, 0, SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_POWER_OF_TWO);
92
			mat.tex_id = SOIL_load_OGL_texture(name.data(), 0, 0, SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_POWER_OF_TWO);
-
 
93
      if(mat.tex_id)
-
 
94
        has_texture[i] = true;
74
		}
95
		}
75
	}
96
	}
76
}
97
}
77
 
98
 
78
void load_mesh(const string& fn)
99
void load_mesh(const string& fn)
79
{
100
{
80
	if(fn.substr(fn.length()-4,fn.length())==".obj")
101
	if(fn.substr(fn.length()-4,fn.length())==".obj")
81
	{
102
	{
82
		obj_load(fn, mesh);
103
		obj_load(fn, mesh);
83
	}
104
	}
84
	else if(fn.substr(fn.length()-4,fn.length())==".ply")
105
	else if(fn.substr(fn.length()-4,fn.length())==".ply")
85
	{
106
	{
86
		ply_load(fn, mesh);
107
		ply_load(fn, mesh);
87
	}	
108
	}	
88
	else if(fn.substr(fn.length()-4,fn.length())==".x3d")
109
	else if(fn.substr(fn.length()-4,fn.length())==".x3d")
89
	{
110
	{
90
		Manifold m;
111
		Manifold m;
91
		x3d_load(fn, m);
112
		x3d_load(fn, m);
92
		
113
		
93
		for(VertexIter v=m.vertices_begin(); v != m.vertices_end();++v)
114
		for(VertexIter v=m.vertices_begin(); v != m.vertices_end();++v)
94
			v->touched = mesh.geometry.add_vertex(v->pos);
115
			v->touched = mesh.geometry.add_vertex(v->pos);
95
		
116
		
96
		for(FaceIter f = m.faces_begin(); f!= m.faces_end(); ++f)
117
		for(FaceIter f = m.faces_begin(); f!= m.faces_end(); ++f)
97
		{
118
		{
98
			Vec3i face;
119
			Vec3i face;
99
			int i=0;
120
			int i=0;
100
			for(FaceCirculator fc(f); !fc.end(); ++fc,++i)
121
			for(FaceCirculator fc(f); !fc.end(); ++fc,++i)
101
			{
122
			{
102
				if(i<2)
123
				if(i<2)
103
					face[i] = fc.get_vertex()->touched;
124
					face[i] = fc.get_vertex()->touched;
104
				else
125
				else
105
				{
126
				{
106
					face[2] = fc.get_vertex()->touched;
127
					face[2] = fc.get_vertex()->touched;
107
					mesh.geometry.add_face(face);
128
					mesh.geometry.add_face(face);
108
					face[1] = face[2];
129
					face[1] = face[2];
109
				}
130
				}
110
			}	
131
			}	
111
		}
132
		}
112
	}
133
	}
113
	else
134
	else
114
	{
135
	{
115
		cout << "Either the format was unrecognized or the file did not have the appropriate extension" << endl;
136
		cout << "Either the format was unrecognized or the file did not have the appropriate extension" << endl;
116
		exit(0);
137
		exit(0);
117
	}
138
	}
118
	enable_textures(mesh);	
139
  load_textures(mesh);	
119
		
140
  if(!do_textures)
-
 
141
    disable_textures(mesh);		
120
}
142
}
121
 
143
 
122
bool depth_pick(int x, int y,Vec3f& wp)
144
bool depth_pick(int x, int y,Vec3f& wp)
123
{
145
{
124
	// Enquire about the viewport dimensions
146
	// Enquire about the viewport dimensions
125
	GLint viewport[4];
147
	GLint viewport[4];
126
	glGetIntegerv(GL_VIEWPORT, viewport);
148
	glGetIntegerv(GL_VIEWPORT, viewport);
127
	
149
	
128
	// Get the minimum and maximum depth values.
150
	// Get the minimum and maximum depth values.
129
	float minmax_depth[2];
151
	float minmax_depth[2];
130
	glGetFloatv(GL_DEPTH_RANGE, minmax_depth);
152
	glGetFloatv(GL_DEPTH_RANGE, minmax_depth);
131
	
153
	
132
	// Read a single pixel at the position of the mouse cursor.
154
	// Read a single pixel at the position of the mouse cursor.
133
	float depth;
155
	float depth;
134
	glReadPixels(x, viewport[3]-y, 1,1, GL_DEPTH_COMPONENT,
156
	glReadPixels(x, viewport[3]-y, 1,1, GL_DEPTH_COMPONENT,
135
				 GL_FLOAT, (void*) &depth);
157
				 GL_FLOAT, (void*) &depth);
136
	
158
	
137
	// If the depth corresponds to the far plane, we clicked on the
159
	// If the depth corresponds to the far plane, we clicked on the
138
	// background.
160
	// background.
139
	if(depth == minmax_depth[1])
161
	if(depth == minmax_depth[1])
140
		return false;
162
		return false;
141
	
163
	
142
	// The lines below copy the viewing transformation from OpenGL
164
	// The lines below copy the viewing transformation from OpenGL
143
	// to local variables. The call to gluLookAt must have exactly
165
	// to local variables. The call to gluLookAt must have exactly
144
	// the same parameters as when the scene is drawn.
166
	// the same parameters as when the scene is drawn.
145
	glLoadIdentity();
167
	glLoadIdentity();
146
	ball->set_gl_modelview();
168
	ball->set_gl_modelview();
147
	double mvmat[16];
169
	double mvmat[16];
148
	glGetDoublev(GL_MODELVIEW_MATRIX, mvmat);
170
	glGetDoublev(GL_MODELVIEW_MATRIX, mvmat);
149
	
171
	
150
	// Copy the projection matrix. We assume it is unchanged.
172
	// Copy the projection matrix. We assume it is unchanged.
151
	double prjmat[16];
173
	double prjmat[16];
152
	glGetDoublev(GL_PROJECTION_MATRIX, prjmat);
174
	glGetDoublev(GL_PROJECTION_MATRIX, prjmat);
153
	
175
	
154
	// Now unproject the point from screen to world coordinates.
176
	// Now unproject the point from screen to world coordinates.
155
	double ox, oy, oz;
177
	double ox, oy, oz;
156
	gluUnProject(x,viewport[3]-y,depth,
178
	gluUnProject(x,viewport[3]-y,depth,
157
				 mvmat,prjmat,viewport,
179
				 mvmat,prjmat,viewport,
158
				 &ox, &oy, &oz);
180
				 &ox, &oy, &oz);
159
	
181
	
160
	wp = Vec3f(ox,oy,oz);
182
	wp = Vec3f(ox,oy,oz);
161
	
183
	
162
	return true;
184
	return true;
163
}
185
}
164
 
186
 
165
 
187
 
166
 
188
 
167
void mouse_motion(int x, int y)
189
void mouse_motion(int x, int y)
168
{
190
{
169
    ball->roll_ball(Vec2i(x,y));
191
    ball->roll_ball(Vec2i(x,y));
170
}
192
}
171
 
193
 
172
void mouse(int btn, int state, int x, int y)
194
void mouse(int btn, int state, int x, int y)
173
{
195
{
174
	if(state == GLUT_DOWN) 
196
	if(state == GLUT_DOWN) 
175
	{
197
	{
176
		if(btn == GLUT_LEFT_BUTTON) 
198
		if(btn == GLUT_LEFT_BUTTON) 
177
			ball->grab_ball(ROTATE_ACTION, Vec2i(x,y));
199
			ball->grab_ball(ROTATE_ACTION, Vec2i(x,y));
178
		else if(btn == GLUT_MIDDLE_BUTTON) 
200
		else if(btn == GLUT_MIDDLE_BUTTON) 
179
			ball->grab_ball(ZOOM_ACTION, Vec2i(x, y));
201
			ball->grab_ball(ZOOM_ACTION, Vec2i(x, y));
180
		else if(btn == GLUT_RIGHT_BUTTON) 
202
		else if(btn == GLUT_RIGHT_BUTTON) 
181
			ball->grab_ball(PAN_ACTION, Vec2i(x, y));
203
			ball->grab_ball(PAN_ACTION, Vec2i(x, y));
182
	}
204
	}
183
	else if(state == GLUT_UP)
205
	else if(state == GLUT_UP)
184
		ball->release_ball();	
206
		ball->release_ball();	
185
}
207
}
186
 
208
 
187
void spin(int x)
209
void spin(int x)
188
{
210
{
189
	ball->do_spin();
211
	ball->do_spin();
190
	glutTimerFunc(spin_timer, spin, 0);  
212
	glutTimerFunc(spin_timer, spin, 0);  
191
	glutPostRedisplay();
213
	glutPostRedisplay();
192
}
214
}
193
 
215
 
194
void display()
216
void display()
195
{
217
{
196
	static unsigned int l;
218
	static unsigned int l;
197
    if(redo_display_list)
219
    if(redo_display_list)
198
    {
220
    {
199
        cout << "Creating display list" << endl;
221
        cout << "Creating display list" << endl;
200
        l = glGenLists(1);
222
        l = glGenLists(1);
201
        glNewList(l, GL_COMPILE);
223
        glNewList(l, GL_COMPILE);
202
        draw(mesh, per_vertex_normals);
224
        draw(mesh, per_vertex_normals);
203
        glEndList();
225
        glEndList();
204
        redo_display_list = false;
226
        redo_display_list = false;
205
		glutTimerFunc(spin_timer, spin, 0);	
227
		glutTimerFunc(spin_timer, spin, 0);	
206
	}
228
	}
207
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
229
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
208
    glLoadIdentity();
230
    glLoadIdentity();
209
    ball->set_gl_modelview();
231
    ball->set_gl_modelview();
210
	
232
	
211
	if(do_wireframe)
233
	if(do_wireframe)
212
	{
234
	{
213
		if(GLEW_EXT_geometry_shader4)
235
		if(GLEW_EXT_geometry_shader4)
214
		{
236
		{
215
			enable_wireframe();
237
			enable_wireframe();
216
			glCallList(l);
238
			glCallList(l);
217
			glUseProgram(0);
239
			glUseProgram(0);
218
		}
240
		}
219
		else
241
		else
220
		{
242
		{
221
			glDisable(GL_LIGHTING);
243
			glDisable(GL_LIGHTING);
222
			glColor3f(1,1,1);
244
			glColor3f(1,1,1);
223
			glCallList(l);
245
			glCallList(l);
224
			glEnable(GL_POLYGON_OFFSET_LINE);
246
			glEnable(GL_POLYGON_OFFSET_LINE);
225
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
247
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
226
			glColor3fv(line_col.get());
248
			glColor3fv(line_col.get());
227
			glPolygonOffset(0,-5);
249
			glPolygonOffset(0,-5);
228
			glCallList(l);
250
			glCallList(l);
229
			glEnable(GL_LIGHTING);
251
			glEnable(GL_LIGHTING);
230
			glDisable(GL_POLYGON_OFFSET_LINE);
252
			glDisable(GL_POLYGON_OFFSET_LINE);
231
			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
253
			glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
232
		}
254
		}
233
	}
255
	}
234
	else
256
	else
235
		glCallList(l);
257
		glCallList(l);
236
		
258
		
237
    glutSwapBuffers();
259
    glutSwapBuffers();
238
}
260
}
239
 
261
 
240
void keyboard(unsigned char key, int x, int y)
262
void keyboard(unsigned char key, int x, int y)
241
{
263
{
242
    switch(key)
264
    switch(key)
243
    {
265
    {
244
		case '\033': exit(0); break;
266
		case '\033': exit(0); break;
245
		case 'w': do_wireframe = !do_wireframe; break;
267
		case 'w': do_wireframe = !do_wireframe; break;
246
		case 'f': per_vertex_normals = !per_vertex_normals; redo_display_list = true; break;
268
		case 'f': per_vertex_normals = !per_vertex_normals; redo_display_list = true; break;
-
 
269
    case 't': 
-
 
270
        do_textures = !do_textures; 
-
 
271
        if(do_textures) 
-
 
272
          enable_textures(mesh); 
-
 
273
        else 
-
 
274
          disable_textures(mesh); 
-
 
275
        redo_display_list = true; 
-
 
276
        break;
247
    }
277
    }
248
}
278
}
249
 
279
 
250
 
-
 
251
int main(int argc, char** argv)
280
int main(int argc, char** argv)
252
{
281
{
253
	Util::ArgExtracter ae(argc, argv);
282
	Util::ArgExtracter ae(argc, argv);
254
	
283
	
255
	bool redo_normals = ae.extract("-n");
284
	bool redo_normals = ae.extract("-n");
256
 
285
 
257
    // GLUT INIT
286
    // GLUT INIT
258
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
287
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
259
    glutInitWindowSize(win_size_x, win_size_y);
288
    glutInitWindowSize(win_size_x, win_size_y);
260
    glutInit(&argc, argv);
289
    glutInit(&argc, argv);
261
    main_window = glutCreateWindow("OBJ Viewer");
290
    main_window = glutCreateWindow("OBJ Viewer");
262
    glutDisplayFunc(display);
291
    glutDisplayFunc(display);
263
    glutKeyboardFunc(keyboard);
292
    glutKeyboardFunc(keyboard);
264
    glutMotionFunc(mouse_motion);
293
    glutMotionFunc(mouse_motion);
265
    glutMouseFunc(mouse);
294
    glutMouseFunc(mouse);
266
    //glutIdleFunc(idle);
295
    //glutIdleFunc(idle);
267
	
296
	
268
	glewInit();
297
	glewInit();
269
	
298
	
270
    // GL INIT
299
    // GL INIT
271
    glClearColor(.8f, 0.9f, 1.0f, 0.f);
300
    glClearColor(.8f, 0.9f, 1.0f, 0.f);
272
    glEnable(GL_DEPTH_TEST);
301
    glEnable(GL_DEPTH_TEST);
273
    glEnable(GL_LIGHTING);
302
    glEnable(GL_LIGHTING);
274
    glEnable(GL_LIGHT0);
303
    glEnable(GL_LIGHT0);
275
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
304
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
276
    glShadeModel(GL_SMOOTH);
305
    glShadeModel(GL_SMOOTH);
277
	
306
	
278
    // LOAD OBJ
307
    // LOAD OBJ
279
    string fn;
308
    string fn;
280
    if(ae.no_remaining_args())
309
    if(ae.no_remaining_args())
281
        fn = ae.get_last_arg();
310
        fn = ae.get_last_arg();
282
    else
311
    else
283
        fn = "../../data/head.obj";
312
        fn = "../../data/head.obj";
284
	
313
	
285
	load_mesh(fn);	
314
	load_mesh(fn);	
286
	
315
	
287
	if(!mesh.has_normals() || redo_normals)
316
	if(!mesh.has_normals() || redo_normals)
288
	{
317
	{
289
		cout << "Computing normals" << endl;
318
		cout << "Computing normals" << endl;
290
		mesh.compute_normals();
319
		mesh.compute_normals();
291
	}
320
	}
292
	
321
	
293
	// Initialize Trackball
322
	// Initialize Trackball
294
	Vec3f c;
323
	Vec3f c;
295
	float r;
324
	float r;
296
	mesh.get_bsphere(c,r);
325
	mesh.get_bsphere(c,r);
297
	r *= 1.5;
326
	r *= 1.5;
298
	ball = new QuatTrackBall(c,r,800,800);
327
	ball = new QuatTrackBall(c,r,800,800);
299
	
328
	
300
	// Setup projection
329
	// Setup projection
301
	glMatrixMode(GL_PROJECTION);
330
	glMatrixMode(GL_PROJECTION);
302
	glLoadIdentity();
331
	glLoadIdentity();
303
	gluPerspective(53,1.0f,r/100.0,r*3.0);
332
	gluPerspective(53,1.0f,r/100.0,r*3.0);
304
	glMatrixMode(GL_MODELVIEW);
333
	glMatrixMode(GL_MODELVIEW);
305
	
334
	
306
	if(GLEW_EXT_geometry_shader4)
335
	if(GLEW_EXT_geometry_shader4)
307
		initialize_wireframe_shaders();
336
		initialize_wireframe_shaders();
308
			
337
			
309
	
338
	
310
	// Pass control to GLUT
339
	// Pass control to GLUT
311
	glutMainLoop();
340
	glutMainLoop();
312
	
341
	
313
	return 0;
342
	return 0;
314
}
343
}
315
 
344