Subversion Repositories gelsvn

Rev

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

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