Subversion Repositories gelsvn

Rev

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

Rev 596 Rev 630
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 <fstream>
31
#include <fstream>
32
#include <iostream>
32
#include <iostream>
33
#include <vector>
33
#include <vector>
34
 
34
 
35
#include <Util/ArgExtracter.h>
35
#include <Util/ArgExtracter.h>
36
#include <CGLA/Vec2i.h>
36
#include <CGLA/Vec2i.h>
37
#include <CGLA/Vec2f.h>
37
#include <CGLA/Vec2f.h>
38
#include <CGLA/Vec3f.h>
38
#include <CGLA/Vec3f.h>
39
#include <CGLA/Mat4x4f.h>
39
#include <CGLA/Mat4x4f.h>
40
#include "GLGraphics/glsl_shader.h"
40
#include "GLGraphics/glsl_shader.h"
41
#include "GLGraphics/gel_glut.h"
41
#include "GLGraphics/gel_glut.h"
42
#include "GLGraphics/QuatTrackBall.h"
42
#include "GLGraphics/QuatTrackBall.h"
43
#include "GLGraphics/draw.h"
43
#include "GLGraphics/draw.h"
44
#include "GLGraphics/SOIL.h"
44
#include "GLGraphics/SOIL.h"
45
#include "Geometry/TriMesh.h"
45
#include "Geometry/TriMesh.h"
46
#include "Geometry/load.h"
46
#include "Geometry/load.h"
47
#include "Geometry/GridAlgorithm.h"
47
#include "Geometry/GridAlgorithm.h"
48
#include "Geometry/HGrid.h"
48
#include "Geometry/HGrid.h"
49
//#include "HMesh/x3d_load.h"
49
//#include "HMesh/x3d_load.h"
50
//#include "HMesh/FaceCirculator.h"
50
//#include "HMesh/FaceCirculator.h"
51
 
51
 
52
using namespace std;
52
using namespace std;
53
using namespace CGLA;
53
using namespace CGLA;
54
using namespace Geometry;
54
using namespace Geometry;
55
using namespace HMesh;
55
using namespace HMesh;
56
using namespace GLGraphics;
56
using namespace GLGraphics;
57
 
57
 
58
int win_size_x = 800;
58
int win_size_x = 800;
59
int win_size_y = 800;
59
int win_size_y = 800;
60
bool per_vertex_normals = 1;
60
bool per_vertex_normals = 1;
61
bool redo_display_list = 1;
61
bool redo_display_list = 1;
62
bool do_wireframe = false;
62
bool do_wireframe = false;
63
Vec3f line_col = Vec3f(1,0,0);
63
Vec3f line_col = Vec3f(1,0,0);
64
QuatTrackBall* ball;
64
QuatTrackBall* ball;
65
int spin_timer = 20;
65
int spin_timer = 20;
66
void spin(int x);
66
void spin(int x);
67
int main_window;
67
int main_window;
68
TriMesh mesh;
68
TriMesh mesh;
69
bool do_textures = true;
69
bool do_textures = true;
70
 
70
 
71
 
71
 
72
bool depth_pick(int x, int y,Vec3f& wp)
72
bool depth_pick(int x, int y,Vec3f& wp)
73
{
73
{
74
	// Enquire about the viewport dimensions
74
	// Enquire about the viewport dimensions
75
	GLint viewport[4];
75
	GLint viewport[4];
76
	glGetIntegerv(GL_VIEWPORT, viewport);
76
	glGetIntegerv(GL_VIEWPORT, viewport);
77
	
77
	
78
	// Get the minimum and maximum depth values.
78
	// Get the minimum and maximum depth values.
79
	float minmax_depth[2];
79
	float minmax_depth[2];
80
	glGetFloatv(GL_DEPTH_RANGE, minmax_depth);
80
	glGetFloatv(GL_DEPTH_RANGE, minmax_depth);
81
	
81
	
82
	// Read a single pixel at the position of the mouse cursor.
82
	// Read a single pixel at the position of the mouse cursor.
83
	float depth;
83
	float depth;
84
	glReadPixels(x, viewport[3]-y, 1,1, GL_DEPTH_COMPONENT,
84
	glReadPixels(x, viewport[3]-y, 1,1, GL_DEPTH_COMPONENT,
85
				 GL_FLOAT, (void*) &depth);
85
				 GL_FLOAT, (void*) &depth);
86
	
86
	
87
	// If the depth corresponds to the far plane, we clicked on the
87
	// If the depth corresponds to the far plane, we clicked on the
88
	// background.
88
	// background.
89
	if(depth == minmax_depth[1])
89
	if(depth == minmax_depth[1])
90
		return false;
90
		return false;
91
	
91
	
92
	// The lines below copy the viewing transformation from OpenGL
92
	// The lines below copy the viewing transformation from OpenGL
93
	// to local variables. The call to gluLookAt must have exactly
93
	// to local variables. The call to gluLookAt must have exactly
94
	// the same parameters as when the scene is drawn.
94
	// the same parameters as when the scene is drawn.
95
	glLoadIdentity();
95
	glLoadIdentity();
96
	ball->set_gl_modelview();
96
	ball->set_gl_modelview();
97
	double mvmat[16];
97
	double mvmat[16];
98
	glGetDoublev(GL_MODELVIEW_MATRIX, mvmat);
98
	glGetDoublev(GL_MODELVIEW_MATRIX, mvmat);
99
	
99
	
100
	// Copy the projection matrix. We assume it is unchanged.
100
	// Copy the projection matrix. We assume it is unchanged.
101
	double prjmat[16];
101
	double prjmat[16];
102
	glGetDoublev(GL_PROJECTION_MATRIX, prjmat);
102
	glGetDoublev(GL_PROJECTION_MATRIX, prjmat);
103
	
103
	
104
	// Now unproject the point from screen to world coordinates.
104
	// Now unproject the point from screen to world coordinates.
105
	double ox, oy, oz;
105
	double ox, oy, oz;
106
	gluUnProject(x,viewport[3]-y,depth,
106
	gluUnProject(x,viewport[3]-y,depth,
107
				 mvmat,prjmat,viewport,
107
				 mvmat,prjmat,viewport,
108
				 &ox, &oy, &oz);
108
				 &ox, &oy, &oz);
109
	
109
	
110
	wp = Vec3f(ox,oy,oz);
110
	wp = Vec3f(ox,oy,oz);
111
	
111
	
112
	return true;
112
	return true;
113
}
113
}
114
 
114
 
115
 
115
 
116
void mouse_motion(int x, int y)
116
void mouse_motion(int x, int y)
117
{
117
{
118
    ball->roll_ball(Vec2i(x,y));
118
    ball->roll_ball(Vec2i(x,y));
119
}
119
}
120
 
120
 
121
void mouse(int btn, int state, int x, int y)
121
void mouse(int btn, int state, int x, int y)
122
{
122
{
123
	if(state == GLUT_DOWN) 
123
	if(state == GLUT_DOWN) 
124
	{
124
	{
125
		if(btn == GLUT_LEFT_BUTTON) 
125
		if(btn == GLUT_LEFT_BUTTON) 
126
			ball->grab_ball(ROTATE_ACTION, Vec2i(x,y));
126
			ball->grab_ball(ROTATE_ACTION, Vec2i(x,y));
127
		else if(btn == GLUT_MIDDLE_BUTTON) 
127
		else if(btn == GLUT_MIDDLE_BUTTON) 
128
			ball->grab_ball(ZOOM_ACTION, Vec2i(x, y));
128
			ball->grab_ball(ZOOM_ACTION, Vec2i(x, y));
129
		else if(btn == GLUT_RIGHT_BUTTON) 
129
		else if(btn == GLUT_RIGHT_BUTTON) 
130
			ball->grab_ball(PAN_ACTION, Vec2i(x, y));
130
			ball->grab_ball(PAN_ACTION, Vec2i(x, y));
131
	}
131
	}
132
	else if(state == GLUT_UP)
132
	else if(state == GLUT_UP)
133
		ball->release_ball();	
133
		ball->release_ball();	
134
}
134
}
135
 
135
 
136
void spin(int x)
136
void spin(int x)
137
{
137
{
138
	ball->do_spin();
138
	ball->do_spin();
139
	glutTimerFunc(spin_timer, spin, 0);  
139
	glutTimerFunc(spin_timer, spin, 0);  
140
	glutPostRedisplay();
140
	glutPostRedisplay();
141
}
141
}
142
 
142
 
143
void setupshader()
143
void setupshader()
144
{
144
{
145
	static GLuint vs,fs,prog;
145
	static GLuint vs,fs,prog;
146
	static bool was_here = false;
146
	static bool was_here = false;
147
	if(!was_here)
147
	if(!was_here)
148
	{
148
	{
149
		was_here = true;
149
		was_here = true;
150
		const string vss = 
150
		const string vss = 
151
		"varying vec3 n;\n"
151
		"varying vec3 n;\n"
152
		"varying vec3 v;\n"
152
		"varying vec3 v;\n"
153
		"varying vec3 v_obj;\n"
153
		"varying vec3 v_obj;\n"
154
		"\n"
154
		"\n"
155
		"void main(void)\n"
155
		"void main(void)\n"
156
		"{\n"
156
		"{\n"
157
		"	gl_Position = ftransform();\n"
157
		"	gl_Position = ftransform();\n"
158
		"   v_obj = gl_Vertex.xyz;\n"
158
		"   v_obj = gl_Vertex.xyz;\n"
159
		"	v = vec3(gl_ModelViewMatrix * gl_Vertex);\n"
159
		"	v = vec3(gl_ModelViewMatrix * gl_Vertex);\n"
160
		"	n = normalize(gl_NormalMatrix * gl_Normal);\n"
160
		"	n = normalize(gl_NormalMatrix * gl_Normal);\n"
161
		"}\n"
161
		"}\n"
162
		"\n";
162
		"\n";
163
		
163
		
164
		const string fss =
164
		const string fss =
165
		"varying vec3 n;\n"
165
		"varying vec3 n;\n"
166
		"varying vec3 v;\n"
166
		"varying vec3 v;\n"
167
		"varying vec3 v_obj;\n"
167
		"varying vec3 v_obj;\n"
168
		"\n"
168
		"\n"
169
		"vec4 glazed_shader(vec4 mat_col,  vec4 light_col, vec3 light_dir)\n"
169
		"vec4 glazed_shader(vec4 mat_col,  vec4 light_col, vec3 light_dir)\n"
170
		"{\n"
170
		"{\n"
171
		"	vec3 e = normalize(-v);\n"
171
		"	vec3 e = normalize(-v);\n"
172
		"	vec3 r = normalize(2.0*dot(e, n)*n - e);\n"
172
		"	vec3 r = normalize(2.0*dot(e, n)*n - e);\n"
173
		"	float d = max(0.05,dot(light_dir, n));\n"
173
		"	float d = max(0.05,dot(light_dir, n));\n"
174
		"	vec4 diff = mat_col * light_col *d; 	\n"
174
		"	vec4 diff = mat_col * light_col *d; 	\n"
175
		"	vec4 refl = smoothstep(0.7,0.75,dot(r,light_dir)) * light_col;\n"
175
		"	vec4 refl = smoothstep(0.7,0.75,dot(r,light_dir)) * light_col;\n"
176
		"	return 0.1*refl + 2.25*diff;\n"
176
		"	return 0.1*refl + 2.25*diff;\n"
177
		"}\n"
177
		"}\n"
178
		"\n"
178
		"\n"
179
		"void main(void)\n"
179
		"void main(void)\n"
180
		"{\n"
180
		"{\n"
181
		"	vec4 mat_col = vec4(0.7,0.6,1.0,1.0);\n"
181
		"	vec4 mat_col = vec4(0.7,0.6,1.0,1.0);\n"
182
		"	\n"
182
		"	\n"
183
		"	vec3 light0_dir = vec3(0.0,1.0,0.0);\n"
183
		"	vec3 light0_dir = vec3(0.0,1.0,0.0);\n"
184
		"	vec4 light0_col = vec4(0.9,0.95,0.95,1.0);\n"
184
		"	vec4 light0_col = vec4(0.9,0.95,0.95,1.0);\n"
185
		"	\n"
185
		"	\n"
186
		"	vec3 light1_dir = vec3(0.0,0.0,1.0);\n"
186
		"	vec3 light1_dir = vec3(0.0,0.0,1.0);\n"
187
		"	vec4 light1_col = vec4(.8,.8,.6,1.0);\n"
187
		"	vec4 light1_col = vec4(.8,.8,.6,1.0);\n"
188
		"	\n"
188
		"	\n"
189
		"	gl_FragColor = \n"
189
		"	gl_FragColor = \n"
190
		"	0.5*glazed_shader(mat_col, light0_col, light0_dir)+\n"
190
		"	0.5*glazed_shader(mat_col, light0_col, light0_dir)+\n"
191
		"	0.5*glazed_shader(mat_col, light1_col, light1_dir);\n"
191
		"	0.5*glazed_shader(mat_col, light1_col, light1_dir);\n"
192
		"	\n"
192
		"	\n"
193
		"	gl_FragColor.a = 1.0;\n"
193
		"	gl_FragColor.a = 1.0;\n"
194
		"}\n";
194
		"}\n";
195
		
195
		
196
		vs = create_glsl_shader(GL_VERTEX_SHADER, vss);
196
		vs = create_glsl_shader(GL_VERTEX_SHADER, vss);
197
		print_glsl_program_log(vs);
197
		print_glsl_program_log(vs);
198
		
198
		
199
		fs = create_glsl_shader(GL_FRAGMENT_SHADER, fss);
199
		fs = create_glsl_shader(GL_FRAGMENT_SHADER, fss);
200
		print_glsl_program_log(fs);
200
		print_glsl_program_log(fs);
201
		
201
		
202
		prog = glCreateProgram();
202
		prog = glCreateProgram();
203
		
203
		
204
		if(vs) glAttachShader(prog, vs);
204
		if(vs) glAttachShader(prog, vs);
205
		if(fs) glAttachShader(prog, fs);
205
		if(fs) glAttachShader(prog, fs);
206
		
206
		
207
		glLinkProgram(prog);
207
		glLinkProgram(prog);
208
		print_glsl_program_log(prog);
208
		print_glsl_program_log(prog);
209
	}
209
	}
210
	glUseProgram(prog);
210
	glUseProgram(prog);
211
	
211
	
212
}
212
}
213
 
213
 
214
void display()
214
void display()
215
{
215
{
216
	static unsigned int l;
216
	static unsigned int l;
217
    if(redo_display_list)
217
    if(redo_display_list)
218
    {
218
    {
219
        cout << "Creating display list" << endl;
219
        cout << "Creating display list" << endl;
220
        l = glGenLists(1);
220
        l = glGenLists(1);
221
        glNewList(l, GL_COMPILE);
221
        glNewList(l, GL_COMPILE);
222
        draw(mesh, per_vertex_normals);
222
        draw(mesh, per_vertex_normals);
223
        glEndList();
223
        glEndList();
224
        redo_display_list = false;
224
        redo_display_list = false;
225
		glutTimerFunc(spin_timer, spin, 0);	
225
		glutTimerFunc(spin_timer, spin, 0);	
226
	}
226
	}
227
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
227
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
228
    glLoadIdentity();
228
    glLoadIdentity();
229
    ball->set_gl_modelview();
229
    ball->set_gl_modelview();
230
	if(do_wireframe)
230
	if(do_wireframe)
231
	{
231
	{
232
		if(GLEW_EXT_geometry_shader4)
232
		if(GLEW_EXT_geometry_shader4)
233
			draw_triangles_in_wireframe(mesh, per_vertex_normals, Vec3f(1,0,0));
233
			draw_triangles_in_wireframe(mesh, per_vertex_normals, Vec3f(1,0,0));
234
		else
234
		else
235
			draw_wireframe_oldfashioned(mesh, per_vertex_normals, Vec3f(1,0,0));
235
			draw_wireframe_oldfashioned(mesh, per_vertex_normals, Vec3f(1,0,0));
236
	}
236
	}
237
	else if(!do_textures)
237
	else if(!do_textures)
238
	{
238
	{
239
		setupshader();	
239
		setupshader();	
240
		glCallList(l);
240
		glCallList(l);
241
	}
241
	}
242
	else
242
	else
243
		glCallList(l);
243
		glCallList(l);
244
	
244
	
245
    glutSwapBuffers();
245
    glutSwapBuffers();
246
}
246
}
247
 
247
 
248
void keyboard(unsigned char key, int x, int y)
248
void keyboard(unsigned char key, int x, int y)
249
{
249
{
250
    switch(key)
250
    switch(key)
251
    {
251
    {
252
		case '\033': exit(0); break;
252
		case '\033': exit(0); break;
253
		case 'w': do_wireframe = !do_wireframe; break;
253
		case 'w': do_wireframe = !do_wireframe; break;
254
		case 'f': per_vertex_normals = !per_vertex_normals; redo_display_list = true; break;
254
		case 'f': per_vertex_normals = !per_vertex_normals; redo_display_list = true; break;
255
		case 's': 
255
		case 's': 
256
		{
256
		{
257
			ofstream f("ball.out", ios::binary);
257
			ofstream f("ball.out", ios::binary);
258
			if(f) f.write(reinterpret_cast<const char*>(ball),sizeof(QuatTrackBall));
258
			if(f) f.write(reinterpret_cast<const char*>(ball),sizeof(QuatTrackBall));
259
		}
259
		}
260
		break;
260
		break;
261
		case 'l':
261
		case 'l':
262
		{
262
		{
263
			ifstream f("ball.out", ios::binary);
263
			ifstream f("ball.out", ios::binary);
264
			if(f) f.read(reinterpret_cast<char*>(ball),sizeof(QuatTrackBall));
264
			if(f) f.read(reinterpret_cast<char*>(ball),sizeof(QuatTrackBall));
265
		}
265
		}
266
			break;
266
			break;
267
		case 't': do_textures = !do_textures;
267
		case 't': do_textures = !do_textures;
268
			break;
268
			break;
269
    }
269
    }
270
	redo_display_list=true;
270
	redo_display_list=true;
271
}
271
}
272
 
272
 
273
int main(int argc, char** argv)
273
int main(int argc, char** argv)
274
{
274
{
275
	Util::ArgExtracter ae(argc, argv);
275
	Util::ArgExtracter ae(argc, argv);
276
	
276
	
277
	bool redo_normals = ae.extract("-n");
277
	bool redo_normals = ae.extract("-n");
278
	
278
	
279
    // GLUT INIT
279
    // GLUT INIT
280
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
280
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
281
    glutInitWindowSize(win_size_x, win_size_y);
281
    glutInitWindowSize(win_size_x, win_size_y);
282
    glutInit(&argc, argv);
282
    glutInit(&argc, argv);
283
    main_window = glutCreateWindow("OBJ Viewer");
283
    main_window = glutCreateWindow("OBJ Viewer");
284
    glutDisplayFunc(display);
284
    glutDisplayFunc(display);
285
    glutKeyboardFunc(keyboard);
285
    glutKeyboardFunc(keyboard);
286
    glutMotionFunc(mouse_motion);
286
    glutMotionFunc(mouse_motion);
287
    glutMouseFunc(mouse);
287
    glutMouseFunc(mouse);
288
    //glutIdleFunc(idle);
288
    //glutIdleFunc(idle);
289
	
289
	
290
	glewInit();
290
	glewInit();
291
	
291
	
292
    // GL INIT
292
    // GL INIT
293
    glClearColor(.8f, 0.9f, 1.0f, 0.f);
293
    glClearColor(.8f, 0.9f, 1.0f, 0.f);
294
    glEnable(GL_DEPTH_TEST);
294
    glEnable(GL_DEPTH_TEST);
295
    glEnable(GL_LIGHTING);
295
    glEnable(GL_LIGHTING);
296
    glEnable(GL_LIGHT0);
296
    glEnable(GL_LIGHT0);
297
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
297
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
298
    glShadeModel(GL_SMOOTH);
298
    glShadeModel(GL_SMOOTH);
299
	
299
	
300
    // LOAD OBJ
300
    // LOAD OBJ
301
    string fn;
301
    string fn;
302
    int arg_no = ae.no_remaining_args();
302
    int arg_no = ae.no_remaining_args();
303
    if(arg_no>1)
303
    if(arg_no>1)
304
        fn = ae.get_last_arg();
304
        fn = ae.get_last_arg();
305
    else
305
    else
306
        fn = "../../data/head.obj";
306
        fn = "../../data/head.obj";
307
	
307
	
308
	load(fn, mesh);
308
	load(fn, mesh);
309
	load_textures(mesh);
309
	load_textures(mesh);
310
	
310
	
311
	if(!mesh.has_normals() || redo_normals)
311
	if(!mesh.has_normals() || redo_normals)
312
	{
312
	{
313
		cout << "Computing normals" << endl;
313
		cout << "Computing normals" << endl;
314
		mesh.compute_normals();
314
		mesh.compute_normals();
315
	}
315
	}
316
	
316
	
317
	// Initialize Trackball
317
	// Initialize Trackball
318
	Vec3f c;
318
	Vec3f c;
319
	float r;
319
	float r;
320
	mesh.get_bsphere(c,r);
320
	mesh.get_bsphere(c,r);
321
	r *= 1.5;
321
	r *= 1.5;
322
	ball = new QuatTrackBall(c,r,800,800);
322
	ball = new QuatTrackBall(c,r,800,800);
323
	
323
	
324
	// Setup projection
324
	// Setup projection
325
	glMatrixMode(GL_PROJECTION);
325
	glMatrixMode(GL_PROJECTION);
326
	glLoadIdentity();
326
	glLoadIdentity();
327
	gluPerspective(53,1.0f,r/100.0,r*3.0);
327
	gluPerspective(53,1.0f,r/100.0,r*3.0);
328
	glMatrixMode(GL_MODELVIEW);
328
	glMatrixMode(GL_MODELVIEW);
329
	
329
	
330
	// Pass control to GLUT
330
	// Pass control to GLUT
331
	glutMainLoop();
331
	glutMainLoop();
332
	
332
	
333
	return 0;
333
	return 0;
334
}
334
}
335
 
335