基于Qt的osg读取模型进度回调

16 篇文章 0 订阅
1 篇文章 0 订阅

目前测试只支持按流的方式读取的模型文件比如*.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节 实例-显示模型读取进度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值