原理:就是用openVR驱动各种类型的VR眼镜驱动,然后不断给指定软件截图用opengl渲染到VR眼镜
这个代码的功能了就是后天运行,创建udp广播,收到“close”命令就启动VR渲染,“start”就是关闭渲染
mian.cpp
#include "mainwindow.h" #include <QApplication> #include <QSurfaceFormat> #include <QSettings> #include<QProcess> #include<QMessageBox> #include<QMutex> #include<QDateTime> #include<QTextStream> #include<QFile> #include<QDir> static bool FindDog(){ QProcess proc; proc.start("tasklist -fi \"imagename eq QVRViewer.exe\""); proc.waitForFinished(); QString tmp; tmp = tmp.prepend(proc.readAll()); if(tmp.contains("Console")){ int step = tmp.indexOf("Console"); tmp = tmp.mid(step + 10); if(tmp.contains("Console")) return true; } return false; } void MessageOutPut(QtMsgType type, const QMessageLogContext &context, const QString &msg) { static QMutex mutex; mutex.lock(); QString text; switch(type) { case QtDebugMsg: text = QString("Debug:"); break; case QtWarningMsg: text = QString("Warning:"); break; case QtCriticalMsg: text = QString("Critical:"); break; case QtFatalMsg: text = QString("Fatal:"); break; default: break; } QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); QString message = QString("%1 %2%3").arg(current_date_time).arg(text).arg(msg); QFile file("log.txt"); file.open(QIODevice::WriteOnly | QIODevice::Append); QTextStream text_stream(&file); text_stream << message << "\r\n"; file.flush(); file.close(); mutex.unlock(); } int main(int argc, char *argv[]) { QCoreApplication::setOrganizationName("Skeletonbrain"); QCoreApplication::setOrganizationDomain("skeletonbrain.com"); QCoreApplication::setApplicationName("QVRViewer"); QSurfaceFormat glFormat; glFormat.setVersion(4, 1); glFormat.setProfile(QSurfaceFormat::CoreProfile); // glFormat.setSamples(0); glFormat.setSwapInterval(0); glFormat.setOption(QSurfaceFormat::DebugContext); QSurfaceFormat::setDefaultFormat(glFormat); QApplication a(argc, argv); qInstallMessageHandler(MessageOutPut);//安装日志 if(FindDog()){ QMessageBox box; box.setText("该程序已运行!"); box.exec(); return 0; } MainWindow w; w.show(); w.move(-200,-200); return a.exec(); }
MainWindow.h#ifndef MAINWINDOW_H #define MAINWINDOW_H #include<QSystemTrayIcon> #include <QMainWindow> #include<QMenu> #include<QAction> #include<QTimer> #include <QUdpSocket> namespace Ui { class MainWindow; } class VRView; class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void HandleClose(); void FindWindownHwnd(); void readPendingDatagrams(); private: Ui::MainWindow *ui; VRView *vr; QSystemTrayIcon *m_trayIcon; QMenu *mMenu; QAction *exitAction; QTimer * tim; QUdpSocket *udpSocket; QString AppName; int Rport; void initSocket(); void ReadConfig(); };
mainwindow.cpp#include "mainwindow.h" #include "ui_mainwindow.h" #include "vrview.h" #include"WinWnd.h" #include <QVBoxLayout> #include <QSurfaceFormat> #include <QSettings> #include <QFileDialog> #include <QStandardPaths> #include <QOffscreenSurface> #include<QSettings> #include<QMessageBox> #include<QDebug> #include<QWindow> #include<QDesktopWidget> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); this->setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::ToolTip); m_trayIcon = new QSystemTrayIcon(this); m_trayIcon->setIcon(QIcon(":/viewer.ico")); //设置图标 mMenu = new QMenu(this); exitAction = new QAction(QStringLiteral("Exit"),this); mMenu->addAction(exitAction); m_trayIcon->setContextMenu(mMenu); connect(exitAction,SIGNAL(triggered(bool)),this,SLOT(HandleClose())); m_trayIcon->show(); m_trayIcon->showMessage("tip","QVRViewer has started",QSystemTrayIcon::Information,1000); ReadConfig(); vr = NULL; tim = new QTimer(this); tim->setInterval(100); connect(tim,SIGNAL(timeout()),this,SLOT(FindWindownHwnd())); initSocket(); tim->start(); } MainWindow::~MainWindow() { if(tim->isActive()) tim->stop(); if(vr != NULL) delete vr; delete ui; } void MainWindow::HandleClose() { QApplication::quit(); } void MainWindow::FindWindownHwnd() { int hwnd = GetWndFromPid(AppName.toLatin1().data()); if(hwnd == 0) return; // qDebug()<<"find Window:"<<hwnd; if(vr == NULL){ if(abs(QWindow::fromWinId(hwnd)->width() - QApplication::desktop()->width()) < 100){ tim->stop(); qDebug()<<"start vr"<<hwnd; vr = new VRView(hwnd,this); this->setCentralWidget(vr); } } } void MainWindow::readPendingDatagrams() { if (udpSocket->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(udpSocket->pendingDatagramSize()); udpSocket->readDatagram(datagram.data(), datagram.size(), NULL,NULL); QString cmd = QString::fromLatin1(datagram); qDebug()<<cmd; if(cmd == "close"){ tim->start(); }else if(cmd == "start"){ if(tim->isActive()) tim->stop(); if(vr != NULL){ delete vr; vr = NULL; } }else{ QMessageBox box; box.setText("命令错误:"+cmd); box.exec(); } } } void MainWindow::initSocket() { udpSocket = new QUdpSocket(this); udpSocket->bind(QHostAddress::Any, Rport); connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); } void MainWindow::ReadConfig() { // QSettings settings("C:\\Users\\9DVR\\Desktop\\QVR\\config\\cutApp.ini",QSettings::IniFormat); QSettings settings("./config/cutApp.ini",QSettings::IniFormat); settings.beginGroup("cutApp"); AppName = settings.value("appName").toString(); Rport = settings.value("port").toInt(); settings.endGroup(); if(AppName.isEmpty() || Rport == 0){ QMessageBox box; box.setText("配置文件格式错误"); box.exec(); this->close(); } }
完整代码下载地址:http://download.csdn.net/download/xzpblog/10039362