Subversion Repositories gelsvn

Rev

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

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