Subversion Repositories gelsvn

Rev

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

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