Subversion Repositories gelsvn

Rev

Rev 492 | Rev 596 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
82 jab 1
// ----------------------------------------
2
// A simple OBJ viewer.
178 bj 3
//
82 jab 4
// Controls:
5
// - left mouse down + mouse motion : rotate
6
// - Scroll button and +- buttons   : zoom
7
// - right mouse click              : centre trackball
8
// - esc                            : exits
178 bj 9
// - x,y,z buttons                  : switch trackball up axis
374 jrf 10
// - w                              : toggle wireframe on/off
11
// - t                              : toggle texture on/off
12
// - f                              : switch between vertex and face normals
82 jab 13
// ----------------------------------------
14
 
195 jrf 15
#include <iostream>
492 jrf 16
#include <string>
17
#include <GL/glew.h>
18
#include "Util/ArgExtracter.h"
19
#include "CGLA/Vec2i.h"
20
#include "CGLA/Vec3f.h"
178 bj 21
#include "GLGraphics/gel_glut.h"
299 jrf 22
#include "GLGraphics/QuatTrackBall.h"
178 bj 23
#include "GLGraphics/draw.h"
82 jab 24
#include "Geometry/TriMesh.h"
442 jab 25
#include "Geometry/load.h"
337 jab 26
 
82 jab 27
using namespace std;
28
using namespace CGLA;
29
using namespace Geometry;
178 bj 30
using namespace GLGraphics;
82 jab 31
 
370 jab 32
int win_size_x = 800;
33
int win_size_y = 800;
34
bool per_vertex_normals = 1;
35
bool redo_display_list = 1;
36
bool do_wireframe = false;
37
Vec3f line_col = Vec3f(1,0,0);
38
QuatTrackBall* ball;
39
int spin_timer = 20;
40
void spin(int x);
41
int main_window;
42
TriMesh mesh;
374 jrf 43
bool do_textures = true;
370 jab 44
 
374 jrf 45
 
370 jab 46
bool depth_pick(int x, int y,Vec3f& wp)
47
{
48
	// Enquire about the viewport dimensions
49
	GLint viewport[4];
50
	glGetIntegerv(GL_VIEWPORT, viewport);
51
 
52
	// Get the minimum and maximum depth values.
53
	float minmax_depth[2];
54
	glGetFloatv(GL_DEPTH_RANGE, minmax_depth);
55
 
56
	// Read a single pixel at the position of the mouse cursor.
57
	float depth;
58
	glReadPixels(x, viewport[3]-y, 1,1, GL_DEPTH_COMPONENT,
59
				 GL_FLOAT, (void*) &depth);
60
 
61
	// If the depth corresponds to the far plane, we clicked on the
62
	// background.
63
	if(depth == minmax_depth[1])
64
		return false;
65
 
66
	// The lines below copy the viewing transformation from OpenGL
67
	// to local variables. The call to gluLookAt must have exactly
68
	// the same parameters as when the scene is drawn.
69
	glLoadIdentity();
70
	ball->set_gl_modelview();
71
	double mvmat[16];
72
	glGetDoublev(GL_MODELVIEW_MATRIX, mvmat);
73
 
74
	// Copy the projection matrix. We assume it is unchanged.
75
	double prjmat[16];
76
	glGetDoublev(GL_PROJECTION_MATRIX, prjmat);
77
 
78
	// Now unproject the point from screen to world coordinates.
79
	double ox, oy, oz;
80
	gluUnProject(x,viewport[3]-y,depth,
81
				 mvmat,prjmat,viewport,
82
				 &ox, &oy, &oz);
83
 
84
	wp = Vec3f(ox,oy,oz);
85
 
86
	return true;
87
}
88
 
89
 
90
 
91
void mouse_motion(int x, int y)
92
{
93
    ball->roll_ball(Vec2i(x,y));
94
}
95
 
96
void mouse(int btn, int state, int x, int y)
97
{
98
	if(state == GLUT_DOWN) 
368 jrf 99
	{
370 jab 100
		if(btn == GLUT_LEFT_BUTTON) 
101
			ball->grab_ball(ROTATE_ACTION, Vec2i(x,y));
102
		else if(btn == GLUT_MIDDLE_BUTTON) 
103
			ball->grab_ball(ZOOM_ACTION, Vec2i(x, y));
104
		else if(btn == GLUT_RIGHT_BUTTON) 
105
			ball->grab_ball(PAN_ACTION, Vec2i(x, y));
368 jrf 106
	}
370 jab 107
	else if(state == GLUT_UP)
108
		ball->release_ball();	
109
}
368 jrf 110
 
370 jab 111
void spin(int x)
112
{
113
	ball->do_spin();
114
	glutTimerFunc(spin_timer, spin, 0);  
115
	glutPostRedisplay();
116
}
117
 
118
void display()
119
{
120
	static unsigned int l;
121
    if(redo_display_list)
122
    {
123
        cout << "Creating display list" << endl;
124
        l = glGenLists(1);
125
        glNewList(l, GL_COMPILE);
126
        draw(mesh, per_vertex_normals);
127
        glEndList();
128
        redo_display_list = false;
129
		glutTimerFunc(spin_timer, spin, 0);	
368 jrf 130
	}
370 jab 131
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
132
    glLoadIdentity();
133
    ball->set_gl_modelview();
337 jab 134
 
370 jab 135
	if(do_wireframe)
357 jab 136
	{
370 jab 137
		if(GLEW_EXT_geometry_shader4)
398 jab 138
			draw_triangles_in_wireframe(mesh, per_vertex_normals, Vec3f(1,0,0));
370 jab 139
		else
398 jab 140
			draw_wireframe_oldfashioned(mesh, per_vertex_normals, Vec3f(1,0,0));
357 jab 141
	}
370 jab 142
	else
143
		glCallList(l);
337 jab 144
 
370 jab 145
    glutSwapBuffers();
146
}
82 jab 147
 
370 jab 148
void keyboard(unsigned char key, int x, int y)
149
{
150
    switch(key)
151
    {
152
		case '\033': exit(0); break;
153
		case 'w': do_wireframe = !do_wireframe; break;
154
		case 'f': per_vertex_normals = !per_vertex_normals; redo_display_list = true; break;
374 jrf 155
        break;
370 jab 156
    }
442 jab 157
	redo_display_list=true;
370 jab 158
}
82 jab 159
 
160
int main(int argc, char** argv)
178 bj 161
{
370 jab 162
	Util::ArgExtracter ae(argc, argv);
163
 
164
	bool redo_normals = ae.extract("-n");
165
 
178 bj 166
    // GLUT INIT
167
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
168
    glutInitWindowSize(win_size_x, win_size_y);
169
    glutInit(&argc, argv);
170
    main_window = glutCreateWindow("OBJ Viewer");
171
    glutDisplayFunc(display);
172
    glutKeyboardFunc(keyboard);
173
    glutMotionFunc(mouse_motion);
174
    glutMouseFunc(mouse);
337 jab 175
 
370 jab 176
	glewInit();
357 jab 177
 
178 bj 178
    // GL INIT
179
    glClearColor(.8f, 0.9f, 1.0f, 0.f);
180
    glEnable(GL_DEPTH_TEST);
181
    glEnable(GL_LIGHTING);
182
    glEnable(GL_LIGHT0);
183
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
184
    glShadeModel(GL_SMOOTH);
337 jab 185
 
178 bj 186
    // LOAD OBJ
187
    string fn;
555 jrf 188
    if(ae.no_remaining_args() > 1)
370 jab 189
        fn = ae.get_last_arg();
178 bj 190
    else
191
        fn = "../../data/head.obj";
370 jab 192
 
442 jab 193
	load(fn, mesh);
194
	load_textures(mesh);
370 jab 195
 
196
	if(!mesh.has_normals() || redo_normals)
337 jab 197
	{
370 jab 198
		cout << "Computing normals" << endl;
199
		mesh.compute_normals();
337 jab 200
	}
201
 
370 jab 202
	// Initialize Trackball
203
	Vec3f c;
204
	float r;
205
	mesh.get_bsphere(c,r);
206
	r *= 1.5;
207
	ball = new QuatTrackBall(c,r,800,800);
337 jab 208
 
370 jab 209
	// Setup projection
210
	glMatrixMode(GL_PROJECTION);
211
	glLoadIdentity();
212
	gluPerspective(53,1.0f,r/100.0,r*3.0);
213
	glMatrixMode(GL_MODELVIEW);
398 jab 214
 
370 jab 215
	// Pass control to GLUT
216
	glutMainLoop();
217
 
218
	return 0;
82 jab 219
}