Subversion Repositories gelsvn

Rev

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

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