Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
204 chris 1
/*
2
 *
3
 * This file is part of ARToolKit.
4
 *
5
 * ARToolKit is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * ARToolKit is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with ARToolKit; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 *
19
 */
20
 
21
// ============================================================================
22
//      Includes
23
// ============================================================================
24
 
25
#ifdef _WIN32
26
#  include <windows.h>
27
#endif
28
#include <math.h>
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <string.h>
32
#ifndef __APPLE__
33
#  include <GL/glut.h>
34
#  ifdef GL_VERSION_1_2
35
#    include <GL/glext.h>
36
#  endif
37
#else
38
#  include <GLUT/glut.h>
39
#  include <OpenGL/glext.h>
40
#endif
41
#include <AR/config.h>
42
#include <AR/video.h>
43
#include <AR/param.h>
44
#include <AR/ar.h>
45
#include <AR/gsub_lite.h>
46
 
47
// ============================================================================
48
//      Constants
49
// ============================================================================
50
 
51
// ============================================================================
52
//      Global variables
53
// ============================================================================
54
 
55
/* set up the video format globals */
56
 
57
#if defined(__sgi)
58
char            *vconf = "-size=FULL";
59
#elif defined(__linux)
60
#  if defined(AR_INPUT_GSTREAMER)
61
char                    *vconf = "videotestsrc";
62
#  elif defined(AR_INPUT_V4L)
63
char            *vconf = "-width=640 -height=480";
64
#  elif defined(AR_INPUT_1394CAM)
65
char            *vconf = "-mode=640x480_YUV411";
66
#  elif defined(AR_INPUT_DV)
67
char            *vconf = "";
68
#  endif
69
#elif defined(_WIN32)
70
char                    *vconf = "Data\\WDM_camera_flipV.xml";
71
#elif defined(__APPLE__)
72
char                    *vconf = "-width=640 -height=480";
73
#else
74
char                    *vconf = "";
75
#endif
76
 
77
// Image acquisition.
78
static ARUint8          *gARTImage = NULL;
79
static ARUint8          *gARTsaveImage = NULL;
80
 
81
// Marker detection.
82
static int                      gARTThreshhold = 100;
83
static ARMarkerInfo* gTarget  = NULL;
84
 
85
 
86
// Drawing.
87
static ARParam          gARTCparam;
88
static ARGL_CONTEXT_SETTINGS_REF gArglSettings = NULL;
89
 
90
// ============================================================================
91
//      Functions
92
// ============================================================================
93
 
94
void lineSeg(double x1, double y1, double x2, double y2, ARGL_CONTEXT_SETTINGS_REF contextSettings, ARParam cparam, double zoom)
95
{
96
        int enable;
97
    float   ox, oy;
98
    double  xx1, yy1, xx2, yy2;
99
 
100
        if (!contextSettings) return;
101
        arglDistortionCompensationGet(contextSettings, &enable);
102
    if (arglDrawModeGet(contextSettings) == AR_DRAW_BY_TEXTURE_MAPPING && enable) {
103
        xx1 = x1;  yy1 = y1;
104
        xx2 = x2;  yy2 = y2;
105
    } else {
106
        arParamIdeal2Observ(cparam.dist_factor, x1, y1, &xx1, &yy1);
107
        arParamIdeal2Observ(cparam.dist_factor, x2, y2, &xx2, &yy2);
108
    }
109
 
110
    xx1 *= zoom; yy1 *= zoom;
111
    xx2 *= zoom; yy2 *= zoom;
112
 
113
        ox = 0;
114
        oy = cparam.ysize - 1;
115
        glBegin(GL_LINES);
116
        glVertex2f(ox + xx1, oy - yy1);
117
        glVertex2f(ox + xx2, oy - yy2);
118
        glEnd();
119
    glFlush();
120
}
121
 
122
static int setupCamera(ARParam *cparam)
123
{
124
    ARParam  wparam;
125
    char     name1[256], name2[256];
126
        int                             xsize, ysize;
127
 
128
    printf("Enter camera parameter filename");
129
    printf("(Data/camera_para.dat): ");
130
    if (fgets(name1, 256, stdin) == NULL) exit(0);
131
    if (sscanf(name1, "%s", name2) != 1) {
132
        strcpy(name2, "Data/camera_para.dat");
133
    }
134
 
135
        // Load the camera parameters.
136
        if (arParamLoad(name2, 1, &wparam) < 0 ) {
137
        printf("Parameter load error !!\n");
138
        return (FALSE);
139
    }
140
 
141
    // Open the video path.
142
    if (arVideoOpen(vconf) < 0) {
143
        fprintf(stderr, "setupCamera(): Unable to open connection to camera.\n");
144
        return (FALSE);
145
        }
146
 
147
    // Find the size of the window.
148
    if (arVideoInqSize(&xsize, &ysize) < 0) return (FALSE);
149
    fprintf(stdout, "Camera image size (x,y) = (%d,%d)\n", xsize, ysize);
150
 
151
        // Resize for the window and init.
152
    arParamChangeSize(&wparam, xsize, ysize, cparam);
153
    fprintf(stdout, "*** Camera Parameter ***\n");
154
    arParamDisp(cparam);
155
 
156
    arInitCparam(cparam);
157
 
158
        if (arVideoCapStart() != 0) {
159
        fprintf(stderr, "setupCamera(): Unable to begin camera data capture.\n");
160
                return (FALSE);        
161
        }
162
 
163
        return (TRUE);
164
}
165
 
166
static void Quit(void)
167
{
168
        free(gARTsaveImage); gARTsaveImage = NULL;
169
        arglCleanup(gArglSettings);
170
        arVideoCapStop();
171
        arVideoClose();
172
        exit(0);
173
}
174
 
175
static void Keyboard(unsigned char key, int x, int y)
176
{
177
        switch (key) {
178
                case 0x1B:                                              // Quit.
179
                case 'Q':
180
                case 'q':
181
                        Quit();
182
                        break;
183
                case 'T':
184
                case 't':
185
                printf("Enter new threshold value (default = 100): ");
186
                        scanf("%d", &gARTThreshhold); while (getchar()!='\n');
187
                                printf("\n");
188
                        break;
189
                case '?':
190
                case '/':
191
                        printf("Keys:\n");
192
                        printf(" q or [esc]    Quit demo.\n");
193
                        printf(" t             Enter new binarization threshold value.\n");
194
                        printf(" ? or /        Show this help.\n");
195
                        printf("\nAdditionally, the ARVideo library supplied the following help text:\n");
196
                        arVideoDispOption();
197
                        break;
198
                default:
199
                        break;
200
    }
201
}
202
 
203
static void Mouse(int button, int state, int x, int y)
204
{
205
    char   name1[256], name2[256];
206
 
207
        if (state == GLUT_DOWN) {
208
                if (button == GLUT_RIGHT_BUTTON) {
209
                        Quit();
210
                } else if (button == GLUT_MIDDLE_BUTTON) {
211
                        printf("Enter new threshold value (default = 100): ");
212
                        scanf("%d", &gARTThreshhold); while (getchar() != '\n');
213
                        printf("\n");
214
                } else if (button == GLUT_LEFT_BUTTON && gARTsaveImage && gTarget) {
215
                        printf("Enter filename: ");
216
                        if (fgets(name1, 256, stdin) == NULL) return;
217
                        if (sscanf(name1, "%s", name2) != 1 ) return;
218
                        if (arSavePatt(gARTsaveImage, gTarget, name2) < 0) {
219
                                printf("ERROR!!\n");
220
                        } else {
221
                                printf("  Saved\n");
222
                        }
223
                }
224
        }
225
}
226
 
227
static void Idle(void)
228
{
229
        static int ms_prev;
230
        int ms;
231
        float s_elapsed;
232
        ARUint8 *image;
233
    int             areamax;
234
        ARMarkerInfo    *marker_info;                                   // Pointer to array holding the details of detected markers.
235
    int             marker_num;                                         // Count of number of markers detected.
236
    int             i;
237
 
238
        // Find out how long since Idle() last ran.
239
        ms = glutGet(GLUT_ELAPSED_TIME);
240
        s_elapsed = (float)(ms - ms_prev) * 0.001;
241
        if (s_elapsed < 0.01f) return; // Don't update more often than 100 Hz.
242
        ms_prev = ms;
243
 
244
        // Grab a video frame.
245
        if ((image = arVideoGetImage()) != NULL) {
246
                gARTImage = image;
247
 
248
                if (arDetectMarker(gARTImage, gARTThreshhold, &marker_info, &marker_num) < 0) {
249
                        Quit();
250
                }
251
 
252
                areamax = 0;
253
                gTarget = NULL;
254
                for (i = 0; i < marker_num; i++) {
255
                        if (marker_info[i].area > areamax) {
256
                                areamax = marker_info[i].area;
257
                                gTarget = &(marker_info[i]);
258
                        }
259
                }
260
                memcpy(gARTsaveImage, gARTImage,  gARTCparam.xsize * gARTCparam.ysize * AR_PIX_SIZE_DEFAULT);
261
 
262
                // Tell GLUT the display has changed.
263
                glutPostRedisplay();
264
        }
265
}
266
 
267
//
268
//      This function is called on events when the visibility of the
269
//      GLUT window changes (including when it first becomes visible).
270
//
271
static void Visibility(int visible)
272
{
273
        if (visible == GLUT_VISIBLE) {
274
                glutIdleFunc(Idle);
275
        } else {
276
                glutIdleFunc(NULL);
277
        }
278
}
279
 
280
//
281
//      This function is called when the
282
//      GLUT window is resized.
283
//
284
static void Reshape(int w, int h)
285
{
286
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
287
        glViewport(0, 0, (GLsizei) w, (GLsizei) h);
288
 
289
        glMatrixMode(GL_PROJECTION);
290
        glLoadIdentity();
291
        glMatrixMode(GL_MODELVIEW);
292
        glLoadIdentity();
293
 
294
        // Call through to anyone else who needs to know about window sizing here.
295
}
296
 
297
static void beginOrtho2D(int xsize, int ysize) {
298
        glMatrixMode(GL_PROJECTION);
299
        glPushMatrix();
300
        glLoadIdentity();
301
        gluOrtho2D(0.0, xsize, 0.0, ysize);
302
        glMatrixMode(GL_MODELVIEW);
303
        glPushMatrix();
304
        glLoadIdentity();      
305
}
306
 
307
static void endOrtho2D(void) {
308
        glMatrixMode(GL_PROJECTION);
309
        glPopMatrix();
310
        glMatrixMode(GL_MODELVIEW);
311
        glPopMatrix();
312
}
313
 
314
//
315
// This function is called when the window needs redrawing.
316
//
317
static void Display(void)
318
{
319
        // Select correct buffer for this context.
320
        glDrawBuffer(GL_BACK);
321
        glClear(GL_COLOR_BUFFER_BIT); // Clear the buffers for new frame.
322
 
323
        arglDispImage(gARTImage, &gARTCparam, 1.0, gArglSettings);      // zoom = 1.0.
324
        arVideoCapNext();
325
        gARTImage = NULL; // Image data is no longer valid after calling arVideoCapNext().
326
 
327
        if (gTarget != NULL) {
328
                glDisable(GL_DEPTH_TEST);
329
                glDisable(GL_LIGHTING);
330
                glDisable(GL_TEXTURE_2D);
331
                beginOrtho2D(gARTCparam.xsize, gARTCparam.ysize);
332
        glLineWidth(2.0f);
333
        glColor3d(0.0, 1.0, 0.0);
334
        lineSeg(gTarget->vertex[0][0], gTarget->vertex[0][1],
335
                                gTarget->vertex[1][0], gTarget->vertex[1][1], gArglSettings, gARTCparam, 1.0);
336
        lineSeg(gTarget->vertex[3][0], gTarget->vertex[3][1],
337
                                gTarget->vertex[0][0], gTarget->vertex[0][1], gArglSettings, gARTCparam, 1.0);
338
        glColor3d(1.0, 0.0, 0.0);
339
        lineSeg(gTarget->vertex[1][0], gTarget->vertex[1][1],
340
                                gTarget->vertex[2][0], gTarget->vertex[2][1], gArglSettings, gARTCparam, 1.0);
341
        lineSeg(gTarget->vertex[2][0], gTarget->vertex[2][1],
342
                                gTarget->vertex[3][0], gTarget->vertex[3][1], gArglSettings, gARTCparam, 1.0);
343
                endOrtho2D();
344
    }
345
 
346
        glutSwapBuffers();
347
}
348
 
349
int main(int argc, char *argv[])
350
{
351
        // ----------------------------------------------------------------------------
352
        // Library inits.
353
        //
354
 
355
        glutInit(&argc, argv);
356
 
357
        // ----------------------------------------------------------------------------
358
        // Hardware setup.
359
        //
360
 
361
        if (!setupCamera(&gARTCparam)) {
362
                fprintf(stderr, "main(): Unable to set up AR camera.\n");
363
                exit(-1);
364
        }
365
 
366
        // ----------------------------------------------------------------------------
367
        // Library setup.
368
        //
369
 
370
        // Set up GL context(s) for OpenGL to draw into.
371
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
372
        glutInitWindowSize(gARTCparam.xsize, gARTCparam.ysize);
373
        glutCreateWindow(argv[0]);
374
 
375
        // Setup argl library for current context.
376
        if ((gArglSettings = arglSetupForCurrentContext()) == NULL) {
377
                fprintf(stderr, "main(): arglSetupForCurrentContext() returned error.\n");
378
                exit(-1);
379
        }
380
 
381
        arMalloc(gARTsaveImage, ARUint8, gARTCparam.xsize * gARTCparam.ysize * AR_PIX_SIZE_DEFAULT);
382
 
383
        // Register GLUT event-handling callbacks.
384
        // NB: Idle() is registered by Visibility.
385
        glutDisplayFunc(Display);
386
        glutReshapeFunc(Reshape);
387
        glutVisibilityFunc(Visibility);
388
        glutKeyboardFunc(Keyboard);
389
    glutMouseFunc(Mouse);
390
 
391
        glutMainLoop();
392
 
393
        return (0);
394
}
395