当前位置: 首页 > 工具软件 > Artoolkit > 使用案例 >

ARtoolkit源码阅读(一) artoolkit框架simpletest.c

李昊苍
2023-12-01

ARToolKit 框架

ARToolKit 是基于opengl和DSVL的增强现实软件包。它遵循opengl的运行模式,基于帧循环实现3D渲染。
主要流程:
1. 初始化视频捕获arVideoCapStart()、读取文件的标记模式、相机参数 arVideoOpen(vconf)
2. 获取一帧输入视频
3. 在输入视频图像中 检测标识和注册的模板
4. 计算相机相对于检测到模板的位置
5. 绘制虚拟模型到检测的模板上
6. 关闭视频捕获arVideoCapStop()、arVideoClose(),回收资源argCleanup()

SimpleTest.c源码

// 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);
}

 类似资料: