ARtoolkit源码阅读(二) openvrml+simplevrml

思考一个问题,artoolkit可以利用opengl绘制的正方体、球形。那么我们是否可以用自己的三维模型去替代它们你?

wrl文件是一种虚拟现实文本格式文件,也是VRML的场景模型文件的扩展名。将三维模型保存成wrl格式,在通过openVRML支持artoolkit 绘制三维模型。

配置openVRML环境

想要编译simplevrml.c 首先要 配置openVRML的环境,如下:
【include】
OpenVRML\dependencies\include
OpenVRML\include
【lib】
OpenVRML\dependencies\lib
OpenVRML\lib
【连接器-输入】
openvrml.lib
openvrml-gl.lib
antlr.lib
regex.lib

这时候编译还是会报错,出现C2001的,lib无法解析

【解决方案】 重新编译openVRML。
打开 OpenVRML\src\openvrml-0.14.3\ide-projects\Windows\VisualC7\OpenVRML\openvrml.sln
然后编译生成 4个lib,并把lib 放置在 OpenVrML\lib的 位置

simplevrml.c 源码分析

simplevrml.c 使用的MainLoop()框架与之前的simpletest不同。simpletest的框架以opengl为主,而simplevrml.c的框架则是以ar为主。

变量声明

#define VIEW_SCALEFACTOR    0.025   //一个ARToolKit单位变成0.025个OpenGL单位。  
#define VIEW_SCALEFACTOR_1  1.0     // 1.0 ARToolKit unit becomes 1.0 of my OpenGL units.  
#define VIEW_SCALEFACTOR_4  4.0     // 1.0 ARToolKit unit becomes 4.0 of my OpenGL units.  
#define VIEW_DISTANCE_MIN   4.0     // 目标与摄像机距离小于4.0不显示  
#define VIEW_DISTANCE_MAX   4000.0  // 目标与摄像机距离大于4000不显示  
//OpenGL初始化参数设置Preferences.  
static int prefWindowed = TRUE;  
static int prefWidth = 640; //全屏模式的宽度  
static int prefHeight = 480;//全屏模式的高度  
static int prefDepth = 32;//全屏模式的位深度  
static int prefRefresh = 0; //全屏模式刷新率  

static ARUint8  *gARTImage = NULL;//获取图像  

static int   gARTThreshhold = 100; //标识检测时的二值化阈值  
static long  gCallCountMarkerDetect = 0;//初始化ARToolKit 帧频计数器为0  

//Transformation matrix retrieval.//转换矩阵检索  
static int  gPatt_found = FALSE;//用gPatt_found判断是否找到标识  


static ARParam  gARTCparam;  
static ARGL_CONTEXT_SETTINGS_REF gArglSettings = NULL;  

static ObjectData_T *gObjectData;  
static int  gObjectDataCount;  

setupCamera()

setupCamera()函数 主要的作用是打开相机,导入相机参数,设置相机大小,初始化相机参数, 捕获图像

//打开相机,导入相机参数,更改相机长宽大小,初始化相机参数,捕获图像  
static int setupCamera(const char *cparam_name, char *vconf, ARParam *cparam)
{
    ARParam   wparam;//储存相机参数  
    int   xsize, ysize;//储存图像大小的值  
    //打开视频路径  
    if (arVideoOpen(vconf) < 0) {
        fprintf(stderr, "setupCamera(): Unable to open connection to camera.\n");
        return (FALSE);
    }

    //得到当前视频图像的大小 
    arVideoInqSize(&xsize, &ysize);
    //导入相机参数,重新定义窗口大小
    arParamLoad(cparam_name, 1, &wparam);
    arParamChangeSize(&wparam, xsize, ysize, cparam);
    //显示参数值
    arParamDisp(cparam);
    //初始化相机参数
    arInitCparam(cparam);
    //开始捕获图像
    arVideoCapStart();
    return (TRUE);
}

setupMarkersObjects()

setupMarkersObjects()函数 主要作用是 导入一个或者多个标识的图像矩阵

//导入一个或多个标识的图像矩阵  
static int setupMarkersObjects(char *objectDataFilename)
{
    //导入一个或多个标识图---训练标识及其相关的位图文件,这里使用了object.c文件中的read_VRMLdata()函数
    if ((gObjectData = read_VRMLdata(objectDataFilename, &gObjectDataCount)) == NULL) {
        fprintf(stderr, "setupMarkersObjects(): read_VRMLdata returned error !!\n");
        return (FALSE);
    }
    printf("Object count = %d\n", gObjectDataCount);
    return (TRUE);
}

Display()

当窗口需要重新绘制模型的时候,调用该函数。

static void Display(void)
{
    int i;
    GLdouble p[16];
    GLdouble m[16];

//第一步:清除屏幕,显示最新的后台缓冲帧  
    glDrawBuffer(GL_BACK);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the buffers for new frame.
    arglDispImage(gARTImage, &gARTCparam, 1.0, gArglSettings);  
    arVideoCapNext(); //开启下一帧
    gARTImage = NULL; //当调用了arVideoCapNext()函数后,此时图像数据不再有效,等待接收下一帧图像。 
//第二步:寻找标识,并根据相机参数设置投影矩阵  
    if (gPatt_found) {
        // 如果找到标识,就执行下面的程序
        arglCameraFrustumRH(&gARTCparam, VIEW_DISTANCE_MIN, VIEW_DISTANCE_MAX, p);
        //把相机参数转换成OpenGL投影矩阵16的数组,然后直接导入,  
        //生成的三维物体就会匹配真实的相机视角
        glMatrixMode(GL_PROJECTION);
        glLoadMatrixd(p);
        glMatrixMode(GL_MODELVIEW);
        // Viewing transformation.视景变换 
        glLoadIdentity();

        for (i = 0; i < gObjectDataCount; i++) {//对标识进行遍历  
            if ((gObjectData[i].visible != 0) && (gObjectData[i].vrml_id >= 0)) {//如果该标识被设置为可见(该设置在Idle()函数中完成)且ID正确那么就执行以下代码  
                arglCameraViewRH(gObjectData[i].trans, m, VIEW_SCALEFACTOR_4);
                /*
                 创建一个视景矩阵,传递给OpenGL设置虚拟相机的视景变换。
                 转换标识转换矩阵成OpenGL视景矩阵,这16个值就是真实相机的位置和方向,
                 使用他们设置虚拟相机的位置,
                 使三维目标准确的放置在物理标识上。  
                */
                glLoadMatrixd(m);//这里是设置虚拟相机的位置。
//第三步:在标识上画出虚拟物体。  
                arVrmlDraw(gObjectData[i].vrml_id);//根据前面加载的模型ID绘制模型  
            }
        }
    } 

    glutSwapBuffers();//清理缓存  
}

object_data_vrml 文件解读

#the number of patterns to be recognized
2

#pattern 1
VRML    ../Wrl/bud_B.dat
../Data/patt.hiro 
80.0
0.0 0.0

#pattern 2
VRML    ../Wrl/snoman.dat
../Data/patt.kanji
80.0
0.0 0.0
  • # 开头的为注释
  • 第一个行标识 pattern被标识的个数为 2
  • “VRML ../Wrl/bud_B.dat” 标识第一个pattern 模型的路径
  • ../Data/patt.hiro 为对应标识的路径

- 标识的宽度为80,标识的中心坐标为(0,0)

../Wrl/bud_B.dat

bud_B.wrl  
0.0 0.0 0.0     # Translation  
0.0 0.0 0.0 0.0     # Rotation  
10.0 10.0 10.0      # Scale  
  • 第一行是 vrml 模型文件
  • 第二行 平移参数
  • 第三行 旋转参数
  • 第四行 缩放参数

show

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值