ARToolKit 是基于opengl和DSVL的增强现实软件包。它遵循opengl的运行模式,基于帧循环实现3D渲染。
主要流程:
1. 初始化视频捕获arVideoCapStart()、读取文件的标记模式、相机参数 arVideoOpen(vconf)
2. 获取一帧输入视频
3. 在输入视频图像中 检测标识和注册的模板
4. 计算相机相对于检测到模板的位置
5. 绘制虚拟模型到检测的模板上
6. 关闭视频捕获arVideoCapStop()、arVideoClose(),回收资源argCleanup()
// simpleTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <AR/gsub.h>
#include <AR/video.h>
#include <AR/param.h>
#include <AR/ar.h>
//摄像机默认参数
char *vconf = "Data\\WDM_camera_flipV.xml";
//摄像机特征参数
char *cparam_name = "Data/camera_para.dat";
//标识信息
char *patt_name = "Data/patt.hiro";
int xsize, ysize;
int thresh = 100;
int count = 0;
ARParam cparam;
int patt_id;
double patt_width = 80.0;
double patt_center[2] = { 0.0, 0.0 };
double patt_trans[3][4];
static void init(void);
static void cleanup(void);
static void keyEvent(unsigned char key, int x, int y);
static void mainLoop(void);
static void draw(void);
int main(int argc, char **argv)
{
//opengl初始化
glutInit(&argc, argv);
//初始化想次参数 和显示窗口
init();
//启动相机
arVideoCapStart();
//进入帧循环、并设定响应事件(参数均为函数指针)
//argMainLoop()函数 有三个参数 分别是 mouseEvent keyEvent mainLoop
argMainLoop(NULL, keyEvent, mainLoop);
return (0);
}
static void keyEvent(unsigned char key, int x, int y)
{
if (key == 0x1b) {
printf("*** %f (frame/sec)\n", (double)count / arUtilTimer());
cleanup();
exit(0);
}
}
/* main loop */
static void mainLoop(void)
{
ARUint8 *dataPtr;
ARMarkerInfo *marker_info; //标志信息struct
int marker_num;
int j, k;
//获取一帧图像
if ((dataPtr = (ARUint8 *)arVideoGetImage()) == NULL) {
//调用延迟
arUtilSleep(2);
return;
}
if (count == 0) arUtilTimerReset();
count++;
//为了渲染2d 更新当前相机参数
argDrawMode2D();
argDispImage(dataPtr, 0, 0);
//检测标识
/*
arDetectMarker()的参数分别是
dataPtr 帧数据
thresh 二值化阈值
marker_info 标识特征信息
marker_num 标识数量
*/
if (arDetectMarker(dataPtr, thresh, &marker_info, &marker_num) < 0) {
cleanup();
exit(0);
}
//每一帧都要调用,支持诸多功能的完成
arVideoCapNext();
k = -1;
for (j = 0; j < marker_num; j++) {
if (patt_id == marker_info[j].id) {
if (k == -1) k = j;
else if (marker_info[k].cf < marker_info[j].cf) k = j;
}
}
if (k == -1) {
argSwapBuffers();
return;
}
//获取相机的位置
arGetTransMat(&marker_info[k], patt_center, patt_width, patt_trans);
//绘制模型到对应的位置
draw();
argSwapBuffers();
}
static void init(void)
{
ARParam wparam;
//打开相机参数文件
arVideoOpen(vconf);
//获取视频窗口大小
arVideoInqSize(&xsize, &ysize);
//设置相机特征参数
arParamLoad(cparam_name, 1, &wparam);
arParamChangeSize(&wparam, xsize, ysize, &cparam);
//初始化相机
arInitCparam(&cparam);
arParamDisp(&cparam);
//读取多个标识 的定义文件
patt_id = arLoadPatt(patt_name);
//打开图像窗口
argInit(&cparam, 1.0, 0, 0, 0, 0);
}
//cleanup
static void cleanup(void)
{
arVideoCapStop();
arVideoClose();
argCleanup();
}
//绘制3D模型 纯opengl的内容
static void draw(void)
{
double gl_para[16];
GLfloat mat_ambient[] = { 0.0, 0.0, 1.0, 1.0 };
GLfloat mat_flash[] = { 0.0, 0.0, 1.0, 1.0 };
GLfloat mat_flash_shiny[] = { 50.0 };
GLfloat light_position[] = { 100.0,-200.0,200.0,0.0 };
GLfloat ambi[] = { 0.1, 0.1, 0.1, 0.1 };
GLfloat lightZeroColor[] = { 0.9, 0.9, 0.9, 0.1 };
argDrawMode3D();
argDraw3dCamera(0, 0);
glClearDepth(1.0);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
//加载相机转换矩阵
argConvGlpara(patt_trans, gl_para);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(gl_para);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambi);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0.0, 0.0, 25.0);
glutSolidCube(50.0);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
}