RToolkit5.4自带的示例是控制台程序,用MFC单文档改写过程如下:
1、开发环境
Win10,VS2017,ARToolkit5.4
2、新建MFC单文档程序Test
在类向导中,为CTestView类添加WM_CREATE消息响应函数
3、在CTestView类的OnCreate函数中,执行以下步骤:
(1)初始化OpenGL
BOOL CTestView::InitializeOpenGL(void)
{
PIXELFORMATDESCRIPTOR pfd;
int n;
m_pDC = new CClientDC(this);
ASSERT(m_pDC != NULL);
// 设置当前的绘图像素格式
if (!SetupPixelFormat())
{
return FALSE;
}
n = ::GetPixelFormat(m_pDC->GetSafeHdc());
::DescribePixelFormat(m_pDC->GetSafeHdc(), n, sizeof(pfd), &pfd);
// 创建绘图描述表
m_hRC = wglCreateContext(m_pDC->GetSafeHdc());
if (m_hRC == NULL)
{
return FALSE;
}
// 使绘图描述表为当前调用现程的当前绘图描述表
if (wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC) == FALSE)
{
return FALSE;
}
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
return TRUE;
}
BOOL CTestView::SetupPixelFormat(void)
{
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // pfd结构的大小
1, // 版本号
PFD_DRAW_TO_WINDOW | // 支持在窗口中绘图
PFD_SUPPORT_OPENGL | // 支持 OpenGL
PFD_DOUBLEBUFFER, // 双缓存模式
PFD_TYPE_RGBA, // RGBA 颜色模式
24, // 24 位颜色深度
0, 0, 0, 0, 0, 0, // 忽略颜色位
0, // 没有非透明度缓存
0, // 忽略移位位
0, // 无累计缓存
0, 0, 0, 0, // 忽略累计位
32, // 32 位深度缓存
0, // 无模板缓存
0, // 无辅助缓存
PFD_MAIN_PLANE, // 主层
0, // 保留
0, 0, 0 // 忽略层,可见性和损毁掩模
};
int pixelFormat;
// 为设备描述表得到最匹配的像素格式
if ((pixelFormat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd)) == 0)
{
MessageBox(_T("ChoosePixelFormat failed"));
return FALSE;
}
// 设置最匹配的像素格式为当前的像素格式
if (SetPixelFormat(m_pDC->GetSafeHdc(), pixelFormat, &pfd) == FALSE)
{
MessageBox(_T("SetPixelFormat failed"));
return FALSE;
}
return TRUE;
}
(2)初始化摄像头和加载标签
两个关键的函数:setupCamera和setupMarker,直接从simpleLite中拷贝,分别添加如下:
int CTestView::setupCamera(const char *cparam_name, char *vconf, ARParamLT **cparamLT_p, ARHandle **arhandle, AR3DHandle **ar3dhandle)
int CTestView::setupMarker(const char *patt_name, int *patt_id, ARHandle *arhandle, ARPattHandle **pattHandle_p)
然后CTestView类的OnCreate函数如下:
int CTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
char glutGamemode[32] = "";
char *vconf = "-module=WinMF -devNum=2 -format=BGRA";
char *cparam_name = NULL;
//int i;
//int gotTwoPartOption;
char patt_name[] = "D:\\1-Desktop\\SingleDocTest\\SingleDocTest\\hiro.patt";
InitializeOpenGL();
if (!setupCamera(cparam_name, vconf, &gCparamLT, &gARHandle, &gAR3DHandle)) {
ARLOGe("main(): Unable to set up AR camera.\n");
exit(-1);
}
if ((gArglSettings = arglSetupForCurrentContext(&(gCparamLT->param), arVideoGetPixelFormat())) == NULL) {
ARLOGe("main(): arglSetupForCurrentContext() returned error.\n");
cleanup();
exit(-1);
}
arglSetupDebugMode(gArglSettings, gARHandle);
arUtilTimerReset();
// Load marker(s).
if (!setupMarker(patt_name, &gPatt_id, gARHandle, &gARPattHandle)) {
ARLOGe("main(): Unable to set up AR marker.\n");
cleanup();
exit(-1);
}
SetTimer(1, 30, NULL);
//glutReshapeFunc(Reshape);
return 0;
}
4、拷贝mainloop函数,用于获取视频图像、检测标志物、计算标志物和摄像机之间的变换矩阵
注意要注释掉其中OpenGL画图的代码,包括计算重新画图的时间间隔,以及用于标记窗口重画的glutPostRedisplay函数等。函数如下:
void CTestView::mainLoop(void)
5、在标志物上画出三维模型
从simpleLite中拷贝Display、DrawCube函数,如下所示:
void CTestView::Display(void)
void CTestView::DrawCube(void)
并且修改Display代码,在函数第一行、最后一行分别添加代码:
wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);
SwapBuffers(wglGetCurrentDC());
并注释掉glutSwapBuffers();
6、在CTestView类中添加定时器,进行循环调用mainLoop、Display函数
void CTestView::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (nIDEvent == 1) //定时器1处理函数,
{
mainLoop();
Display();
}
CView::OnTimer(nIDEvent);
}
在OnCreate最后启动定时器
SetTimer(1, 30, NULL);
7、环境配置
包含目录:
库目录:
附加依赖项:
8、运行结果
例子下载地址
ARToolkit5.4+VS2017编译包下载地址