VAPS XT入门系列15:Windows下Qt动态加载VAPS XT编译生成的DLL文件

系列索引:VAPS XT4.2.1入门系列索引

开发环境

软件版本
OSWindows 10 20H2
VS2013
Qt5.10.1
编译器MSVC2013_64bit for Qt 5.10.1
VAPS XT4.2.1

首先先准备一个VAPS XT编译生成的DLL文件,使用VAPS编译就可以了。

创建一个空白的QWidget项目。

在*.pro文件中添加:

1
2
3
4
5
6
7
8
9
10
INCLUDEPATH += C:/Presagis/VAPS_XT_4_2_1/src/ThirdParty/glut/3.7.6.3/include
DEPENDPATH += C:/Presagis/VAPS_XT_4_2_1/src/ThirdParty/glut/3.7.6.3/include

INCLUDEPATH += $$PWD/3part
DEPENDPATH += $$PWD/3part

unix|win32: LIBS += -L$$PWD/3part/ -lGlU32 -lOpenGL32 -lglmf32

win32:CONFIG(release, debug|release): LIBS += -LC:/Presagis/VAPS_XT_4_2_1/src/ThirdParty/glut/3.7.6.3/lib/ -lglut64
else:win32:CONFIG(debug, debug|release): LIBS += -LC:/Presagis/VAPS_XT_4_2_1/src/ThirdParty/glut/3.7.6.3/lib/ -lglut64

有的操作系统没有GLU32等等链接库,所以就直接加上。

在*.ui文件中添加QWidget窗口,至少一个用于显示效果。

这是我的界面:

ui

QOpenGLWidget类

在FFmpeg系列和OpenGL系列中有提及Qt+OpenGL的开发,本文简单介绍一下。

首先创建一个类,继承QOpenGLWidget和QOpenGLFunctions。

有三个必须实现的虚函数:

1
2
3
4
protected:
void initializeGL() override;
void paintGL() override;
void resizeGL(int width, int height) override;

initializeGL用于初始化,PaintGL用于实时绘图,resizeGL用于调整界面大小。三个函数由基类直接调用。

首先添加头文件:

1
2
3
4
#include "GL/gl.h"

#include "./include/vxtRTDrawingIntegrationI.h"
#include "c:\Presagis\VAPS_XT_4_2_1\src\Ports\OS\win32\include\vxtPLBasicTypes.h"

定义接口

1
typedef vxtRTDrawingIntegrationI* (*fCreateTopIntegrator)();

官方示例就是这样写的。

创建接口对象:

1
vxtRTDrawingIntegrationI*  m_pDrawingIntegration = NULL;

初始化

1
2
3
4
5
6
7
8
9
10
11
12
//初始化opengl窗口部件
void myopenGL::initializeGL()
{
initializeOpenGLFunctions();
glClearColor(0.0,0.0,0.0,1.0);
glShadeModel(GL_SMOOTH);

glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
}

就是常用的清空缓冲区、设置背景色等等。

绘图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//绘制opengl窗口
void myopenGL::paintGL()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

//绘制操作:
glMatrixMode ( GL_PROJECTION );
glLoadIdentity();
glOrtho ( 0, this->width(), 0, this->height(), -1, 1 );
glMatrixMode ( GL_MODELVIEW );
glLoadIdentity();

if (NULL != m_pDrawingIntegration){
m_pDrawingIntegration->vExecuteIteration();
}

glFlush();
update();
}

和普通的OpenGL程序一样,不过最重要的是调用接口通知VAPS XT DLL进行绘图。

调整大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//处理窗口大小
void myopenGL::resizeGL(int width, int height)
{
glMatrixMode ( GL_PROJECTION );
glLoadIdentity();
glOrtho ( 0, this->width(), 0, this->height(), -1, 1 );
glMatrixMode ( GL_MODELVIEW );
glLoadIdentity();

if (NULL != m_pDrawingIntegration){
m_pDrawingIntegration->vSetSize(0, width, height);
}

glViewport(0, 0, this->width(), this->height()); //重置模型观察矩阵
}

加载DLL

使用QLibrary来加载DLL,解析DLL的函数列表,设置调用参数,然后初始化接口。

代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void myopenGL::loadDll(QString fileName)
{
UnLoadDll();

lib=new QLibrary(fileName);
if(lib->load()){
fCreateTopIntegrator fun = (fCreateTopIntegrator)lib->resolve("vxtGetDrawingIntegrationI");
if(fun){
m_pDrawingIntegration = fun();
if(NULL != m_pDrawingIntegration){
const char *argv[4];
argv[0] = "VAPSXT.exe";
argv[1] = "-alwaysdraw";
argv[2] = "-fit";
argv[3] = "-displayupdaterate";

const int size = sizeof(argv) / sizeof(argv[0]);
if(VXT_TRUE == m_pDrawingIntegration->vInit(size, (char **)argv, VXT_FALSE)){
// The following line sets the VAPS XT drawing area to have the full extent of the MFC Window.
m_pDrawingIntegration->vSetSize(0, this->width(), this->height());
}else{
// The following line sets the VAPS XT drawing area to have the full extent of the MFC Window.
m_pDrawingIntegration->vSetSize(0, this->width(), this->height());
qDebug() << "Cannot initialize the vxtRTDrawingIntegrationI";
}
}else{
qDebug() << "m_pDrawingIntegration is NULL";
}
}else{
qDebug() << "Get fun Error";
}
}else{
qDebug() << "Load library Error";
}
}

说明一下argv参数。

VAPS参考文档中提供了以下几个参数:

  • [-width <wnd_width>]: 指定窗口的宽度(像素值)
  • [-height <wnd_height>]: 指定窗口的高度(像素值)
  • [-xpos <wnd_x_pos>]: 指定窗口的X位置(像素值)
  • [-ypos <wnd_y_pos>]: 指定窗口的Y位置(像素值)
  • [-noborder]: 移除窗口的黑色边框
  • [-center]: 将图像界面移至窗口中心位置
  • [-fit]: 将图像界面缩放并放置到适应窗口
  • [-bottomleftwindoworigin]: 设置屏幕的左下角作为窗口的起点
  • [-fulldraw]: (默认)当发生变化时才绘制整个框架(frame)
  • [-alwaysdraw]: 总是绘制整个框架(frame)即使没有什么东西发生变化
  • [-displaylist]: 使用显示列表(display list)优化
  • [-truetypefontpath]: 设置字体路径

VAPSXT有自动执行程序的脚本,脚本中也是使用这些参数。

取消加载

1
2
3
4
5
6
7
8
9
10
11
12
void myopenGL::UnLoadDll()
{
if(lib!=NULL){
if(VXT_NULL != m_pDrawingIntegration){
m_pDrawingIntegration->vClose();
m_pDrawingIntegration = VXT_NULL;

lib->unload();
lib = NULL;
}
}
}

调用接口关闭,重置指针。

测试

编译运行,运行效果

Windows+Linux下Qt动态加载VAPS XT动态链接库视频(与LINUX版使用的是同一份代码,所以就放在一起了)- B站

完整Qt代码在VAPS_XT中的dlload。测试用的DLL由官方示例编译而来。