每天30分钟写Editor--(1)在Qt窗口里用D3D画转动的三角形
用优秀的UI库Qt试验下 ^_^,折腾了接近一天,才能画出来,但是动画不动。
截图:
现在的问题是只有“脏”了才画,也就是才去调用如下的method;不是三角形没动,是动了但是没画出来,我们看不见。
void
QD3DWidget::paintEvent( QPaintEvent
*
)
{
if (updatesEnabled())
{
d3dDraw();
}
}
{
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;
}
{
// 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
#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;
}
#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 );
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.
mTimer -> setInterval( 0 );
connect(mTimer, SIGNAL(timeout()), this , SLOT(timerLoop()));
mTimer -> start();
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();
}
{
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 timerLoop();
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();
}
{
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();
}