Subversion Repositories gelsvn

Rev

Rev 102 | Rev 132 | 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.
3
// 
4
// Controls:
5
// - left mouse down + mouse motion : rotate
6
// - Scroll button and +- buttons   : zoom
7
// - right mouse click              : centre trackball
8
// - esc                            : exits
9
// - x,y,z buttons                  : switch trackball up axis 
10
// ----------------------------------------
11
 
102 bj 12
#if (_MSC_VER >= 1200)
82 jab 13
#pragma warning (disable: 4786)
102 bj 14
#endif
82 jab 15
 
16
#include <list>
17
#include <vector>
18
 
19
#include <CGLA/Vec3f.h>
20
#include <CGLA/Mat4x4f.h>
125 jab 21
#if defined(__APPLE__) && defined(__MACH__)
22
#include <GLUT/glut.h>
23
#else
82 jab 24
#include <GL/glut.h>
125 jab 25
#endif
26
 
82 jab 27
#include "Geometry/TriMesh.h"
28
#include "Graphics/SimpleTrackBall.h"
29
#include "Geometry/obj_load.h"
30
 
31
using namespace std;
32
using namespace CGLA;
33
using namespace Geometry;
34
using namespace Graphics;
35
 
36
namespace
37
{
38
	int win_size_x = 800;
39
	int win_size_y = 800;
40
 
41
	SimpleTrackBall* ball;
42
 
43
	int main_window; 
44
 
45
 
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->gl_view();
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
	TriMesh mesh;
91
 
92
	void mouse_motion(int x, int y)
93
	{
94
		ball->roll(x,y);
95
	}
96
 
97
	void mouse(int button, int state, int x, int y)
98
	{
99
		if(button==GLUT_RIGHT_BUTTON && state==GLUT_DOWN)
100
			{
101
				Vec3f p;
102
				if(depth_pick(x, y, p))
103
					ball->set_center(p);
104
			}
105
		else if(button==3) 
106
			ball->farther(); 
107
		else if(button==4)
108
			ball->closer();
109
	}
110
 
111
	void idle()
112
	{
113
		if ( glutGetWindow() != main_window ) 
114
			glutSetWindow(main_window);  
115
		glutPostRedisplay();
116
	}
117
 
118
	void display() 
119
	{
120
			static bool washere = false;
121
			static unsigned int l;
122
			if(!washere)
123
			{
124
					cout << "Creating display list" << endl;
125
					l = glGenLists(1);
126
					glNewList(l, GL_COMPILE);
127
					mesh.gl_draw();
128
					glEndList();
129
					washere = true;
130
			}
131
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
132
			glLoadIdentity();
133
			ball->gl_view();
134
			glCallList(l);
135
			glutSwapBuffers();
136
	}
137
 
138
	void keyboard(unsigned char key, int x, int y) 
139
	{	
140
		switch(key) 
141
			{
142
			case '\033': exit(0); break;
143
			case '+': ball->closer(); break;
144
			case '-': ball->farther(); break;
145
			default:
146
				ball->up_axis(key);
147
			}
148
	}
149
}
150
 
151
int main(int argc, char** argv)
152
{ 
153
	// GLUT INIT
154
	glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
155
	glutInitWindowSize(win_size_x, win_size_y);
156
	glutInit(&argc, argv);
157
	main_window = glutCreateWindow("OBJ Viewer");
158
	glutDisplayFunc(display);
159
	glutKeyboardFunc(keyboard);
160
	glutMotionFunc(mouse_motion);
161
	glutMouseFunc(mouse);
162
	glutIdleFunc(idle);
163
 
164
	// GL INIT
165
	glClearColor(.8f, 0.9f, 1.0f, 0.f);
166
	glEnable(GL_DEPTH_TEST);
167
	glEnable(GL_LIGHTING);
168
	glEnable(GL_LIGHT0);
169
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
170
	glShadeModel(GL_SMOOTH);
171
 
172
	// LOAD OBJ
97 bj 173
	string fn;
174
	if(argc>1)
175
			fn = argv[1];
176
		else
177
			fn = "../../data/head.obj";
178
 
82 jab 179
	cout << "Loading " << fn << endl;
180
	if(fn == "") exit(0);
181
	obj_load(fn, mesh);
182
	if(!mesh.has_normals())
183
		{
184
			cout << "Computing normals" << endl;
185
			mesh.compute_normals();
186
		}
187
	// Initialize textures
188
	mesh.gl_init_textures();
189
 
190
	// Initialize Trackball
191
	Vec3f c;
192
	float r;
193
	mesh.get_bsphere(c,r);
194
	r *= 1.5;
195
	ball = new SimpleTrackBall(c,r);
196
 
197
	// Setup projection
198
	glMatrixMode(GL_PROJECTION);
199
	glLoadIdentity();
200
	gluPerspective(53,1.0f,r/100,r*3);
201
	glMatrixMode(GL_MODELVIEW);
202
 
203
	// Pass control to GLUT
204
	glutMainLoop();
205
 
206
	return 0;
207
}