Subversion Repositories gelsvn

Rev

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

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