#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef __APPLE__
# ifdef _WIN32
# include <windows.h>
# endif
# include <GL/glut.h>
#else
# include <GLUT/glut.h>
#endif
#include <AR/ar.h>
#include <AR/gsub.h>
#include <AR/video.h>
#include <AR/arMulti.h>
#include "GLFont.h"
#include "BasicInfo.h"
//#define CPARA_NAME "Data/camera_para.dat"
//#define CONFIG_NAME "Data/multi/marker.dat"
#define CPARA_NAME "E:/MyGitProject/vsProjectCollection/ARDrawWord/ARToolKitTest/Data/camera_para.dat"
#define CONFIG_NAME "E:/MyGitProject/vsProjectCollection/ARDrawWord/ARToolKitTest/Data/testM/barcode.dat" //marker.dat"
ARHandle *arHandle;
AR3DHandle *ar3DHandle;
ARGViewportHandle *vp;
ARMultiMarkerInfoT *config;
int robustFlag = 0;
int count;
ARParamLT *gCparamLT1 = NULL;
static void init(int argc, char *argv[]);
static void cleanup(void);
static void mainLoop(void);
static void draw(ARdouble trans1[3][4], ARdouble trans2[3][4], int mode);
static void keyEvent(unsigned char key, int x, int y);
void DrawCube_multi(LPCTSTR disContent);
void DrawCube1(void);
int main(int argc, char *argv[])
{
//初始化openGL环境
glutInit(&argc, argv);//
init(argc, argv);
//设置显示函数
argSetDispFunc(mainLoop, 1);
//设置键盘输入事件函数
argSetKeyFunc(keyEvent);
count = 0;
arVideoCapStart();//开始捕获视频源
arUtilTimerReset();//重置定时器
argMainLoop();//glut主循环
return (0);
}
static void keyEvent(unsigned char key, int x, int y)
{
int debug;
int thresh;
/* quit if the ESC key is pressed */
if (key == 0x1b) {
ARLOG("*** %f (frame/sec)\n", (double)count / arUtilTimer());
cleanup();
exit(0);
}
if (key == 'd') {
arGetDebugMode(arHandle, &debug);
debug = 1 - debug;
arSetDebugMode(arHandle, debug);
}
if (key == '1') {
arGetDebugMode(arHandle, &debug);
if (debug) {
arGetLabelingThresh(arHandle, &thresh);
thresh -= 5;
if (thresh < 0) thresh = 0;
arSetLabelingThresh(arHandle, thresh);
ARLOG("thresh = %d\n", thresh);
}
}
if (key == '2') {
arGetDebugMode(arHandle, &debug);
if (debug) {
arGetLabelingThresh(arHandle, &thresh);
thresh += 5;
if (thresh > 255) thresh = 255;
arSetLabelingThresh(arHandle, thresh);
ARLOG("thresh = %d\n", thresh);
}
}
if (key == ' ') {
robustFlag = 1 - robustFlag;
if (robustFlag) ARLOG("Robust estimation mode.\n");
else ARLOG("Normal estimation mode.\n");
}
}
/* main loop */
static void mainLoop(void)
{
ARUint8 *dataPtr;//捕获视频数据的数据指针 unsigned char 类型
ARMarkerInfo *marker_info;//描述一个被检测到梯形区域相关信息
int marker_num;
int imageProcMode; //图像处理模式
int debugMode;
double err;
int i;
/* grab a video frame */
if ((dataPtr = (ARUint8 *)arVideoGetImage()) == NULL) {
arUtilSleep(2); //休眠2毫秒
return;//arVideoGetImage 返回被捕获视频图像的buffer,从左上角第一行开始读取数据,逐行读取
}
//获取一帧图片
if (count == 100) {
ARLOG("*** %f (frame/sec)\n", (double)count / arUtilTimer());
arUtilTimerReset(); //获取到100张图片后对定时器进行重置
count = 0;
}
count++;
/* detect the markers in the video frame */
if (arDetectMarker(arHandle, dataPtr) < 0) {
cleanup();
exit(0);
}
marker_num = arGetMarkerNum(arHandle); //获取从 video frame中检测到的marker数目
marker_info = arGetMarker(arHandle); //获取检测到的marker_info信息
for (int cnt = 0; cnt < marker_num; cnt++){
if (marker_info[cnt].id >= 0){
//若为单独一个模型检测,则可以直接打印其置信度等相关信息
printf("检测到第%d个标记与配置文件中的标识%d之间的相似度为:%f\n", cnt, marker_info[cnt].id, marker_info[cnt].cf);
}
else if (marker_info[cnt].idPatt >= 0){
//若为多个模型,且模型为自定义模板,则将打印其相似度信息如下
printf("检测到第%d个标记与配置文件中的标识%d之间的相似度为:%f\n", cnt, marker_info[cnt].idPatt, marker_info[cnt].cfPatt);
}
else if (marker_info[cnt].idMatrix >= 0){
//若为多个模型,且模型为二维条形码,则将打印其相似度信息如下
printf("检测到第%d个标记与配置文件中的标识%d之间的相似度为:%f\n", cnt, marker_info[cnt].idMatrix, marker_info[cnt].cfMatrix);
}
}
argDrawMode2D(vp); //Update curent camera parameters (internal and external) for rendering 2D or 3D objects in the view plane (like text or 2D shape).
arGetDebugMode(arHandle, &debugMode); //Find out whether ARToolKit's debug mode is enabled.
if (debugMode == 0) {
argDrawImage(dataPtr);
}
else {
arGetImageProcMode(arHandle, &imageProcMode); //Get the image processing mode.
if (imageProcMode == AR_IMAGE_PROC_FRAME_IMAGE) {
argDrawImage(arHandle->labelInfo.bwImage);
}
else {
argDrawImageHalf(arHandle->labelInfo.bwImage);
}
glColor3f(1.0f, 0.0f, 0.0f);
glLineWidth(2.0f);
for (i = 0; i < marker_num; i++) {
argDrawSquareByIdealPos(marker_info[i].vertex);
}
glLineWidth(1.0f);
}
if (robustFlag) {
err = arGetTransMatMultiSquareRobust(ar3DHandle, marker_info, marker_num, config);
}
else {
err = arGetTransMatMultiSquare(ar3DHandle, marker_info, marker_num, config);
}
if (config->prevF == 0) {
argSwapBuffers();
return;
}
//ARLOGd("err = %f\n", err);
argDrawMode3D(vp);
glClearDepth(1.0);
glClear(GL_DEPTH_BUFFER_BIT);
for (i = 0; i < config->marker_num; i++) {
if (config->marker[i].visible >= 0) draw(config->trans, config->marker[i].trans, 0, i);
/*else draw(config->trans, config->marker[i].trans, 1, i);*/
}
argSwapBuffers();
}
static void init(int argc, char *argv[])
{
ARParam cparam;
ARGViewport viewport;
ARPattHandle *arPattHandle;
char vconf[512];
char configName[512];
int xsize, ysize;
AR_PIXEL_FORMAT pixFormat;
int i;
configName[0] = '\0';
vconf[0] = '\0';
for (i = 1; i < argc; i++) {
if (strncmp(argv[i], "-config=", 8) == 0) {
strcpy(configName, &argv[i][8]);
}
else {
if (vconf[0] != '\0') strcat(vconf, " ");
strcat(vconf, argv[i]);
}
}
if (configName[0] == '\0') strcpy(configName, CONFIG_NAME);
/* open the video path */
if (arVideoOpen(vconf) < 0) exit(0);
/* find the size of the window */
if (arVideoGetSize(&xsize, &ysize) < 0) exit(0);
ARLOGi("Image size (x,y) = (%d,%d)\n", xsize, ysize);
if ((pixFormat = arVideoGetPixelFormat()) < 0) exit(0);
/* set the initial camera parameters */
if (arParamLoad(CPARA_NAME, 1, &cparam) < 0) {
ARLOGe("Camera parameter load error !!\n");
exit(0);
}
arParamChangeSize(&cparam, xsize, ysize, &cparam);
ARLOG("*** Camera Parameter ***\n");
arParamDisp(&cparam);
if ((gCparamLT1 = arParamLTCreate(&cparam, AR_PARAM_LT_DEFAULT_OFFSET)) == NULL) {
ARLOGe("Error: arParamLTCreate.\n");
exit(-1);
}
if ((arHandle = arCreateHandle(gCparamLT1)) == NULL) {
ARLOGe("Error: arCreateHandle.\n");
exit(0);
}
if (arSetPixelFormat(arHandle, pixFormat) < 0) {
ARLOGe("Error: arSetPixelFormat.\n");
exit(0);
}
if ((ar3DHandle = ar3DCreateHandle(&cparam)) == NULL) {
ARLOGe("Error: ar3DCreateHandle.\n");
exit(0);
}
if ((arPattHandle = arPattCreateHandle()) == NULL) {
ARLOGe("Error: arPattCreateHandle.\n");
exit(0);
}
arPattAttach(arHandle, arPattHandle);
if ((config = arMultiReadConfigFile(configName, arPattHandle)) == NULL) {
ARLOGe("config data load error !!\n");
exit(0);
}
//提高每个图像检测之间的相似度截止频率,默认值为0.5,这样提高检测的准确度
config->cfMatrixCutoff = 0.6;
config->cfPattCutoff = 0.6;
if (config->patt_type == AR_MULTI_PATTERN_DETECTION_MODE_TEMPLATE) {
arSetPatternDetectionMode(arHandle, AR_TEMPLATE_MATCHING_COLOR);
}
else if (config->patt_type == AR_MULTI_PATTERN_DETECTION_MODE_MATRIX) {
arSetPatternDetectionMode(arHandle, AR_MATRIX_CODE_DETECTION);
arSetMatrixCodeType(arHandle, AR_MATRIX_CODE_4x4);
}
else { // AR_MULTI_PATTERN_DETECTION_MODE_TEMPLATE_AND_MATRIX
arSetPatternDetectionMode(arHandle, AR_TEMPLATE_MATCHING_COLOR_AND_MATRIX);
arSetMatrixCodeType(arHandle, AR_MATRIX_CODE_4x4);
}
/* open the graphics window */
viewport.sx = 0;
viewport.sy = 0;
viewport.xsize = xsize;
viewport.ysize = ysize;
if ((vp = argCreateViewport(&viewport)) == NULL) exit(0);
argViewportSetCparam(vp, &cparam);
argViewportSetPixFormat(vp, pixFormat);
}
/* cleanup function called when program exits */
static void cleanup(void)
{
arParamLTFree(&gCparamLT1);
arVideoCapStop();
arVideoClose();
argCleanup();
}
static void draw(ARdouble trans1[3][4], ARdouble trans2[3][4], int mode, int patt_num)
{
ARdouble gl_para[16];
GLfloat light_position[] = { 100.0f, -200.0f, 200.0f, 0.0f };
GLfloat light_ambi[] = { 0.1f, 0.1f, 0.1f, 0.0f };
GLfloat light_color[] = { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat mat_flash[] = { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat mat_flash_shiny[] = { 50.0f };
GLfloat mat_diffuse[] = { 0.0f, 0.0f, 1.0f, 1.0f };
GLfloat mat_diffuse1[] = { 1.0f, 0.0f, 0.0f, 1.0f };
int debugMode;
//glEnable(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
/* load the camera transformation matrix */
glMatrixMode(GL_MODELVIEW);
argConvGlpara(trans1, gl_para);
#ifdef ARDOUBLE_IS_FLOAT
glLoadMatrixf(gl_para);
#else
glLoadMatrixd(gl_para);
#endif
argConvGlpara(trans2, gl_para);
#ifdef ARDOUBLE_IS_FLOAT
glMultMatrixf(gl_para);
#else
glMultMatrixd(gl_para);
#endif
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambi);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_color);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny);
if (mode == 0) {
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse);
}
else {
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse1);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse1);
}
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
//glTranslatef(0.0f, 0.0f, 20.0f);
glTranslatef(0.0f, 0.0f, 0.0f);
arGetDebugMode(arHandle, &debugMode);
if (debugMode == 0){
switch (patt_num){
case 0: {
char *dispContent = getAirInfo();
DrawCube_multi(dispContent);
free(dispContent);
dispContent = NULL;
break;
}
case 1:{
char *dispContent = getHotChannelInfo();
DrawCube_multi(dispContent);
free(dispContent);
dispContent = NULL;
break;
}
case 2: {
char *dispContent = getColdChannelInfo();
DrawCube_multi(dispContent);
free(dispContent);
dispContent = NULL;
break;
}
case 3:{
char *dispContent = getCabinetInfo();
DrawCube_multi(dispContent);
free(dispContent);
dispContent = NULL;
break;
}
case 4:{
char *dispContent = getPDUInfo();
DrawCube_multi(dispContent);
free(dispContent);
dispContent = NULL;
break;
}
case 5:{
char *dispContent = getShortColdChannelInfo();
DrawCube_multi(dispContent);
free(dispContent);
dispContent = NULL;
break;
}
default:
DrawCube_multi("没有相对应的设备信息");
}
}
else {
DrawCube_multi("没有相对应的设备信息");
}
glPopMatrix();
glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
//glDisable(GL_DEPTH_TEST);
}
void DrawCube_multi(char *disContent)
{
// Colour cube data.
int i;
float fSize = 40.0f;
//平面大小 2.4*2.4
const GLfloat cube_vertices[8][3] = {
/* +z */{ 1.2f, 1.2f, 0.5f }, { 1.2f, -1.2f, 0.5f }, { -1.2f, -1.2f, 0.5f }, { -1.2f, 1.2f, 0.5f },
/* -z */{ 1.2f, 1.2f, 0.5f }, { 1.2f, -1.2f, 0.5f }, { -1.2f, -1.2f, 0.5f }, { -1.2f, 1.2f, 0.5f } };
//绿色,全透明
const GLubyte cube_vertex_colors[8][4] = {
{ 0, 255, 0, 255 }, { 0, 255, 0, 255 }, { 0, 255, 0, 255 }, { 0, 255, 0, 255},
{ 0, 255, 0, 255 }, { 0, 255, 0, 255}, { 0, 255, 0, 255}, { 0, 255, 0, 255} };
const GLubyte cube_faces[6][4] = { /* ccw-winding counter - clockwise winding 逆时针方向缠绕*/
/* +z */{ 3, 2, 1, 0 }, /* -x */{ 2, 3, 7, 6 }, /* +x */{ 0, 1, 5, 4 },
/* -y */{ 3, 0, 4, 7 }, /* +y */{ 1, 2, 6, 5 }, /* -z */{ 4, 5, 6, 7 } };
glPushMatrix(); // Save world coordinate system.
glScalef(fSize, fSize, fSize);
glTranslatef(-0.3f, 0.05f, 0.0f); // Place base of cube on marker surface. 覆盖整个标签,z轴不变,x,y
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);//纹理
//glDisable(GL_BLEND);
glEnable(GL_BLEND);
glDepthMask(GL_FALSE);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, cube_vertex_colors);//指定含有顶点颜色的数组
glVertexPointer(3, GL_FLOAT, 0, cube_vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
for (i = 0; i < 6; i++) {
//glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_BYTE, &(cube_faces[i][0]));
glDrawElements(GL_LINE, 4, GL_UNSIGNED_BYTE, &(cube_faces[i][0]));
}
glDisableClientState(GL_COLOR_ARRAY);
glColor4ub(0, 0, 0, 255);
for (i = 0; i < 6; i++) {
glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_BYTE, &(cube_faces[i][0]));
}
//glBlendFunc(GL_ONE, GL_ONE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glDepthMask(GL_TRUE);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_BLEND);
/*CreateFont的参数
cHeight 字体的逻辑高度
cWidth 字体的逻辑宽度
cEscapement 指定移位向量相对x轴的偏转角度
cOrientation 指定字符基线相对x轴的偏转角度
cWeight 设置字符粗细程度
bItalic 是否启用斜体
bUnderline 是否启用下划线
bStrikeOut 是否启用删除线
iCharset 指定字符集
iOutPrecision 输出精度
iClipPrecision 剪裁精度
iQuality 输出质量
iPitchAndFamily 字体族
pszFaceName 字体名
*/
HFONT hFont = CreateFont(0, 0, 0, 0, 100, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, FF_MODERN, TEXT("宋体"));
/*根据字符串里面是否包含\n对字符串进行行分割并进行多行显示*/
char delims[] = "\n";
char *lineStr=NULL;
//将字符串常量转为字符串变量
char *dispContentStr = (char *)malloc(sizeof(char)*(strlen(disContent) + 1));
int yOffsetUnitCnt = 0;
float originY = 0.7f;
float actualY = originY;
float moveYdistance = 0.2f;
if (dispContentStr != NULL){
strcpy(dispContentStr, disContent);
lineStr = strtok(dispContentStr, delims); //strtok中的char *Str为非常量指针,而非常量指针可以隐式转换为常量指针,由于strtok会对指针指向值进行修改,
while (lineStr != NULL){ //所以当Str为常量指针时,编译时没有问题,但运行时会报错
actualY = originY - yOffsetUnitCnt*moveYdistance;
draw3dtextWithCloseLight(lineStr, hFont, 0.2f, -1.1f, actualY, 0.7f, 0.2f, 0.2f, 0.2f, 0.0f, 0.0f, 0.0f);
printf("result is \"%s\"\n", lineStr);
lineStr = strtok(NULL, delims);
yOffsetUnitCnt++;
}
}
else{
printf("mallocerror\n");
exit(-1);
}
free(dispContentStr);
dispContentStr = NULL;
/*
str 一行需要显示的字体
hFont 一种具有特殊性的逻辑字体,在后面可以被任何设备选择
cDepth 字体的深度
dXoffset,Yoffset,Zoffset 偏移原点位置
*/
//draw3dtextWithCloseLight(disContent, hFont, 0.0f, -0.5f, -0.5f, 0.6f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f);
//draw3dtextWithCloseLight(disContent, hFont, 0.0f, -0.5f, 0.0f, 0.6f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f);
//draw3dtextWithCloseLight(disContent, hFont, 0.0f, -0.5f, 0.5f, 0.6f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f);
glPopMatrix(); // Restore world coordinate system.
}
#include <stdlib.h>
#include <string.h>
#ifndef __APPLE__
# ifdef _WIN32
# include <windows.h>
# endif
# include <GL/glut.h>
#else
# include <GLUT/glut.h>
#endif
#include <AR/ar.h>
#include <AR/gsub.h>
#include <AR/video.h>
#include <AR/arMulti.h>
#include "GLFont.h"
#include "BasicInfo.h"
//#define CPARA_NAME "Data/camera_para.dat"
//#define CONFIG_NAME "Data/multi/marker.dat"
#define CPARA_NAME "E:/MyGitProject/vsProjectCollection/ARDrawWord/ARToolKitTest/Data/camera_para.dat"
#define CONFIG_NAME "E:/MyGitProject/vsProjectCollection/ARDrawWord/ARToolKitTest/Data/testM/barcode.dat" //marker.dat"
ARHandle *arHandle;
AR3DHandle *ar3DHandle;
ARGViewportHandle *vp;
ARMultiMarkerInfoT *config;
int robustFlag = 0;
int count;
ARParamLT *gCparamLT1 = NULL;
static void init(int argc, char *argv[]);
static void cleanup(void);
static void mainLoop(void);
static void draw(ARdouble trans1[3][4], ARdouble trans2[3][4], int mode);
static void keyEvent(unsigned char key, int x, int y);
void DrawCube_multi(LPCTSTR disContent);
void DrawCube1(void);
int main(int argc, char *argv[])
{
//初始化openGL环境
glutInit(&argc, argv);//
init(argc, argv);
//设置显示函数
argSetDispFunc(mainLoop, 1);
//设置键盘输入事件函数
argSetKeyFunc(keyEvent);
count = 0;
arVideoCapStart();//开始捕获视频源
arUtilTimerReset();//重置定时器
argMainLoop();//glut主循环
return (0);
}
static void keyEvent(unsigned char key, int x, int y)
{
int debug;
int thresh;
/* quit if the ESC key is pressed */
if (key == 0x1b) {
ARLOG("*** %f (frame/sec)\n", (double)count / arUtilTimer());
cleanup();
exit(0);
}
if (key == 'd') {
arGetDebugMode(arHandle, &debug);
debug = 1 - debug;
arSetDebugMode(arHandle, debug);
}
if (key == '1') {
arGetDebugMode(arHandle, &debug);
if (debug) {
arGetLabelingThresh(arHandle, &thresh);
thresh -= 5;
if (thresh < 0) thresh = 0;
arSetLabelingThresh(arHandle, thresh);
ARLOG("thresh = %d\n", thresh);
}
}
if (key == '2') {
arGetDebugMode(arHandle, &debug);
if (debug) {
arGetLabelingThresh(arHandle, &thresh);
thresh += 5;
if (thresh > 255) thresh = 255;
arSetLabelingThresh(arHandle, thresh);
ARLOG("thresh = %d\n", thresh);
}
}
if (key == ' ') {
robustFlag = 1 - robustFlag;
if (robustFlag) ARLOG("Robust estimation mode.\n");
else ARLOG("Normal estimation mode.\n");
}
}
/* main loop */
static void mainLoop(void)
{
ARUint8 *dataPtr;//捕获视频数据的数据指针 unsigned char 类型
ARMarkerInfo *marker_info;//描述一个被检测到梯形区域相关信息
int marker_num;
int imageProcMode; //图像处理模式
int debugMode;
double err;
int i;
/* grab a video frame */
if ((dataPtr = (ARUint8 *)arVideoGetImage()) == NULL) {
arUtilSleep(2); //休眠2毫秒
return;//arVideoGetImage 返回被捕获视频图像的buffer,从左上角第一行开始读取数据,逐行读取
}
//获取一帧图片
if (count == 100) {
ARLOG("*** %f (frame/sec)\n", (double)count / arUtilTimer());
arUtilTimerReset(); //获取到100张图片后对定时器进行重置
count = 0;
}
count++;
/* detect the markers in the video frame */
if (arDetectMarker(arHandle, dataPtr) < 0) {
cleanup();
exit(0);
}
marker_num = arGetMarkerNum(arHandle); //获取从 video frame中检测到的marker数目
marker_info = arGetMarker(arHandle); //获取检测到的marker_info信息
for (int cnt = 0; cnt < marker_num; cnt++){
if (marker_info[cnt].id >= 0){
//若为单独一个模型检测,则可以直接打印其置信度等相关信息
printf("检测到第%d个标记与配置文件中的标识%d之间的相似度为:%f\n", cnt, marker_info[cnt].id, marker_info[cnt].cf);
}
else if (marker_info[cnt].idPatt >= 0){
//若为多个模型,且模型为自定义模板,则将打印其相似度信息如下
printf("检测到第%d个标记与配置文件中的标识%d之间的相似度为:%f\n", cnt, marker_info[cnt].idPatt, marker_info[cnt].cfPatt);
}
else if (marker_info[cnt].idMatrix >= 0){
//若为多个模型,且模型为二维条形码,则将打印其相似度信息如下
printf("检测到第%d个标记与配置文件中的标识%d之间的相似度为:%f\n", cnt, marker_info[cnt].idMatrix, marker_info[cnt].cfMatrix);
}
}
argDrawMode2D(vp); //Update curent camera parameters (internal and external) for rendering 2D or 3D objects in the view plane (like text or 2D shape).
arGetDebugMode(arHandle, &debugMode); //Find out whether ARToolKit's debug mode is enabled.
if (debugMode == 0) {
argDrawImage(dataPtr);
}
else {
arGetImageProcMode(arHandle, &imageProcMode); //Get the image processing mode.
if (imageProcMode == AR_IMAGE_PROC_FRAME_IMAGE) {
argDrawImage(arHandle->labelInfo.bwImage);
}
else {
argDrawImageHalf(arHandle->labelInfo.bwImage);
}
glColor3f(1.0f, 0.0f, 0.0f);
glLineWidth(2.0f);
for (i = 0; i < marker_num; i++) {
argDrawSquareByIdealPos(marker_info[i].vertex);
}
glLineWidth(1.0f);
}
if (robustFlag) {
err = arGetTransMatMultiSquareRobust(ar3DHandle, marker_info, marker_num, config);
}
else {
err = arGetTransMatMultiSquare(ar3DHandle, marker_info, marker_num, config);
}
if (config->prevF == 0) {
argSwapBuffers();
return;
}
//ARLOGd("err = %f\n", err);
argDrawMode3D(vp);
glClearDepth(1.0);
glClear(GL_DEPTH_BUFFER_BIT);
for (i = 0; i < config->marker_num; i++) {
if (config->marker[i].visible >= 0) draw(config->trans, config->marker[i].trans, 0, i);
/*else draw(config->trans, config->marker[i].trans, 1, i);*/
}
argSwapBuffers();
}
static void init(int argc, char *argv[])
{
ARParam cparam;
ARGViewport viewport;
ARPattHandle *arPattHandle;
char vconf[512];
char configName[512];
int xsize, ysize;
AR_PIXEL_FORMAT pixFormat;
int i;
configName[0] = '\0';
vconf[0] = '\0';
for (i = 1; i < argc; i++) {
if (strncmp(argv[i], "-config=", 8) == 0) {
strcpy(configName, &argv[i][8]);
}
else {
if (vconf[0] != '\0') strcat(vconf, " ");
strcat(vconf, argv[i]);
}
}
if (configName[0] == '\0') strcpy(configName, CONFIG_NAME);
/* open the video path */
if (arVideoOpen(vconf) < 0) exit(0);
/* find the size of the window */
if (arVideoGetSize(&xsize, &ysize) < 0) exit(0);
ARLOGi("Image size (x,y) = (%d,%d)\n", xsize, ysize);
if ((pixFormat = arVideoGetPixelFormat()) < 0) exit(0);
/* set the initial camera parameters */
if (arParamLoad(CPARA_NAME, 1, &cparam) < 0) {
ARLOGe("Camera parameter load error !!\n");
exit(0);
}
arParamChangeSize(&cparam, xsize, ysize, &cparam);
ARLOG("*** Camera Parameter ***\n");
arParamDisp(&cparam);
if ((gCparamLT1 = arParamLTCreate(&cparam, AR_PARAM_LT_DEFAULT_OFFSET)) == NULL) {
ARLOGe("Error: arParamLTCreate.\n");
exit(-1);
}
if ((arHandle = arCreateHandle(gCparamLT1)) == NULL) {
ARLOGe("Error: arCreateHandle.\n");
exit(0);
}
if (arSetPixelFormat(arHandle, pixFormat) < 0) {
ARLOGe("Error: arSetPixelFormat.\n");
exit(0);
}
if ((ar3DHandle = ar3DCreateHandle(&cparam)) == NULL) {
ARLOGe("Error: ar3DCreateHandle.\n");
exit(0);
}
if ((arPattHandle = arPattCreateHandle()) == NULL) {
ARLOGe("Error: arPattCreateHandle.\n");
exit(0);
}
arPattAttach(arHandle, arPattHandle);
if ((config = arMultiReadConfigFile(configName, arPattHandle)) == NULL) {
ARLOGe("config data load error !!\n");
exit(0);
}
//提高每个图像检测之间的相似度截止频率,默认值为0.5,这样提高检测的准确度
config->cfMatrixCutoff = 0.6;
config->cfPattCutoff = 0.6;
if (config->patt_type == AR_MULTI_PATTERN_DETECTION_MODE_TEMPLATE) {
arSetPatternDetectionMode(arHandle, AR_TEMPLATE_MATCHING_COLOR);
}
else if (config->patt_type == AR_MULTI_PATTERN_DETECTION_MODE_MATRIX) {
arSetPatternDetectionMode(arHandle, AR_MATRIX_CODE_DETECTION);
arSetMatrixCodeType(arHandle, AR_MATRIX_CODE_4x4);
}
else { // AR_MULTI_PATTERN_DETECTION_MODE_TEMPLATE_AND_MATRIX
arSetPatternDetectionMode(arHandle, AR_TEMPLATE_MATCHING_COLOR_AND_MATRIX);
arSetMatrixCodeType(arHandle, AR_MATRIX_CODE_4x4);
}
/* open the graphics window */
viewport.sx = 0;
viewport.sy = 0;
viewport.xsize = xsize;
viewport.ysize = ysize;
if ((vp = argCreateViewport(&viewport)) == NULL) exit(0);
argViewportSetCparam(vp, &cparam);
argViewportSetPixFormat(vp, pixFormat);
}
/* cleanup function called when program exits */
static void cleanup(void)
{
arParamLTFree(&gCparamLT1);
arVideoCapStop();
arVideoClose();
argCleanup();
}
static void draw(ARdouble trans1[3][4], ARdouble trans2[3][4], int mode, int patt_num)
{
ARdouble gl_para[16];
GLfloat light_position[] = { 100.0f, -200.0f, 200.0f, 0.0f };
GLfloat light_ambi[] = { 0.1f, 0.1f, 0.1f, 0.0f };
GLfloat light_color[] = { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat mat_flash[] = { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat mat_flash_shiny[] = { 50.0f };
GLfloat mat_diffuse[] = { 0.0f, 0.0f, 1.0f, 1.0f };
GLfloat mat_diffuse1[] = { 1.0f, 0.0f, 0.0f, 1.0f };
int debugMode;
//glEnable(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
/* load the camera transformation matrix */
glMatrixMode(GL_MODELVIEW);
argConvGlpara(trans1, gl_para);
#ifdef ARDOUBLE_IS_FLOAT
glLoadMatrixf(gl_para);
#else
glLoadMatrixd(gl_para);
#endif
argConvGlpara(trans2, gl_para);
#ifdef ARDOUBLE_IS_FLOAT
glMultMatrixf(gl_para);
#else
glMultMatrixd(gl_para);
#endif
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambi);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_color);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_flash);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_flash_shiny);
if (mode == 0) {
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse);
}
else {
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse1);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse1);
}
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
//glTranslatef(0.0f, 0.0f, 20.0f);
glTranslatef(0.0f, 0.0f, 0.0f);
arGetDebugMode(arHandle, &debugMode);
if (debugMode == 0){
switch (patt_num){
case 0: {
char *dispContent = getAirInfo();
DrawCube_multi(dispContent);
free(dispContent);
dispContent = NULL;
break;
}
case 1:{
char *dispContent = getHotChannelInfo();
DrawCube_multi(dispContent);
free(dispContent);
dispContent = NULL;
break;
}
case 2: {
char *dispContent = getColdChannelInfo();
DrawCube_multi(dispContent);
free(dispContent);
dispContent = NULL;
break;
}
case 3:{
char *dispContent = getCabinetInfo();
DrawCube_multi(dispContent);
free(dispContent);
dispContent = NULL;
break;
}
case 4:{
char *dispContent = getPDUInfo();
DrawCube_multi(dispContent);
free(dispContent);
dispContent = NULL;
break;
}
case 5:{
char *dispContent = getShortColdChannelInfo();
DrawCube_multi(dispContent);
free(dispContent);
dispContent = NULL;
break;
}
default:
DrawCube_multi("没有相对应的设备信息");
}
}
else {
DrawCube_multi("没有相对应的设备信息");
}
glPopMatrix();
glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
//glDisable(GL_DEPTH_TEST);
}
void DrawCube_multi(char *disContent)
{
// Colour cube data.
int i;
float fSize = 40.0f;
//平面大小 2.4*2.4
const GLfloat cube_vertices[8][3] = {
/* +z */{ 1.2f, 1.2f, 0.5f }, { 1.2f, -1.2f, 0.5f }, { -1.2f, -1.2f, 0.5f }, { -1.2f, 1.2f, 0.5f },
/* -z */{ 1.2f, 1.2f, 0.5f }, { 1.2f, -1.2f, 0.5f }, { -1.2f, -1.2f, 0.5f }, { -1.2f, 1.2f, 0.5f } };
//绿色,全透明
const GLubyte cube_vertex_colors[8][4] = {
{ 0, 255, 0, 255 }, { 0, 255, 0, 255 }, { 0, 255, 0, 255 }, { 0, 255, 0, 255},
{ 0, 255, 0, 255 }, { 0, 255, 0, 255}, { 0, 255, 0, 255}, { 0, 255, 0, 255} };
const GLubyte cube_faces[6][4] = { /* ccw-winding counter - clockwise winding 逆时针方向缠绕*/
/* +z */{ 3, 2, 1, 0 }, /* -x */{ 2, 3, 7, 6 }, /* +x */{ 0, 1, 5, 4 },
/* -y */{ 3, 0, 4, 7 }, /* +y */{ 1, 2, 6, 5 }, /* -z */{ 4, 5, 6, 7 } };
glPushMatrix(); // Save world coordinate system.
glScalef(fSize, fSize, fSize);
glTranslatef(-0.3f, 0.05f, 0.0f); // Place base of cube on marker surface. 覆盖整个标签,z轴不变,x,y
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);//纹理
//glDisable(GL_BLEND);
glEnable(GL_BLEND);
glDepthMask(GL_FALSE);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, cube_vertex_colors);//指定含有顶点颜色的数组
glVertexPointer(3, GL_FLOAT, 0, cube_vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
for (i = 0; i < 6; i++) {
//glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_BYTE, &(cube_faces[i][0]));
glDrawElements(GL_LINE, 4, GL_UNSIGNED_BYTE, &(cube_faces[i][0]));
}
glDisableClientState(GL_COLOR_ARRAY);
glColor4ub(0, 0, 0, 255);
for (i = 0; i < 6; i++) {
glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_BYTE, &(cube_faces[i][0]));
}
//glBlendFunc(GL_ONE, GL_ONE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glDepthMask(GL_TRUE);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_BLEND);
/*CreateFont的参数
cHeight 字体的逻辑高度
cWidth 字体的逻辑宽度
cEscapement 指定移位向量相对x轴的偏转角度
cOrientation 指定字符基线相对x轴的偏转角度
cWeight 设置字符粗细程度
bItalic 是否启用斜体
bUnderline 是否启用下划线
bStrikeOut 是否启用删除线
iCharset 指定字符集
iOutPrecision 输出精度
iClipPrecision 剪裁精度
iQuality 输出质量
iPitchAndFamily 字体族
pszFaceName 字体名
*/
HFONT hFont = CreateFont(0, 0, 0, 0, 100, 0, 0, 0, GB2312_CHARSET, 0, 0, 0, FF_MODERN, TEXT("宋体"));
/*根据字符串里面是否包含\n对字符串进行行分割并进行多行显示*/
char delims[] = "\n";
char *lineStr=NULL;
//将字符串常量转为字符串变量
char *dispContentStr = (char *)malloc(sizeof(char)*(strlen(disContent) + 1));
int yOffsetUnitCnt = 0;
float originY = 0.7f;
float actualY = originY;
float moveYdistance = 0.2f;
if (dispContentStr != NULL){
strcpy(dispContentStr, disContent);
lineStr = strtok(dispContentStr, delims); //strtok中的char *Str为非常量指针,而非常量指针可以隐式转换为常量指针,由于strtok会对指针指向值进行修改,
while (lineStr != NULL){ //所以当Str为常量指针时,编译时没有问题,但运行时会报错
actualY = originY - yOffsetUnitCnt*moveYdistance;
draw3dtextWithCloseLight(lineStr, hFont, 0.2f, -1.1f, actualY, 0.7f, 0.2f, 0.2f, 0.2f, 0.0f, 0.0f, 0.0f);
printf("result is \"%s\"\n", lineStr);
lineStr = strtok(NULL, delims);
yOffsetUnitCnt++;
}
}
else{
printf("mallocerror\n");
exit(-1);
}
free(dispContentStr);
dispContentStr = NULL;
/*
str 一行需要显示的字体
hFont 一种具有特殊性的逻辑字体,在后面可以被任何设备选择
cDepth 字体的深度
dXoffset,Yoffset,Zoffset 偏移原点位置
*/
//draw3dtextWithCloseLight(disContent, hFont, 0.0f, -0.5f, -0.5f, 0.6f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f);
//draw3dtextWithCloseLight(disContent, hFont, 0.0f, -0.5f, 0.0f, 0.6f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f);
//draw3dtextWithCloseLight(disContent, hFont, 0.0f, -0.5f, 0.5f, 0.6f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 0.0f);
glPopMatrix(); // Restore world coordinate system.
}
参考链接:
http://www.artoolworks.com/support/applications/marker/