用优秀的UI库Qt试验下 ^_^,折腾了接近一天,才能画出来,但是动画不动。
截图:
现在的问题是只有“脏”了才画,也就是才去调用如下的method;不是三角形没动,是动了但是没画出来,我们看不见。
void QD3DWidget::paintEvent( QPaintEvent* )
{
if (updatesEnabled())
{
d3dDraw();
}
}
用个timer去解决这个问题?
这老外的帖子对我帮助很大,不搞下面的两条整个QD3DWidget都看不到:
Using Direct3D 9 with Qt - flicker problem
According to the Qt docs, if you want to use GDI or Direct3D on Windows with Qt, you need to:
1) Override
QWidget::paintEngine to return NULL
2) Call
QWidget::setAttribute(Qt::WA_PaintOnScreen, true)
部分代码:
HRESULT InitD3D( HWND hWnd )
{
// Create the D3D object.
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;
// Set up the structure used to create the D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
// Create the D3DDevice
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}
// Turn off culling, so we see the front and back of the triangle
// 关闭剔除,以便三角形的前后都能被我们看到
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
// Turn off D3D lighting, since we are providing our own vertex colors
// 关闭D3D光照,因为我们提供我们自己的顶点颜色
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
return S_OK;
}
QD3DWidget.h
#ifndef QD3DWIDGET_H
#define QD3DWIDGET_H
#include <QWidget>
class QD3DWidget : public QWidget
{
Q_OBJECT
public:
QD3DWidget(QWidget *parent = 0);
~QD3DWidget();
//QSize minimumSizeHint() const;
//QSize sizeHint() const;
QPaintEngine *paintEngine() const;
protected:
virtual void initializeD3D();
virtual void paintD3D();
void paintEvent(QPaintEvent*);
virtual void d3dInit();
virtual void d3dDraw();
bool initialized() const{ return m_bInit; }
private:
bool m_bInit;
};
#endif // QD3DWIDGET_H
QD3DWidget.cpp
#include "QD3DWidget.h"
#include "Matrices.h"
QD3DWidget::QD3DWidget(QWidget *parent)
: QWidget(parent)
, m_bInit(false)
{
resize(QSize(400, 300));
setAttribute(Qt::WA_PaintOnScreen, true);
}
QD3DWidget::~QD3DWidget()
{
}
void QD3DWidget::initializeD3D()
{
InitD3D(/*this->topLevelWidget()->*/winId());
InitGeometry();
m_bInit = true;
}
void QD3DWidget::paintD3D()
{
// lyl: 真正要画的东西放这儿
Render();
}
void QD3DWidget::paintEvent( QPaintEvent* )
{
if (updatesEnabled())
{
d3dDraw();
}
}
void QD3DWidget::d3dInit()
{
initializeD3D();
}
void QD3DWidget::d3dDraw()
{
if (!initialized())
{
d3dInit();
}
paintD3D();
}
//QSize QD3DWidget::minimumSizeHint() const
//{
// return QSize(50, 50);
//}
//
//QSize QD3DWidget::sizeHint() const
//{
// return QSize(200, 200);
//}
QPaintEngine * QD3DWidget::paintEngine() const
{
return NULL;
}
2008-11-26 PM 21:30 用个timer让动画显示出来了,每隔20ms就强制画一下,参考了Qt 的例子opengl/textures
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(rotateOneStep()));
timer->start(20);
2010-09-06 AM 2:55 【重剑注:时光匆匆,竟然已是快过去两年了!今日看了下Ogitor的代码,0.4.2版本看起来已是相当完善,电脑上有0.3的代码,随便看下其render loop】
Ogitor 0.3里面也是用的Timer的方式
MainWindow.cpp MainWindow的构造函数中
mTimer = new QTimer(this);
mTimer->setInterval(0);
connect(mTimer, SIGNAL(timeout()), this, SLOT(timerLoop()));
mTimer->start();
看timerLoop的代码,可知窗口不最小化时,setInterval为50.
void MainWindow::timerLoop()
{
if(mHasFileArgs)
{
if(mOgreWidget->mOgreInitialised)
{
OgitorsRoot::getSingletonPtr()->LoadScene(mArgsFile.toStdString());
mHasFileArgs = false;
mOgreWidget->setDoLoadFile(false);
}
}
if(isMinimized())
{
if(mTimer->interval() != 200)
mTimer->setInterval(200);
return;
}
else
{
if(mTimer->interval() != 50)
mTimer->setInterval(50);
}
updateActions();
if(OgitorsRoot::getSingletonPtr()->IsSceneLoaded())
{
mOgreWidget->ProcessKeyActions();
}
LogDataVector messages;
LOGBUFFER.getBuffer(messages);
for(unsigned int i = 0;i < messages.size();i++)
{
updateLog(new QListWidgetItem(messages[i].mMessage, 0, messages[i].mLevel) );
}
if(messages.size() > 0)
logWidget->scrollToBottom();
}
不过这个timerLoop里面没有渲染的代码啊!改天再看了!睡觉!
ogrewidget.hxx
public Q_SLOTS:
void timerLoop();
ogrewidget.cpp
void OgreWidget::timerLoop()
{
if(mOgitorMainWindow->isMinimized())
return;
if(mRenderStop)
{
if(QMessageBox::information(this,"qtOgitor", tr("Render Device is Lost! Please click ok to continue.."), QMessageBox::Ok) == QMessageBox::Ok)
mRenderStop = false;
}
update();
}