目前测试只支持按流的方式读取的模型文件比如*.ive,*.fbx测试不可用,代码留给有需要的人。
#ifndef ReadFileCB_h__
#define ReadFileCB_h__
#include <osgDB/Registry>
#include <QObject>
class CReadFileCB : public QObject, public osgDB::Registry::ReadFileCallback
{
Q_OBJECT
public:
CReadFileCB();
virtual ~CReadFileCB(){}
void AttachFile(const std::string& strFilePath);
osgDB::ReaderWriter::ReadResult readNode(const std::string& filename, const osgDB::Options* options) override;
signals:
void SigStart();
void SigFinish();
void SigCurrentProgress(int nCur);
private:
void Start();
void Finish();
void SetCurrentProgress(int nCur);
private:
friend class CReadingThread;
std::string m_strFilePath;
};
#endif // ReadFileCB_h__
#include "ReadFileCB.h"
#include "ReadFileProgressBar.h"
#include "ReadingThread.h"
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
CReadFileCB::CReadFileCB()
{
}
void CReadFileCB::AttachFile(const std::string& strFilePath)
{
m_strFilePath = strFilePath;
}
osgDB::ReaderWriter::ReadResult CReadFileCB::readNode(const std::string& filename, const osgDB::Options* options)
{
if (m_strFilePath != filename)
{
return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
}
std::string dtrExt = osgDB::getLowerCaseFileExtension(filename);
osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForExtension(dtrExt);
if (NULL != rw)
{
return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED;
}
std::string strFileName = osgDB::findDataFile(filename, options);
if (strFileName.empty())
{
return osgDB::ReaderWriter::ReadResult::FILE_NOT_FOUND;
}
osgDB::ifstream fin(strFileName.c_str(), std::ios::in | std::ios::binary);
if (!fin.is_open())
{
return osgDB::ReaderWriter::ReadResult::ERROR_IN_READING_FILE;
}
CReadingThread crt(this, &fin);
crt.start();
bool bIsGood = fin.good();
if (bIsGood)
{
std::cout << "Using default format readerwriter" << std::endl;
osgDB::ReaderWriter::ReadResult rr = rw->readNode(fin);
QEventLoop loop;
connect(&crt, &CReadingThread::finished, &loop, &QEventLoop::quit);
loop.exec();
return rr;
}
else
{
return osgDB::ReaderWriter::ReadResult::ERROR_IN_READING_FILE;
}
}
void CReadFileCB::Start()
{
emit SigStart();
}
void CReadFileCB::Finish()
{
emit SigFinish();
}
void CReadFileCB::SetCurrentProgress(int nCur)
{
CReadFileProgressBar* p = CReadFileProgressBar::Instance();
if (NULL != p)
{
p->SetValue(nCur);
}
//emit SigCurrentProgress(nCur);
}
#ifndef ReadingThread_h__
#define ReadingThread_h__
#include <osgDB/fstream>
#include <QThread>
class CReadFileCB;
class CReadingThread : public QThread
{
public:
CReadingThread(CReadFileCB* pReadFileCB, osgDB::ifstream* fin);
virtual ~CReadingThread(){}
protected:
void run() override;
protected:
CReadFileCB* m_pReadFileCB;
osgDB::ifstream* m_pFin;
double m_dLength;
};
#endif // ReadingThread_h__
#include "ReadingThread.h"
#include "ReadFileCB.h"
CReadingThread::CReadingThread(CReadFileCB* pReadFileCB, osgDB::ifstream* fin)
: m_pReadFileCB(pReadFileCB)
, m_pFin(fin)
, m_dLength(0)
{
if (NULL != fin && fin->is_open())
{
fin->seekg(0, std::ifstream::end);
m_dLength = fin->tellg();
fin->seekg(0, std::ifstream::beg);
}
else
{
std::cerr << "Error: File not opened correctly." << std::endl;
}
}
void CReadingThread::run()
{
if (NULL == m_pFin || !m_pFin->is_open())
{
std::cerr << "Error: File stream is not open." << std::endl;
return;
}
m_pReadFileCB->Start();
double dPos = m_pFin->tellg();
while (dPos < m_dLength)
{
dPos = m_pFin->tellg();
if (dPos == -1)
{
dPos = m_dLength;
}
// 回调进度
if (NULL != m_pReadFileCB)
{
int nCur = static_cast<int>(dPos / m_dLength * 100);
m_pReadFileCB->SetCurrentProgress(nCur);
}
std::cout << 100.0 * dPos / m_dLength << "%" << std::endl;
}
m_pReadFileCB->Finish();
}
#ifndef ReadFileProgressBar_h__
#define ReadFileProgressBar_h__
#include <QDialog>
#include <QEventLoop>
class CReadFileCB;
QT_BEGIN_NAMESPACE
namespace Ui { class CReadFileProgressBarClass; };
QT_END_NAMESPACE
// 目前测试只支持可以以流的形式读入的模型文件
class CReadFileProgressBar : public QDialog
{
Q_OBJECT
private:
CReadFileProgressBar(QWidget *parent = nullptr);
~CReadFileProgressBar();
public:
static CReadFileProgressBar* Instance();
bool AttachFile(const std::string& strFilePath);
void Detach();
int Value();
int MaxValue();
//默认0-100
void SetRange(int nMin, int nMax);
void SetValue(int nValue);
void SetTitle(const QString& strTitle);
private slots:
void SlotShow();
void SlotClose();
void SlotSetCurrentValue(int nValue);
private:
Ui::CReadFileProgressBarClass *ui;
CReadFileCB* m_pReadFileCB;
};
#endif // ReadFileProgressBar_h__
#include "ReadFileProgressBar.h"
#include "ui_ReadFileProgressBar.h"
#include "ReadFileCB.h"
CReadFileProgressBar::CReadFileProgressBar(QWidget* parent)
: QDialog(parent)
, ui(new Ui::CReadFileProgressBarClass())
, m_pReadFileCB(new CReadFileCB)
{
ui->setupUi(this);
setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);//去掉标题栏
setStyleSheet("QProgressBar{"
" font:9pt;"
" border-radius:5px;"
" text-align:center;"
" border:1px solid #E8EDF2;"
" background-color: rgb(255, 255, 255);"
" border-color: rgb(180, 180, 180);"
"}"
"QProgressBar:chunk{"
" border-radius:5px;"
" background-color:#1aafea;"
"}");
SetRange(0, 100);
connect(m_pReadFileCB, &CReadFileCB::SigCurrentProgress, this, &CReadFileProgressBar::SlotSetCurrentValue);
connect(m_pReadFileCB, &CReadFileCB::SigStart, this, &CReadFileProgressBar::SlotShow);
connect(m_pReadFileCB, &CReadFileCB::SigFinish, this, &CReadFileProgressBar::SlotClose);
}
CReadFileProgressBar::~CReadFileProgressBar()
{
delete ui;
}
CReadFileProgressBar* CReadFileProgressBar::Instance()
{
static CReadFileProgressBar customProgressBar();
return &customProgressBar;
}
bool CReadFileProgressBar::AttachFile(const std::string& strFilePath)
{
if (NULL != m_pReadFileCB)
{
m_pReadFileCB->AttachFile(strFilePath);
SetTitle(QString(strFilePath.c_str()));
osgDB::Registry::instance()->setReadFileCallback(m_pReadFileCB);
return true;
}
std::cerr << "CReadFileProgressBar::AttachFile failed!";
return false;
}
void CReadFileProgressBar::Detach()
{
osgDB::Registry::instance()->setReadFileCallback(nullptr);
}
int CReadFileProgressBar::Value()
{
return ui->progressBar->value();
}
int CReadFileProgressBar::MaxValue()
{
return ui->progressBar->maximum();
}
void CReadFileProgressBar::SetRange(int nMin, int nMax)
{
ui->progressBar->setRange(nMin, nMax);
}
void CReadFileProgressBar::SetValue(int nValue)
{
ui->progressBar->setValue(nValue);
QApplication::processEvents();
}
void CReadFileProgressBar::SetTitle(const QString& strTitle)
{
ui->label->setText(strTitle);
}
void CReadFileProgressBar::SlotShow()
{
show();
}
void CReadFileProgressBar::SlotClose()
{
close();
}
void CReadFileProgressBar::SlotSetCurrentValue(int nValue)
{
SetValue(nValue);
}
读取模型文件部分代码参考了杨总的博客-第19节 实例-显示模型读取进度。