Subversion Repositories gelsvn

Rev

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

Rev 337 Rev 341
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
// ----------------------------------------
10
// ----------------------------------------
11
 
11
 
12
#if (_MSC_VER >= 1200)
12
#if (_MSC_VER >= 1200)
13
#pragma warning (disable: 4786)
13
#pragma warning (disable: 4786)
14
#endif
14
#endif
15
 
15
 
16
#include <list>
16
#include <list>
17
#include <vector>
17
#include <vector>
18
 
18
 
19
#include <assert.h>
19
#include <assert.h>
20
#include <stdio.h>
20
#include <stdio.h>
21
#ifdef WIN32
21
#ifdef WIN32
22
#include <windows.h>
22
#include <windows.h>
23
#include <io.h>
23
#include <io.h>
24
#endif
24
#endif
25
#include <string.h>
25
#include <string.h>
26
#include <stdlib.h>
26
#include <stdlib.h>
27
 
27
 
28
#include <iostream>
28
#include <iostream>
29
 
29
 
30
#include <IL/il.h>
30
#include <IL/il.h>
31
#include <IL/ilu.h>
31
#include <IL/ilu.h>
32
 
32
 
33
#include <CGLA/Vec2i.h>
33
#include <CGLA/Vec2i.h>
34
#include <CGLA/Vec2f.h>
34
#include <CGLA/Vec2f.h>
35
#include <CGLA/Vec3f.h>
35
#include <CGLA/Vec3f.h>
36
#include <CGLA/Mat4x4f.h>
36
#include <CGLA/Mat4x4f.h>
37
#include "GLGraphics/gel_glut.h"
37
#include "GLGraphics/gel_glut.h"
38
#include "GLGraphics/QuatTrackBall.h"
38
#include "GLGraphics/QuatTrackBall.h"
39
#include "GLGraphics/draw.h"
39
#include "GLGraphics/draw.h"
40
#include "Geometry/TriMesh.h"
40
#include "Geometry/TriMesh.h"
41
#include "Geometry/obj_load.h"
41
#include "Geometry/obj_load.h"
42
 
42
 
43
#include "ply_load.h"
43
#include "ply_load.h"
44
 
44
 
45
using namespace std;
45
using namespace std;
46
using namespace CGLA;
46
using namespace CGLA;
47
using namespace Geometry;
47
using namespace Geometry;
48
using namespace GLGraphics;
48
using namespace GLGraphics;
49
 
49
 
50
namespace
50
namespace
51
{
51
{
52
	int win_size_x = 800;
52
	int win_size_x = 800;
53
	int win_size_y = 800;
53
	int win_size_y = 800;
54
	QuatTrackBall* ball;
54
	QuatTrackBall* ball;
55
	int spin_timer = 20;
55
	int spin_timer = 20;
56
	void spin(int x);
56
	void spin(int x);
57
	int main_window;
57
	int main_window;
58
	TriMesh mesh;
58
	TriMesh mesh;
59
	
59
	
60
	
60
	
61
	bool load_image_into_texture(const std::string& name, GLuint& id)
61
	bool load_image_into_texture(const std::string& name, GLuint& id)
62
	{
62
	{
63
		unsigned char* image = 0;
63
		unsigned char* image = 0;
64
		unsigned int bpp = 0;
64
		unsigned int bpp = 0;
65
		unsigned int size_x = 0;
65
		unsigned int size_x = 0;
66
		unsigned int size_y = 0;
66
		unsigned int size_y = 0;
67
		unsigned int load_size_x = 0;
67
		unsigned int load_size_x = 0;
68
		unsigned int load_size_y = 0;
68
		unsigned int load_size_y = 0;
69
		
69
		
70
		
70
		
71
		ILenum Error;
71
		ILenum Error;
72
		ILuint  ImgId;
72
		ILuint  ImgId;
73
		
73
		
74
		static bool washere = false;
74
		static bool washere = false;
75
		if(!washere)
75
		if(!washere)
76
		{
76
		{
77
			ilInit();
77
			ilInit();
78
			iluInit();
78
			iluInit();
79
			washere=true;
79
			washere=true;
80
		}
80
		}
81
		ilEnable(IL_CONV_PAL);
81
		ilEnable(IL_CONV_PAL);
82
		ilEnable(IL_ORIGIN_SET);
82
		ilEnable(IL_ORIGIN_SET);
83
		ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
83
		ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
84
		ilGenImages(1, &ImgId);
84
		ilGenImages(1, &ImgId);
85
		ilBindImage(ImgId);
85
		ilBindImage(ImgId);
86
		char* name_cstr = const_cast<char*>(name.c_str());
86
		char* name_cstr = const_cast<char*>(name.c_str());
87
		if(!ilLoadImage(name_cstr))
87
		if(!ilLoadImage(name_cstr))
88
		{
88
		{
89
			cout << "could not load <" << name_cstr  << ">" << endl;
89
			cout << "could not load <" << name_cstr  << ">" << endl;
90
			return false;
90
			return false;
91
		}
91
		}
92
		
92
		
93
		load_size_x = ilGetInteger(IL_IMAGE_WIDTH);
93
		load_size_x = ilGetInteger(IL_IMAGE_WIDTH);
94
		load_size_y = ilGetInteger(IL_IMAGE_HEIGHT);
94
		load_size_y = ilGetInteger(IL_IMAGE_HEIGHT);
95
		bpp = ilGetInteger(IL_IMAGE_BITS_PER_PIXEL);
95
		bpp = ilGetInteger(IL_IMAGE_BITS_PER_PIXEL);
96
		
96
		
97
		if (bpp==24)
97
		if (bpp==24)
98
			ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);
98
			ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE);
99
		else if (bpp==32)
99
		else if (bpp==32)
100
			ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
100
			ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
101
		else if (bpp==8)
101
		else if (bpp==8)
102
			ilConvertImage(IL_LUMINANCE, IL_UNSIGNED_BYTE);
102
			ilConvertImage(IL_LUMINANCE, IL_UNSIGNED_BYTE);
103
		else
103
		else
104
			assert(0);
104
			assert(0);
105
		
105
		
106
		unsigned int i;
106
		unsigned int i;
107
		for (i=2;i<=4096 ;i*=2)
107
		for (i=2;i<=4096 ;i*=2)
108
			if (i>=load_size_x)
108
			if (i>=load_size_x)
109
				break;
109
				break;
110
		size_x = i;
110
		size_x = i;
111
		for (i=2;i<=4096 ;i*=2)
111
		for (i=2;i<=4096 ;i*=2)
112
			if (i>=load_size_y)
112
			if (i>=load_size_y)
113
				break;
113
				break;
114
		size_y = i;
114
		size_y = i;
115
		
115
		
116
		if(size_x != load_size_x || size_y != load_size_y)
116
		if(size_x != load_size_x || size_y != load_size_y)
117
		{
117
		{
118
			iluImageParameter(ILU_FILTER, ILU_BILINEAR);
118
			iluImageParameter(ILU_FILTER, ILU_BILINEAR);
119
			iluScale(size_x, size_y, 1);
119
			iluScale(size_x, size_y, 1);
120
		}
120
		}
121
		
121
		
122
		const int image_size =size_x*size_y*ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);
122
		const int image_size =size_x*size_y*ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);
123
		image = new unsigned char[image_size];
123
		image = new unsigned char[image_size];
124
		memcpy(image, ilGetData(), image_size);
124
		memcpy(image, ilGetData(), image_size);
125
		ilDeleteImages(1, &ImgId);
125
		ilDeleteImages(1, &ImgId);
126
		
126
		
127
		bool any_errors=false;
127
		bool any_errors=false;
128
		while ((Error = ilGetError())) {
128
		while ((Error = ilGetError())) {
129
			cout << __LINE__ << "Error: " << iluErrorString(Error) << endl;
129
			cout << __LINE__ << "Error: " << iluErrorString(Error) << endl;
130
			any_errors = true;
130
			any_errors = true;
131
		}
131
		}
132
		if(any_errors) return false;
132
		if(any_errors) return false;
133
		
133
		
134
		GLint internalFormat=0;
134
		GLint internalFormat=0;
135
		GLenum format=0;
135
		GLenum format=0;
136
		
136
		
137
		glGenTextures(1, &id);
137
		glGenTextures(1, &id);
138
		switch (bpp)
138
		switch (bpp)
139
		{
139
		{
140
			case 8:
140
			case 8:
141
				internalFormat =  GL_LUMINANCE;
141
				internalFormat =  GL_LUMINANCE;
142
				format = GL_LUMINANCE;
142
				format = GL_LUMINANCE;
143
				break;
143
				break;
144
			case 24:
144
			case 24:
145
				internalFormat =  GL_RGB;
145
				internalFormat =  GL_RGB;
146
				format = GL_RGB;
146
				format = GL_RGB;
147
				break;
147
				break;
148
			case 32:
148
			case 32:
149
				internalFormat =  GL_RGBA;
149
				internalFormat =  GL_RGBA;
150
				format = GL_RGBA;
150
				format = GL_RGBA;
151
				break;
151
				break;
152
			default:
152
			default:
153
				return false;
153
				return false;
154
		}
154
		}
155
		
155
		
156
		glBindTexture(GL_TEXTURE_2D, id);
156
		glBindTexture(GL_TEXTURE_2D, id);
157
		glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, size_x, size_y, 0,
157
		glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, size_x, size_y, 0,
158
					 format, GL_UNSIGNED_BYTE, image);
158
					 format, GL_UNSIGNED_BYTE, image);
159
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
159
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
160
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
160
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
161
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
161
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
162
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
162
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
163
		
163
		
164
		return true;
164
		return true;
165
	}
165
	}
166
	
166
	
167
	void enable_textures(TriMesh& tm)
167
	void enable_textures(TriMesh& tm)
168
	{
168
	{
169
		for(unsigned int i=0;i<tm.materials.size(); ++i)
169
		for(unsigned int i=0;i<tm.materials.size(); ++i)
170
		{
170
		{
171
			Material& mat = tm.materials[i];
171
			Material& mat = tm.materials[i];
172
			if(mat.tex_name != "")
172
			if(mat.tex_name != "")
173
			{
173
			{
174
				string name = mat.tex_path + mat.tex_name;
174
				string name = mat.tex_path + mat.tex_name;
175
				
175
				
176
				GLuint tex_id;
176
				GLuint tex_id;
177
				if(load_image_into_texture(name, tex_id))
177
				if(load_image_into_texture(name, tex_id))
178
					mat.tex_id = tex_id;
178
					mat.tex_id = tex_id;
179
			}
179
			}
180
		}
180
		}
181
	}
181
	}
182
	
182
	
183
	bool depth_pick(int x, int y,Vec3f& wp)
183
	bool depth_pick(int x, int y,Vec3f& wp)
184
	{
184
	{
185
		// Enquire about the viewport dimensions
185
		// Enquire about the viewport dimensions
186
		GLint viewport[4];
186
		GLint viewport[4];
187
		glGetIntegerv(GL_VIEWPORT, viewport);
187
		glGetIntegerv(GL_VIEWPORT, viewport);
188
		
188
		
189
		// Get the minimum and maximum depth values.
189
		// Get the minimum and maximum depth values.
190
		float minmax_depth[2];
190
		float minmax_depth[2];
191
		glGetFloatv(GL_DEPTH_RANGE, minmax_depth);
191
		glGetFloatv(GL_DEPTH_RANGE, minmax_depth);
192
		
192
		
193
		// Read a single pixel at the position of the mouse cursor.
193
		// Read a single pixel at the position of the mouse cursor.
194
		float depth;
194
		float depth;
195
		glReadPixels(x, viewport[3]-y, 1,1, GL_DEPTH_COMPONENT,
195
		glReadPixels(x, viewport[3]-y, 1,1, GL_DEPTH_COMPONENT,
196
					 GL_FLOAT, (void*) &depth);
196
					 GL_FLOAT, (void*) &depth);
197
		
197
		
198
		// If the depth corresponds to the far plane, we clicked on the
198
		// If the depth corresponds to the far plane, we clicked on the
199
		// background.
199
		// background.
200
		if(depth == minmax_depth[1])
200
		if(depth == minmax_depth[1])
201
			return false;
201
			return false;
202
		
202
		
203
		// The lines below copy the viewing transformation from OpenGL
203
		// The lines below copy the viewing transformation from OpenGL
204
		// to local variables. The call to gluLookAt must have exactly
204
		// to local variables. The call to gluLookAt must have exactly
205
		// the same parameters as when the scene is drawn.
205
		// the same parameters as when the scene is drawn.
206
		glLoadIdentity();
206
		glLoadIdentity();
207
		ball->set_gl_modelview();
207
		ball->set_gl_modelview();
208
		double mvmat[16];
208
		double mvmat[16];
209
		glGetDoublev(GL_MODELVIEW_MATRIX, mvmat);
209
		glGetDoublev(GL_MODELVIEW_MATRIX, mvmat);
210
		
210
		
211
		// Copy the projection matrix. We assume it is unchanged.
211
		// Copy the projection matrix. We assume it is unchanged.
212
		double prjmat[16];
212
		double prjmat[16];
213
		glGetDoublev(GL_PROJECTION_MATRIX, prjmat);
213
		glGetDoublev(GL_PROJECTION_MATRIX, prjmat);
214
		
214
		
215
		// Now unproject the point from screen to world coordinates.
215
		// Now unproject the point from screen to world coordinates.
216
		double ox, oy, oz;
216
		double ox, oy, oz;
217
		gluUnProject(x,viewport[3]-y,depth,
217
		gluUnProject(x,viewport[3]-y,depth,
218
					 mvmat,prjmat,viewport,
218
					 mvmat,prjmat,viewport,
219
					 &ox, &oy, &oz);
219
					 &ox, &oy, &oz);
220
		
220
		
221
		wp = Vec3f(ox,oy,oz);
221
		wp = Vec3f(ox,oy,oz);
222
		
222
		
223
		return true;
223
		return true;
224
	}
224
	}
225
	
225
	
226
 
226
 
227
 
227
 
228
void mouse_motion(int x, int y)
228
void mouse_motion(int x, int y)
229
{
229
{
230
    ball->roll_ball(Vec2i(x,y));
230
    ball->roll_ball(Vec2i(x,y));
231
}
231
}
232
 
232
 
233
void mouse(int btn, int state, int x, int y)
233
void mouse(int btn, int state, int x, int y)
234
{
234
{
235
	if(state == GLUT_DOWN) 
235
	if(state == GLUT_DOWN) 
236
	{
236
	{
237
		if(btn == GLUT_LEFT_BUTTON) 
237
		if(btn == GLUT_LEFT_BUTTON) 
238
			ball->grab_ball(ROTATE_ACTION, Vec2i(x,y));
238
			ball->grab_ball(ROTATE_ACTION, Vec2i(x,y));
239
		else if(btn == GLUT_MIDDLE_BUTTON) 
239
		else if(btn == GLUT_MIDDLE_BUTTON) 
240
			ball->grab_ball(ZOOM_ACTION, Vec2i(x, y));
240
			ball->grab_ball(ZOOM_ACTION, Vec2i(x, y));
241
		else if(btn == GLUT_RIGHT_BUTTON) 
241
		else if(btn == GLUT_RIGHT_BUTTON) 
242
			ball->grab_ball(PAN_ACTION, Vec2i(x, y));
242
			ball->grab_ball(PAN_ACTION, Vec2i(x, y));
243
	}
243
	}
244
	else if(state == GLUT_UP)
244
	else if(state == GLUT_UP)
245
		ball->release_ball();	
245
		ball->release_ball();	
246
}
246
}
247
 
247
 
248
void spin(int x)
248
void spin(int x)
249
{
249
{
250
	ball->do_spin();
250
	ball->do_spin();
251
	glutTimerFunc(spin_timer, spin, 0);  
251
	glutTimerFunc(spin_timer, spin, 0);  
252
	glutPostRedisplay();
252
	glutPostRedisplay();
253
}
253
}
254
 
254
 
255
void display()
255
void display()
256
{
256
{
257
    static bool washere = false;
257
    static bool washere = false;
258
    static unsigned int l;
258
    static unsigned int l;
259
    if(!washere)
259
    if(!washere)
260
    {
260
    {
261
        cout << "Creating display list" << endl;
261
        cout << "Creating display list" << endl;
262
        l = glGenLists(1);
262
        l = glGenLists(1);
263
        glNewList(l, GL_COMPILE);
263
        glNewList(l, GL_COMPILE);
264
        draw(mesh);
264
        draw(mesh);
265
        glEndList();
265
        glEndList();
266
        washere = true;
266
        washere = true;
267
		glutTimerFunc(spin_timer, spin, 0);	
267
		glutTimerFunc(spin_timer, spin, 0);	
268
	}
268
	}
269
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
269
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
270
    glLoadIdentity();
270
    glLoadIdentity();
271
    ball->set_gl_modelview();
271
    ball->set_gl_modelview();
272
    glCallList(l);
272
    glCallList(l);
273
    glutSwapBuffers();
273
    glutSwapBuffers();
274
}
274
}
275
 
275
 
276
void keyboard(unsigned char key, int x, int y)
276
void keyboard(unsigned char key, int x, int y)
277
{
277
{
278
    switch(key)
278
    switch(key)
279
    {
279
    {
280
		case '\033': exit(0); break;
280
		case '\033': exit(0); break;
281
			//case '+': ball->closer(); break;
281
			//case '+': ball->closer(); break;
282
			//case '-': ball->farther(); break;
282
			//case '-': ball->farther(); break;
283
			//default:
283
			//default:
284
			//    ball->up_axis(key);
284
			//    ball->up_axis(key);
285
    }
285
    }
286
}
286
}
287
}
287
}
288
 
288
 
289
int main(int argc, char** argv)
289
int main(int argc, char** argv)
290
{
290
{
291
    // GLUT INIT
291
    // GLUT INIT
292
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
292
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
293
    glutInitWindowSize(win_size_x, win_size_y);
293
    glutInitWindowSize(win_size_x, win_size_y);
294
    glutInit(&argc, argv);
294
    glutInit(&argc, argv);
295
    main_window = glutCreateWindow("OBJ Viewer");
295
    main_window = glutCreateWindow("OBJ Viewer");
296
    glutDisplayFunc(display);
296
    glutDisplayFunc(display);
297
    glutKeyboardFunc(keyboard);
297
    glutKeyboardFunc(keyboard);
298
    glutMotionFunc(mouse_motion);
298
    glutMotionFunc(mouse_motion);
299
    glutMouseFunc(mouse);
299
    glutMouseFunc(mouse);
300
    //glutIdleFunc(idle);
300
    //glutIdleFunc(idle);
301
	
301
	
302
    // GL INIT
302
    // GL INIT
303
    glClearColor(.8f, 0.9f, 1.0f, 0.f);
303
    glClearColor(.8f, 0.9f, 1.0f, 0.f);
304
    glEnable(GL_DEPTH_TEST);
304
    glEnable(GL_DEPTH_TEST);
305
    glEnable(GL_LIGHTING);
305
    glEnable(GL_LIGHTING);
306
    glEnable(GL_LIGHT0);
306
    glEnable(GL_LIGHT0);
307
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
307
    glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
308
    glShadeModel(GL_SMOOTH);
308
    glShadeModel(GL_SMOOTH);
309
	
309
	
310
    // LOAD OBJ
310
    // LOAD OBJ
311
    string fn;
311
    string fn;
312
    if(argc>1)
312
    if(argc>1)
313
        fn = argv[1];
313
        fn = argv[1];
314
    else
314
    else
315
        fn = "../../data/head.obj";
315
        fn = "../../data/head.obj";
316
		
316
		
317
	if(fn.substr(fn.length()-4,fn.length())==".obj")
317
	if(fn.substr(fn.length()-4,fn.length())==".obj")
318
	{
318
	{
319
		obj_load(fn, mesh);
319
		obj_load(fn, mesh);
320
	}
320
	}
321
	else if(fn.substr(fn.length()-4,fn.length())==".ply")
321
	else if(fn.substr(fn.length()-4,fn.length())==".ply")
322
	{
322
	{
323
		ply_load(fn, mesh);
323
		ply_load(fn, mesh);
324
	}	
324
	}	
325
	else
325
	else
326
	{
326
	{
327
		cout << "Either the format was unrecognized or the file did not have the appropriate extension" << endl;
327
		cout << "Either the format was unrecognized or the file did not have the appropriate extension" << endl;
328
		exit(0);
328
		exit(0);
329
	}		
329
	}		
330
/*    enable_textures(mesh);	
330
    enable_textures(mesh);	
331
    if(!mesh.has_normals())
331
    if(!mesh.has_normals())
332
    {
332
    {
333
        cout << "Computing normals" << endl;
333
        cout << "Computing normals" << endl;
334
        mesh.compute_normals();
334
        mesh.compute_normals();
335
    }
335
    }
336
*/	
336
 
337
    // Initialize Trackball
337
    // Initialize Trackball
338
    Vec3f c;
338
    Vec3f c;
339
    float r;
339
    float r;
340
    mesh.get_bsphere(c,r);
340
    mesh.get_bsphere(c,r);
341
    r *= 1.5;
341
    r *= 1.5;
342
    ball = new QuatTrackBall(c,r,800,800);
342
    ball = new QuatTrackBall(c,r,800,800);
343
	
343
	
344
    // Setup projection
344
    // Setup projection
345
    glMatrixMode(GL_PROJECTION);
345
    glMatrixMode(GL_PROJECTION);
346
    glLoadIdentity();
346
    glLoadIdentity();
347
    gluPerspective(53,1.0f,r/100.0,r*3.0);
347
    gluPerspective(53,1.0f,r/100.0,r*3.0);
348
    glMatrixMode(GL_MODELVIEW);
348
    glMatrixMode(GL_MODELVIEW);
349
	
349
	
350
    // Pass control to GLUT
350
    // Pass control to GLUT
351
    glutMainLoop();
351
    glutMainLoop();
352
	
352
	
353
    return 0;
353
    return 0;
354
}
354
}
355
 
355