simpleLite.c
Go to the documentation of this file.
00001 /*
00002  *  simpleLite.c
00003  *
00004  *  Some code to demonstrate use of gsub_lite's argl*() functions.
00005  *  Shows the correct GLUT usage to read a video frame (in the idle callback)
00006  *  and to draw it (in the display callback).
00007  *
00008  *  Press '?' while running for help on available key commands.
00009  *
00010  *  Copyright (c) 2001-2007 Philip Lamb (PRL) phil@eden.net.nz. All rights reserved.
00011  *
00012  *      Rev             Date            Who             Changes
00013  *      1.0.0   20040302        PRL             Initial version, simple test animation using GLUT.
00014  *      1.0.1   20040721        PRL             Correctly sets window size; supports arVideoDispOption().
00015  *
00016  */
00017 /*
00018  * 
00019  * This file is part of ARToolKit.
00020  * 
00021  * ARToolKit is free software; you can redistribute it and/or modify
00022  * it under the terms of the GNU General Public License as published by
00023  * the Free Software Foundation; either version 2 of the License, or
00024  * (at your option) any later version.
00025  * 
00026  * ARToolKit is distributed in the hope that it will be useful,
00027  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00028  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00029  * GNU General Public License for more details.
00030  * 
00031  * You should have received a copy of the GNU General Public License
00032  * along with ARToolKit; if not, write to the Free Software
00033  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00034  * 
00035  */
00036 
00037 
00038 // ============================================================================
00039 //      Includes
00040 // ============================================================================
00041 
00042 #include <stdio.h>
00043 #include <stdlib.h>                                     // malloc(), free()
00044 #ifdef __APPLE__
00045 #  include <GLUT/glut.h>
00046 #else
00047 #  include <GL/glut.h>
00048 #endif
00049 #include <AR/config.h>
00050 #include <AR/video.h>
00051 #include <AR/param.h>                   // arParamDisp()
00052 #include <AR/ar.h>
00053 #include <AR/gsub_lite.h>
00054 
00055 // ============================================================================
00056 //      Constants
00057 // ============================================================================
00058 
00059 #define VIEW_SCALEFACTOR                0.025           // 1.0 ARToolKit unit becomes 0.025 of my OpenGL units.
00060 #define VIEW_DISTANCE_MIN               0.1                     // Objects closer to the camera than this will not be displayed.
00061 #define VIEW_DISTANCE_MAX               100.0           // Objects further away from the camera than this will not be displayed.
00062 
00063 // ============================================================================
00064 //      Global variables
00065 // ============================================================================
00066 
00067 // Preferences.
00068 static int prefWindowed = TRUE;
00069 static int prefWidth = 640;                                     // Fullscreen mode width.
00070 static int prefHeight = 480;                            // Fullscreen mode height.
00071 static int prefDepth = 32;                                      // Fullscreen mode bit depth.
00072 static int prefRefresh = 0;                                     // Fullscreen mode refresh rate. Set to 0 to use default rate.
00073 
00074 // Image acquisition.
00075 static ARUint8          *gARTImage = NULL;
00076 
00077 // Marker detection.
00078 static int                      gARTThreshhold = 100;
00079 static long                     gCallCountMarkerDetect = 0;
00080 
00081 // Transformation matrix retrieval.
00082 static double           gPatt_width     = 80.0; // Per-marker, but we are using only 1 marker.
00083 static double           gPatt_centre[2] = {0.0, 0.0}; // Per-marker, but we are using only 1 marker.
00084 static double           gPatt_trans[3][4];              // Per-marker, but we are using only 1 marker.
00085 static int                      gPatt_found = FALSE;    // Per-marker, but we are using only 1 marker.
00086 static int                      gPatt_id;                               // Per-marker, but we are using only 1 marker.
00087 
00088 // Drawing.
00089 static ARParam          gARTCparam;
00090 static ARGL_CONTEXT_SETTINGS_REF gArglSettings = NULL;
00091 static int gDrawRotate = FALSE;
00092 static float gDrawRotateAngle = 0;                      // For use in drawing.
00093 
00094 // ============================================================================
00095 //      Functions
00096 // ============================================================================
00097 
00098 // Something to look at, draw a rotating colour cube.
00099 static void DrawCube(void)
00100 {
00101         // Colour cube data.
00102         static GLuint polyList = 0;
00103         float fSize = 0.5f;
00104         long f, i;      
00105         const GLfloat cube_vertices [8][3] = {
00106         {1.0, 1.0, 1.0}, {1.0, -1.0, 1.0}, {-1.0, -1.0, 1.0}, {-1.0, 1.0, 1.0},
00107         {1.0, 1.0, -1.0}, {1.0, -1.0, -1.0}, {-1.0, -1.0, -1.0}, {-1.0, 1.0, -1.0} };
00108         const GLfloat cube_vertex_colors [8][3] = {
00109         {1.0, 1.0, 1.0}, {1.0, 1.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 1.0, 1.0},
00110         {1.0, 0.0, 1.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0} };
00111         GLint cube_num_faces = 6;
00112         const short cube_faces [6][4] = {
00113         {3, 2, 1, 0}, {2, 3, 7, 6}, {0, 1, 5, 4}, {3, 0, 4, 7}, {1, 2, 6, 5}, {4, 5, 6, 7} };
00114         
00115         if (!polyList) {
00116                 polyList = glGenLists (1);
00117                 glNewList(polyList, GL_COMPILE);
00118                 glBegin (GL_QUADS);
00119                 for (f = 0; f < cube_num_faces; f++)
00120                         for (i = 0; i < 4; i++) {
00121                                 glColor3f (cube_vertex_colors[cube_faces[f][i]][0], cube_vertex_colors[cube_faces[f][i]][1], cube_vertex_colors[cube_faces[f][i]][2]);
00122                                 glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);
00123                         }
00124                 glEnd ();
00125                 glColor3f (0.0, 0.0, 0.0);
00126                 for (f = 0; f < cube_num_faces; f++) {
00127                         glBegin (GL_LINE_LOOP);
00128                         for (i = 0; i < 4; i++)
00129                                 glVertex3f(cube_vertices[cube_faces[f][i]][0] * fSize, cube_vertices[cube_faces[f][i]][1] * fSize, cube_vertices[cube_faces[f][i]][2] * fSize);
00130                         glEnd ();
00131                 }
00132                 glEndList ();
00133         }
00134         
00135         glPushMatrix(); // Save world coordinate system.
00136         glTranslatef(0.0, 0.0, 0.5); // Place base of cube on marker surface.
00137         glRotatef(gDrawRotateAngle, 0.0, 0.0, 1.0); // Rotate about z axis.
00138         glDisable(GL_LIGHTING); // Just use colours.
00139         glCallList(polyList);   // Draw the cube.
00140         glPopMatrix();  // Restore world coordinate system.
00141         
00142 }
00143 
00144 static void DrawCubeUpdate(float timeDelta)
00145 {
00146         if (gDrawRotate) {
00147                 gDrawRotateAngle += timeDelta * 45.0f; // Rotate cube at 45 degrees per second.
00148                 if (gDrawRotateAngle > 360.0f) gDrawRotateAngle -= 360.0f;
00149         }
00150 }
00151 
00152 static int setupCamera(const char *cparam_name, char *vconf, ARParam *cparam)
00153 {       
00154     ARParam                     wparam;
00155         int                             xsize, ysize;
00156 
00157     // Open the video path.
00158     if (arVideoOpen(vconf) < 0) {
00159         fprintf(stderr, "setupCamera(): Unable to open connection to camera.\n");
00160         return (FALSE);
00161         }
00162         
00163     // Find the size of the window.
00164     if (arVideoInqSize(&xsize, &ysize) < 0) return (FALSE);
00165     fprintf(stdout, "Camera image size (x,y) = (%d,%d)\n", xsize, ysize);
00166         
00167         // Load the camera parameters, resize for the window and init.
00168     if (arParamLoad(cparam_name, 1, &wparam) < 0) {
00169                 fprintf(stderr, "setupCamera(): Error loading parameter file %s for camera.\n", cparam_name);
00170         return (FALSE);
00171     }
00172     arParamChangeSize(&wparam, xsize, ysize, cparam);
00173     fprintf(stdout, "*** Camera Parameter ***\n");
00174     arParamDisp(cparam);
00175         
00176     arInitCparam(cparam);
00177 
00178         if (arVideoCapStart() != 0) {
00179         fprintf(stderr, "setupCamera(): Unable to begin camera data capture.\n");
00180                 return (FALSE);         
00181         }
00182         
00183         return (TRUE);
00184 }
00185 
00186 static int setupMarker(const char *patt_name, int *patt_id)
00187 {
00188         // Loading only 1 pattern in this example.
00189         if ((*patt_id = arLoadPatt(patt_name)) < 0) {
00190                 fprintf(stderr, "setupMarker(): pattern load error !!\n");
00191                 return (FALSE);
00192         }
00193 
00194         return (TRUE);
00195 }
00196 
00197 // Report state of ARToolKit global variables arFittingMode,
00198 // arImageProcMode, arglDrawMode, arTemplateMatchingMode, arMatchingPCAMode.
00199 static void debugReportMode(const ARGL_CONTEXT_SETTINGS_REF arglContextSettings)
00200 {
00201         if (arFittingMode == AR_FITTING_TO_INPUT) {
00202                 fprintf(stderr, "FittingMode (Z): INPUT IMAGE\n");
00203         } else {
00204                 fprintf(stderr, "FittingMode (Z): COMPENSATED IMAGE\n");
00205         }
00206         
00207         if (arImageProcMode == AR_IMAGE_PROC_IN_FULL) {
00208                 fprintf(stderr, "ProcMode (X)   : FULL IMAGE\n");
00209         } else {
00210                 fprintf(stderr, "ProcMode (X)   : HALF IMAGE\n");
00211         }
00212         
00213         if (arglDrawModeGet(arglContextSettings) == AR_DRAW_BY_GL_DRAW_PIXELS) {
00214                 fprintf(stderr, "DrawMode (C)   : GL_DRAW_PIXELS\n");
00215         } else if (arglTexmapModeGet(arglContextSettings) == AR_DRAW_TEXTURE_FULL_IMAGE) {
00216                 fprintf(stderr, "DrawMode (C)   : TEXTURE MAPPING (FULL RESOLUTION)\n");
00217         } else {
00218                 fprintf(stderr, "DrawMode (C)   : TEXTURE MAPPING (HALF RESOLUTION)\n");
00219         }
00220                 
00221         if (arTemplateMatchingMode == AR_TEMPLATE_MATCHING_COLOR) {
00222                 fprintf(stderr, "TemplateMatchingMode (M)   : Color Template\n");
00223         } else {
00224                 fprintf(stderr, "TemplateMatchingMode (M)   : BW Template\n");
00225         }
00226         
00227         if (arMatchingPCAMode == AR_MATCHING_WITHOUT_PCA) {
00228                 fprintf(stderr, "MatchingPCAMode (P)   : Without PCA\n");
00229         } else {
00230                 fprintf(stderr, "MatchingPCAMode (P)   : With PCA\n");
00231         }
00232 }
00233 
00234 static void Quit(void)
00235 {
00236         arglCleanup(gArglSettings);
00237         arVideoCapStop();
00238         arVideoClose();
00239         exit(0);
00240 }
00241 
00242 static void Keyboard(unsigned char key, int x, int y)
00243 {
00244         int mode;
00245         switch (key) {
00246                 case 0x1B:                                              // Quit.
00247                 case 'Q':
00248                 case 'q':
00249                         Quit();
00250                         break;
00251                 case ' ':
00252                         gDrawRotate = !gDrawRotate;
00253                         break;
00254                 case 'C':
00255                 case 'c':
00256                         mode = arglDrawModeGet(gArglSettings);
00257                         if (mode == AR_DRAW_BY_GL_DRAW_PIXELS) {
00258                                 arglDrawModeSet(gArglSettings, AR_DRAW_BY_TEXTURE_MAPPING);
00259                                 arglTexmapModeSet(gArglSettings, AR_DRAW_TEXTURE_FULL_IMAGE);
00260                         } else {
00261                                 mode = arglTexmapModeGet(gArglSettings);
00262                                 if (mode == AR_DRAW_TEXTURE_FULL_IMAGE) arglTexmapModeSet(gArglSettings, AR_DRAW_TEXTURE_HALF_IMAGE);
00263                                 else arglDrawModeSet(gArglSettings, AR_DRAW_BY_GL_DRAW_PIXELS);
00264                         }
00265                         fprintf(stderr, "*** Camera - %f (frame/sec)\n", (double)gCallCountMarkerDetect/arUtilTimer());
00266                         gCallCountMarkerDetect = 0;
00267                         arUtilTimerReset();
00268                         debugReportMode(gArglSettings);
00269                         break;
00270                 case 'D':
00271                 case 'd':
00272                         arDebug = !arDebug;
00273                         break;
00274                 case '?':
00275                 case '/':
00276                         printf("Keys:\n");
00277                         printf(" q or [esc]    Quit demo.\n");
00278                         printf(" c             Change arglDrawMode and arglTexmapMode.\n");
00279                         printf(" d             Activate / deactivate debug mode.\n");
00280                         printf(" ? or /        Show this help.\n");
00281                         printf("\nAdditionally, the ARVideo library supplied the following help text:\n");
00282                         arVideoDispOption();
00283                         break;
00284                 default:
00285                         break;
00286         }
00287 }
00288 
00289 static void Idle(void)
00290 {
00291         static int ms_prev;
00292         int ms;
00293         float s_elapsed;
00294         ARUint8 *image;
00295 
00296         ARMarkerInfo    *marker_info;                                   // Pointer to array holding the details of detected markers.
00297     int             marker_num;                                         // Count of number of markers detected.
00298     int             j, k;
00299         
00300         // Find out how long since Idle() last ran.
00301         ms = glutGet(GLUT_ELAPSED_TIME);
00302         s_elapsed = (float)(ms - ms_prev) * 0.001;
00303         if (s_elapsed < 0.01f) return; // Don't update more often than 100 Hz.
00304         ms_prev = ms;
00305         
00306         // Update drawing.
00307         DrawCubeUpdate(s_elapsed);
00308         
00309         // Grab a video frame.
00310         if ((image = arVideoGetImage()) != NULL) {
00311                 gARTImage = image;      // Save the fetched image.
00312                 
00313                 gCallCountMarkerDetect++; // Increment ARToolKit FPS counter.
00314                 
00315                 // Detect the markers in the video frame.
00316                 if (arDetectMarker(gARTImage, gARTThreshhold, &marker_info, &marker_num) < 0) {
00317                         exit(-1);
00318                 }
00319                 
00320                 // Check through the marker_info array for highest confidence
00321                 // visible marker matching our preferred pattern.
00322                 k = -1;
00323                 for (j = 0; j < marker_num; j++) {
00324                         if (marker_info[j].id == gPatt_id) {
00325                                 if (k == -1) k = j; // First marker detected.
00326                                 else if(marker_info[j].cf > marker_info[k].cf) k = j; // Higher confidence marker detected.
00327                         }
00328                 }
00329                 
00330                 if (k != -1) {
00331                         // Get the transformation between the marker and the real camera into gPatt_trans.
00332                         arGetTransMat(&(marker_info[k]), gPatt_centre, gPatt_width, gPatt_trans);
00333                         gPatt_found = TRUE;
00334                 } else {
00335                         gPatt_found = FALSE;
00336                 }
00337                 
00338                 // Tell GLUT the display has changed.
00339                 glutPostRedisplay();
00340         }
00341 }
00342 
00343 //
00344 //      This function is called on events when the visibility of the
00345 //      GLUT window changes (including when it first becomes visible).
00346 //
00347 static void Visibility(int visible)
00348 {
00349         if (visible == GLUT_VISIBLE) {
00350                 glutIdleFunc(Idle);
00351         } else {
00352                 glutIdleFunc(NULL);
00353         }
00354 }
00355 
00356 //
00357 //      This function is called when the
00358 //      GLUT window is resized.
00359 //
00360 static void Reshape(int w, int h)
00361 {
00362         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00363         glViewport(0, 0, (GLsizei) w, (GLsizei) h);
00364         
00365         glMatrixMode(GL_PROJECTION);
00366         glLoadIdentity();
00367         glMatrixMode(GL_MODELVIEW);
00368         glLoadIdentity();
00369 
00370         // Call through to anyone else who needs to know about window sizing here.
00371 }
00372 
00373 //
00374 // This function is called when the window needs redrawing.
00375 //
00376 static void Display(void)
00377 {
00378     GLdouble p[16];
00379         GLdouble m[16];
00380         
00381         // Select correct buffer for this context.
00382         glDrawBuffer(GL_BACK);
00383         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.
00384         
00385         arglDispImage(gARTImage, &gARTCparam, 1.0, gArglSettings);      // zoom = 1.0.
00386         arVideoCapNext();
00387         gARTImage = NULL; // Image data is no longer valid after calling arVideoCapNext().
00388                                 
00389         // Projection transformation.
00390         arglCameraFrustumRH(&gARTCparam, VIEW_DISTANCE_MIN, VIEW_DISTANCE_MAX, p);
00391         glMatrixMode(GL_PROJECTION);
00392         glLoadMatrixd(p);
00393         glMatrixMode(GL_MODELVIEW);
00394                 
00395         // Viewing transformation.
00396         glLoadIdentity();
00397         // Lighting and geometry that moves with the camera should go here.
00398         // (I.e. must be specified before viewing transformations.)
00399         //none
00400         
00401         if (gPatt_found) {
00402         
00403                 // Calculate the camera position relative to the marker.
00404                 // Replace VIEW_SCALEFACTOR with 1.0 to make one drawing unit equal to 1.0 ARToolKit units (usually millimeters).
00405                 arglCameraViewRH(gPatt_trans, m, VIEW_SCALEFACTOR);
00406                 glLoadMatrixd(m);
00407 
00408                 // All lighting and geometry to be drawn relative to the marker goes here.
00409                 DrawCube();
00410         
00411         } // gPatt_found
00412         
00413         // Any 2D overlays go here.
00414         //none
00415         
00416         glutSwapBuffers();
00417 }
00418 
00419 int main(int argc, char** argv)
00420 {
00421         char glutGamemode[32];
00422         const char *cparam_name = "Data/camera_para.dat";
00423         //
00424         // Camera configuration.
00425         //
00426 #ifdef _WIN32
00427         char                    *vconf = "Data\\WDM_camera_flipV.xml";
00428 #else
00429         char                    *vconf = "";
00430 #endif
00431         const char *patt_name  = "Data/patt.hiro";
00432         
00433         // ----------------------------------------------------------------------------
00434         // Library inits.
00435         //
00436 
00437         glutInit(&argc, argv);
00438 
00439         // ----------------------------------------------------------------------------
00440         // Hardware setup.
00441         //
00442 
00443         if (!setupCamera(cparam_name, vconf, &gARTCparam)) {
00444                 fprintf(stderr, "main(): Unable to set up AR camera.\n");
00445                 exit(-1);
00446         }
00447 
00448         // ----------------------------------------------------------------------------
00449         // Library setup.
00450         //
00451 
00452         // Set up GL context(s) for OpenGL to draw into.
00453         glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
00454         if (!prefWindowed) {
00455                 if (prefRefresh) sprintf(glutGamemode, "%ix%i:%i@%i", prefWidth, prefHeight, prefDepth, prefRefresh);
00456                 else sprintf(glutGamemode, "%ix%i:%i", prefWidth, prefHeight, prefDepth);
00457                 glutGameModeString(glutGamemode);
00458                 glutEnterGameMode();
00459         } else {
00460                 glutInitWindowSize(prefWidth, prefHeight);
00461                 glutCreateWindow(argv[0]);
00462         }
00463 
00464         // Setup argl library for current context.
00465         if ((gArglSettings = arglSetupForCurrentContext()) == NULL) {
00466                 fprintf(stderr, "main(): arglSetupForCurrentContext() returned error.\n");
00467                 exit(-1);
00468         }
00469         debugReportMode(gArglSettings);
00470         glEnable(GL_DEPTH_TEST);
00471         arUtilTimerReset();
00472                 
00473         if (!setupMarker(patt_name, &gPatt_id)) {
00474                 fprintf(stderr, "main(): Unable to set up AR marker.\n");
00475                 Quit();
00476         }
00477         
00478         // Register GLUT event-handling callbacks.
00479         // NB: Idle() is registered by Visibility.
00480         glutDisplayFunc(Display);
00481         glutReshapeFunc(Reshape);
00482         glutVisibilityFunc(Visibility);
00483         glutKeyboardFunc(Keyboard);
00484         
00485         glutMainLoop();
00486 
00487         return (0);
00488 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


ar_recog
Author(s): Graylin Trevor Jay and Christopher Crick
autogenerated on Fri Jan 25 2013 12:15:00