Blame |
Last modification |
View Log
| RSS feed
/*
*
* This file is part of ARToolKit.
*
* ARToolKit is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ARToolKit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ARToolKit; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
// ============================================================================
// Includes
// ============================================================================
#ifdef _WIN32
# include <windows.h>
#endif
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef __APPLE__
# include <GL/glut.h>
# ifdef GL_VERSION_1_2
# include <GL/glext.h>
# endif
#else
# include <GLUT/glut.h>
# include <OpenGL/glext.h>
#endif
#include <AR/config.h>
#include <AR/video.h>
#include <AR/param.h>
#include <AR/ar.h>
#include <AR/gsub_lite.h>
// ============================================================================
// Constants
// ============================================================================
// ============================================================================
// Global variables
// ============================================================================
/* set up the video format globals */
#if defined(__sgi)
char *vconf
= "-size=FULL";
#elif defined(__linux)
# if defined(AR_INPUT_GSTREAMER)
char *vconf
= "videotestsrc";
# elif defined(AR_INPUT_V4L)
char *vconf
= "-width=640 -height=480";
# elif defined(AR_INPUT_1394CAM)
char *vconf
= "-mode=640x480_YUV411";
# elif defined(AR_INPUT_DV)
char *vconf
= "";
# endif
#elif defined(_WIN32)
char *vconf
= "Data\\WDM_camera_flipV.xml";
#elif defined(__APPLE__)
char *vconf
= "-width=640 -height=480";
#else
char *vconf
= "";
#endif
// Image acquisition.
static ARUint8
*gARTImage
= NULL
;
static ARUint8
*gARTsaveImage
= NULL
;
// Marker detection.
static int gARTThreshhold
= 100;
static ARMarkerInfo
* gTarget
= NULL
;
// Drawing.
static ARParam gARTCparam
;
static ARGL_CONTEXT_SETTINGS_REF gArglSettings
= NULL
;
// ============================================================================
// Functions
// ============================================================================
void lineSeg
(double x1
, double y1
, double x2
, double y2
, ARGL_CONTEXT_SETTINGS_REF contextSettings
, ARParam cparam
, double zoom
)
{
int enable
;
float ox
, oy
;
double xx1
, yy1
, xx2
, yy2
;
if (!contextSettings
) return;
arglDistortionCompensationGet
(contextSettings
, &enable
);
if (arglDrawModeGet
(contextSettings
) == AR_DRAW_BY_TEXTURE_MAPPING
&& enable
) {
xx1
= x1
; yy1
= y1
;
xx2
= x2
; yy2
= y2
;
} else {
arParamIdeal2Observ
(cparam.
dist_factor, x1
, y1
, &xx1
, &yy1
);
arParamIdeal2Observ
(cparam.
dist_factor, x2
, y2
, &xx2
, &yy2
);
}
xx1
*= zoom
; yy1
*= zoom
;
xx2
*= zoom
; yy2
*= zoom
;
ox
= 0;
oy
= cparam.
ysize - 1;
glBegin
(GL_LINES
);
glVertex2f
(ox
+ xx1
, oy
- yy1
);
glVertex2f
(ox
+ xx2
, oy
- yy2
);
glEnd
();
glFlush
();
}
static int setupCamera
(ARParam
*cparam
)
{
ARParam wparam
;
char name1
[256], name2
[256];
int xsize
, ysize
;
printf("Enter camera parameter filename");
printf("(Data/camera_para.dat): ");
if (fgets(name1
, 256, stdin
) == NULL
) exit(0);
if (sscanf(name1
, "%s", name2
) != 1) {
strcpy(name2
, "Data/camera_para.dat");
}
// Load the camera parameters.
if (arParamLoad
(name2
, 1, &wparam
) < 0 ) {
printf("Parameter load error !!\n");
return (FALSE
);
}
// Open the video path.
if (arVideoOpen
(vconf
) < 0) {
fprintf(stderr
, "setupCamera(): Unable to open connection to camera.\n");
return (FALSE
);
}
// Find the size of the window.
if (arVideoInqSize
(&xsize
, &ysize
) < 0) return (FALSE
);
fprintf(stdout
, "Camera image size (x,y) = (%d,%d)\n", xsize
, ysize
);
// Resize for the window and init.
arParamChangeSize
(&wparam
, xsize
, ysize
, cparam
);
fprintf(stdout
, "*** Camera Parameter ***\n");
arParamDisp
(cparam
);
arInitCparam
(cparam
);
if (arVideoCapStart
() != 0) {
fprintf(stderr
, "setupCamera(): Unable to begin camera data capture.\n");
return (FALSE
);
}
return (TRUE
);
}
static void Quit
(void)
{
free(gARTsaveImage
); gARTsaveImage
= NULL
;
arglCleanup
(gArglSettings
);
arVideoCapStop
();
arVideoClose
();
exit(0);
}
static void Keyboard
(unsigned char key
, int x
, int y
)
{
switch (key
) {
case 0x1B: // Quit.
case 'Q':
case 'q':
Quit
();
break;
case 'T':
case 't':
printf("Enter new threshold value (default = 100): ");
scanf("%d", &gARTThreshhold
); while (getchar()!='\n');
printf("\n");
break;
case '?':
case '/':
printf("Keys:\n");
printf(" q or [esc] Quit demo.\n");
printf(" t Enter new binarization threshold value.\n");
printf(" ? or / Show this help.\n");
printf("\nAdditionally, the ARVideo library supplied the following help text:\n");
arVideoDispOption
();
break;
default:
break;
}
}
static void Mouse
(int button
, int state
, int x
, int y
)
{
char name1
[256], name2
[256];
if (state
== GLUT_DOWN
) {
if (button
== GLUT_RIGHT_BUTTON
) {
Quit
();
} else if (button
== GLUT_MIDDLE_BUTTON
) {
printf("Enter new threshold value (default = 100): ");
scanf("%d", &gARTThreshhold
); while (getchar() != '\n');
printf("\n");
} else if (button
== GLUT_LEFT_BUTTON
&& gARTsaveImage
&& gTarget
) {
printf("Enter filename: ");
if (fgets(name1
, 256, stdin
) == NULL
) return;
if (sscanf(name1
, "%s", name2
) != 1 ) return;
if (arSavePatt
(gARTsaveImage
, gTarget
, name2
) < 0) {
printf("ERROR!!\n");
} else {
printf(" Saved\n");
}
}
}
}
static void Idle
(void)
{
static int ms_prev
;
int ms
;
float s_elapsed
;
ARUint8
*image
;
int areamax
;
ARMarkerInfo
*marker_info
; // Pointer to array holding the details of detected markers.
int marker_num
; // Count of number of markers detected.
int i
;
// Find out how long since Idle() last ran.
ms
= glutGet
(GLUT_ELAPSED_TIME
);
s_elapsed
= (float)(ms
- ms_prev
) * 0.001;
if (s_elapsed
< 0.01f) return; // Don't update more often than 100 Hz.
ms_prev
= ms
;
// Grab a video frame.
if ((image
= arVideoGetImage
()) != NULL
) {
gARTImage
= image
;
if (arDetectMarker
(gARTImage
, gARTThreshhold
, &marker_info
, &marker_num
) < 0) {
Quit
();
}
areamax
= 0;
gTarget
= NULL
;
for (i
= 0; i
< marker_num
; i
++) {
if (marker_info
[i
].
area > areamax
) {
areamax
= marker_info
[i
].
area;
gTarget
= &(marker_info
[i
]);
}
}
memcpy(gARTsaveImage
, gARTImage
, gARTCparam.
xsize * gARTCparam.
ysize * AR_PIX_SIZE_DEFAULT
);
// Tell GLUT the display has changed.
glutPostRedisplay
();
}
}
//
// This function is called on events when the visibility of the
// GLUT window changes (including when it first becomes visible).
//
static void Visibility
(int visible
)
{
if (visible
== GLUT_VISIBLE
) {
glutIdleFunc
(Idle
);
} else {
glutIdleFunc
(NULL
);
}
}
//
// This function is called when the
// GLUT window is resized.
//
static void Reshape
(int w
, int h
)
{
glClear
(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
glViewport
(0, 0, (GLsizei
) w
, (GLsizei
) h
);
glMatrixMode
(GL_PROJECTION
);
glLoadIdentity
();
glMatrixMode
(GL_MODELVIEW
);
glLoadIdentity
();
// Call through to anyone else who needs to know about window sizing here.
}
static void beginOrtho2D
(int xsize
, int ysize
) {
glMatrixMode
(GL_PROJECTION
);
glPushMatrix
();
glLoadIdentity
();
gluOrtho2D
(0.0, xsize
, 0.0, ysize
);
glMatrixMode
(GL_MODELVIEW
);
glPushMatrix
();
glLoadIdentity
();
}
static void endOrtho2D
(void) {
glMatrixMode
(GL_PROJECTION
);
glPopMatrix
();
glMatrixMode
(GL_MODELVIEW
);
glPopMatrix
();
}
//
// This function is called when the window needs redrawing.
//
static void Display
(void)
{
// Select correct buffer for this context.
glDrawBuffer
(GL_BACK
);
glClear
(GL_COLOR_BUFFER_BIT
); // Clear the buffers for new frame.
arglDispImage
(gARTImage
, &gARTCparam
, 1.0, gArglSettings
); // zoom = 1.0.
arVideoCapNext
();
gARTImage
= NULL
; // Image data is no longer valid after calling arVideoCapNext().
if (gTarget
!= NULL
) {
glDisable
(GL_DEPTH_TEST
);
glDisable
(GL_LIGHTING
);
glDisable
(GL_TEXTURE_2D
);
beginOrtho2D
(gARTCparam.
xsize, gARTCparam.
ysize);
glLineWidth
(2.0f);
glColor3d
(0.0, 1.0, 0.0);
lineSeg
(gTarget
->vertex
[0][0], gTarget
->vertex
[0][1],
gTarget
->vertex
[1][0], gTarget
->vertex
[1][1], gArglSettings
, gARTCparam
, 1.0);
lineSeg
(gTarget
->vertex
[3][0], gTarget
->vertex
[3][1],
gTarget
->vertex
[0][0], gTarget
->vertex
[0][1], gArglSettings
, gARTCparam
, 1.0);
glColor3d
(1.0, 0.0, 0.0);
lineSeg
(gTarget
->vertex
[1][0], gTarget
->vertex
[1][1],
gTarget
->vertex
[2][0], gTarget
->vertex
[2][1], gArglSettings
, gARTCparam
, 1.0);
lineSeg
(gTarget
->vertex
[2][0], gTarget
->vertex
[2][1],
gTarget
->vertex
[3][0], gTarget
->vertex
[3][1], gArglSettings
, gARTCparam
, 1.0);
endOrtho2D
();
}
glutSwapBuffers
();
}
int main
(int argc
, char *argv
[])
{
// ----------------------------------------------------------------------------
// Library inits.
//
glutInit
(&argc
, argv
);
// ----------------------------------------------------------------------------
// Hardware setup.
//
if (!setupCamera
(&gARTCparam
)) {
fprintf(stderr
, "main(): Unable to set up AR camera.\n");
exit(-1);
}
// ----------------------------------------------------------------------------
// Library setup.
//
// Set up GL context(s) for OpenGL to draw into.
glutInitDisplayMode
(GLUT_RGB
| GLUT_DOUBLE
);
glutInitWindowSize
(gARTCparam.
xsize, gARTCparam.
ysize);
glutCreateWindow
(argv
[0]);
// Setup argl library for current context.
if ((gArglSettings
= arglSetupForCurrentContext
()) == NULL
) {
fprintf(stderr
, "main(): arglSetupForCurrentContext() returned error.\n");
exit(-1);
}
arMalloc
(gARTsaveImage
, ARUint8
, gARTCparam.
xsize * gARTCparam.
ysize * AR_PIX_SIZE_DEFAULT
);
// Register GLUT event-handling callbacks.
// NB: Idle() is registered by Visibility.
glutDisplayFunc
(Display
);
glutReshapeFunc
(Reshape
);
glutVisibilityFunc
(Visibility
);
glutKeyboardFunc
(Keyboard
);
glutMouseFunc
(Mouse
);
glutMainLoop
();
return (0);
}