Subversion Repositories gelsvn

Rev

Rev 600 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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