ARtoolkit源碼閱讀(一) artoolkit框架simpletest.c

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章