Subversion Repositories gelsvn

Rev

Rev 132 | Rev 195 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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