D3DX: ID3DXEffect::BeginPass: Must be called between ID3DXEffect::Begin and ID3DXEffect::End
D3DX: ID3DXEffect::EndPass: EndPass called while not in a pass
D3DX: ID3DXEffect::End: Cannot be called without a preceding call to ID3DXEffect::Begin
Direct3D9: (ERROR) :All user created stateblocks must be freed before ResetEx can succeed. ResetEx Fails.
Direct3D9: (ERROR) :ResetEx failed and ResetEx/TestCooperativeLevel/Release are the only legal APIs to be called subsequently
Direct3D9: (INFO) :DDI threading stopped
Direct3D9: (ERROR) :Device is in an invalid state. Only Reset, TestCooperativeLevel, CheckDeviceState or Release could be called
#pragma once
#include "Camera\camera.h"
#include "SkinnedMesh\SkinnedMesh.h"
#include "common.h"
#include <QWidget.h>
#include <QtGui/QResizeEvent>
#include <QtGui/QMainWindow.h>
#include <QtGui/QStatusBar.h>
#include <QtGui/QVector2D.h>
#include <QtGui/QVector3D.h>
#include <QtGui/QVector4D.h>
#include <d3dx9.h>
extern IDirect3DDevice9 *g_pDevice;
extern ID3DXEffect *g_pEffect;
class DXWidget : public QWidget
{
public:
DXWidget( QWidget *parent = 0, Qt::WFlags flags = 0 ) : QWidget( parent, flags )
{
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_NoSystemBackground);
m_standBy = false;
m_lastRendered = 0;
m_fTime = 0;
m_iCurCam = 0;
}
~DXWidget(void) { }
virtual void setVisible(bool visible)
{
if(visible)
{
QWidget::setVisible(visible);
//initialize();
}
else
{
//uninitialize();
QWidget::setVisible(visible);
}
}
virtual HRESULT initialize() = 0;
virtual void uninitialize() = 0;
virtual HRESULT restoreDeviceObjects() = 0;
virtual HRESULT invalidateDeviceObjects() = 0;
virtual void setTime(double fTime)
{
m_fTime = fTime;
}
virtual HRESULT render()
{
return S_OK;
}
virtual HRESULT present()
{
return S_OK;
}
virtual void initCamera()
{
/*
perspective( 45.0f, width() / (float)height(), 0.1f, 5000.0f );
lookAtCamera( vmVector3( 3.857, 2.5, -3.857 ), vmVector3( 0, 0, 0 ), vmVector3( 0, 1, 0 ) );
*/
}
virtual void initModels()
{
}
virtual void initEffects()
{
}
virtual void update()
{
}
void setAspect(float aspect)
{
/*
m_camera->setAspect(aspect);
*/
}
void perspective(float fovx, float aspect, float znear, float zfar)
{
/*
m_camera->perspective(fovx, aspect, znear, zfar);
emit setAngleOfView((double)fovx);
emit setNearClipPlane((double)znear);
emit setFarClipPlane((double)zfar);
*/
}
void moveCamera(float dx, float dy, float dz)
{
/*
m_camera->move(dx, dy, dz);
vmVector3 target = m_camera->getTarget();
emit setCameraTranslate(QVector3D(target[0], target[1], target[2]));
*/
}
void rotateCamera(float headingDegrees, float pitchDegrees, float rollDegrees)
{
/*
m_camera->rotate(headingDegrees, pitchDegrees, rollDegrees);
vmVector3 euler;
if(m_camera->getEulerAngle(euler))
{
emit setCameraRotate(QVector3D(btDegrees(euler[0]), btDegrees(euler[1]), btDegrees(euler[2])));
}
*/
}
void zoomCamera(float zoom)
{
/*
m_camera->zoom(zoom);
emit setCenterOfInterest((double)m_camera->getCenterOfInterest());
*/
}
void lookAtCamera(const D3DXVECTOR3 &eye, const D3DXVECTOR3 &target, const D3DXVECTOR3 &up)
{
/*
m_camera->lookAt(eye, target, up);
emit setCameraTranslate(QVector3D(target[0], target[1], target[2]));
emit setCenterOfInterest((double)m_camera->getCenterOfInterest());
vmVector3 euler;
if(m_camera->getEulerAngle(euler))
{
emit setCameraRotate(QVector3D(btDegrees(euler[0]), btDegrees(euler[1]), btDegrees(euler[2])));
}
emit setCameraScale(QVector3D(1, 1, 1));
*/
}
signals:
void setCameraTranslate(QVector3D);
void setCameraRotate(QVector3D);
void setCameraScale(QVector3D);
void setCenterOfInterest(double);
void setAngleOfView(double);
void setNearClipPlane(double);
void setFarClipPlane(double);
public slots:
void cameraTranslateChanged(QVector3D p)
{
//m_camera->setTarget(vmVector3(p.x(), p.y(), p.z()));
update();
}
void cameraRotateChanged(QVector3D p)
{
//m_camera->setEulerAngle(vmVector3(btRadians(p.x()), btRadians(p.y()), btRadians(p.z())));
update();
}
void cameraScaleChanged(QVector3D p)
{
}
void angleOfViewChanged(double value)
{
//m_camera->setFovx(value);
update();
}
void nearClipPlaneChanged(double value)
{
//m_camera->setZnear(value);
update();
}
void farClipPlaneChanged(double value)
{
//m_camera->setZfar(value);
update();
}
void centerOfInterestChanged(double value)
{
//m_camera->setCenterOfInterest(value);
update();
}
protected:
QPaintEngine *paintEngine() const { return 0; }
virtual void onResize(UINT, UINT) = 0;
virtual void paintEvent(QPaintEvent *e)
{
Q_UNUSED(e);
update();
render();
}
virtual void resizeEvent(QResizeEvent *p_event)
{
QSize newSize = size();
if(p_event)
{
newSize = p_event->size();
// if( width()==newSize.width() && height()==newSize.height() ) return;
QWidget::resizeEvent( p_event );
}
onResize(newSize.width(), newSize.height());
}
void keyPressEvent(QKeyEvent *e)
{
switch (e->key()) {
//case Qt::Key_Escape:
break;
default:
QWidget::keyPressEvent(e);
}
}
const D3DXMATRIX& ViewMatrix()
{
return m_camera[m_iCurCam].GetViewMatrix();
}
const D3DXMATRIX& ProjMatrix()
{
return m_camera[m_iCurCam].GetProjMatrix();
}
static bool isCameraOperation(QMouseEvent *e)
{
return true/*e->modifiers() == Qt::AltModifier*/;
}
void showStatus(const QString &message)
{
qobject_cast<QMainWindow*>(parent())->statusBar()->showMessage(message);
}
void mousePressEvent(QMouseEvent *e)
{
/*
m_clickPos = e->posF();
if(isCameraOperation(e))
{
m_camera->backup();
if((e->buttons() & Qt::LeftButton) && !(e->buttons() & Qt::RightButton))
{
// Shift to constrain rotaion
showStatus(tr("Tumble Tool: LMB Drag: Use LMB or MMB to tumble"));
setCursor(Qt::OpenHandCursor);
}
else if((e->buttons() & Qt::RightButton) && !(e->buttons() & Qt::LeftButton))
{
showStatus(tr("Dolly Tool: RMB Drag: Use mouse to dolly"));
setCursor(Qt::SizeVerCursor);
}
else if(e->buttons() & Qt::MiddleButton)
{
showStatus(tr("Track Tool: MMB Drag: Use LMB or MMB to track"));
setCursor(Qt::SizeAllCursor);
}
}
*/
QWidget::mousePressEvent(e);
}
void mouseMoveEvent(QMouseEvent *e)
{
/*
if(isCameraOperation(e) && height()>0)
{
if((e->buttons() & Qt::LeftButton) && !(e->buttons() & Qt::RightButton))
{
QPointF delta = (e->posF() - m_clickPos) / (float)height() * 180.0f;
m_camera->recover();
rotateCamera( delta.x(), delta.y(), 0.0f );
update();
}
else if((e->buttons() & Qt::RightButton) && !(e->buttons() & Qt::LeftButton))
{
QPointF delta = (e->posF() - m_clickPos) / (float)height() * m_camera->getCenterOfInterest();
m_camera->recover();
moveCamera( 0, 0, delta.y() );
update();
}
else if(e->buttons() & Qt::MiddleButton)
{
QPointF delta = (e->posF() - m_clickPos) / (float)height() * m_camera->getCenterOfInterest();
m_camera->recover();
moveCamera( -delta.x(), delta.y(), 0.0f );
update();
}
}
*/
update(); // Jacky
QWidget::mouseMoveEvent(e);
}
void mouseReleaseEvent(QMouseEvent *e)
{
setCursor(Qt::ArrowCursor);
showStatus("");
QWidget::mouseReleaseEvent(e);
}
void wheelEvent(QWheelEvent *e)
{
QWidget::wheelEvent(e);
// zoomCamera(1.0f - (e->delta() / WHEEL_DELTA) * 0.125f);
update();
}
Camera m_camera[NO_CAMS];
//! if stand-by mode
bool m_standBy;
// indicate the device has been lost
bool m_bDeviceLost;
//! Last updated time
double m_lastRendered;
//! Clicked mouse position
QPointF m_clickPos;
//! Time
double m_fTime;
int m_iCurCam;
};
#pragma once
#include "dxwidget.h"
class myDX9Widget :
public DXWidget
{
public:
#ifdef QWIDGET_H
myDX9Widget( QWidget *parent = 0, Qt::WFlags flags = 0 )
: DXWidget( parent, flags ), m_pD3D(0)
{
}
#else
myDX9Widget()
: m_pD3D(0), g_pDevice(0)
{
}
#endif
virtual ~myDX9Widget()
{
delete mOperatorMesh;
uninitialize();
}
virtual void initCamera()
{
m_camera[0].Load("Data\\Others\\Demo1.cam");
m_camera[1].Load("Data\\Others\\Demo2.cam");
m_camera[2].Load("Data\\Others\\Demo3.cam");
}
virtual void initModels()
{
mOperatorMesh = new SkinnedMesh();
mOperatorMesh->Load(L"Data/DemoWarehouse.x");
}
virtual void initEffects()
{
//Load Effect
ID3DXBuffer *pErrorMsgs = NULL;
HRESULT hRes = D3DXCreateEffectFromFile(g_pDevice, L"resources/fx/lighting.fx", NULL, NULL, D3DXSHADER_DEBUG, NULL, &g_pEffect, &pErrorMsgs);
if(FAILED(hRes) && (pErrorMsgs != NULL)) //Failed to create Effect
{
MessageBox(NULL, L"Effect Compilation Error", L"Error", NULL);
pErrorMsgs->Release();
PostQuitMessage(0);
}
pErrorMsgs->Release();
}
//-----------------------------------------------------------------------------
// Name: initialize()
// Desc: This function will only be called once during the application's
// initialization phase. Therefore, it can't contain any resources that
// need to be restored every time the Direct3D device is lost or the
// window is resized.
//-----------------------------------------------------------------------------
HRESULT initialize()
{
HRESULT hr = S_OK;
m_pD3D = 0;
g_pDevice = 0;
/* m_pVB = NULL;
m_pIB = NULL;
m_pVertexShader = NULL;
m_pConstantTable = NULL;
m_pVertexDeclaration = NULL;*/
m_pD3D = Direct3DCreate9(D3D_SDK_VERSION); //Standard
D3DCAPS9 Caps;
m_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &Caps );
DWORD BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
// If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW
// then switch to SWVP.
if( ( Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) == 0 ||
Caps.VertexShaderVersion < D3DVS_VERSION( 2, 0 ) )
{
BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}
ZeroMemory( &m_d3dpp, sizeof(m_d3dpp) );
m_d3dpp.Windowed = TRUE;
m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
m_d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
m_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
m_d3dpp.MultiSampleQuality = 0;
m_d3dpp.EnableAutoDepthStencil = TRUE;
m_d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
for( int m=0; m<=(int)D3DMULTISAMPLE_4_SAMPLES; m+=2 )
{
DWORD QualityBackBuffer = 0;
hr = m_pD3D->CheckDeviceMultiSampleType( D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
m_d3dpp.BackBufferFormat,
m_d3dpp.Windowed,
(D3DMULTISAMPLE_TYPE)m,
&QualityBackBuffer );
if( FAILED(hr) ) break;
if( QualityBackBuffer>0 )
{
m_d3dpp.MultiSampleType = (D3DMULTISAMPLE_TYPE)m;
m_d3dpp.MultiSampleQuality = QualityBackBuffer-1;
}
}
// Hardware Device
hr = m_pD3D->CreateDevice(
D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, winId(),
BehaviorFlags, &m_d3dpp, &g_pDevice );
if( FAILED(hr) )
{
m_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
m_d3dpp.MultiSampleQuality = 0;
// Reference Rasterizer
hr = m_pD3D->CreateDevice(
D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, winId(),
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &m_d3dpp, &g_pDevice );
}
if (SUCCEEDED(hr))
{
hr = restoreDeviceObjects();
}
initCamera();
initModels();
initEffects();
return hr;
}
//-----------------------------------------------------------------------------
// Name: uninitialize()
// Desc: Releases all previously initialized objects
//-----------------------------------------------------------------------------
void uninitialize()
{
invalidateDeviceObjects();
SAFE_RELEASE(g_pDevice);
SAFE_RELEASE(m_pD3D);
SAFE_RELEASE(g_pEffect);
}
virtual void update()
{
m_camera[m_iCurCam].Update(m_fTime);
D3DXMATRIX matIden;
D3DXMatrixIdentity(&matIden);
g_pDevice->SetTransform(D3DTS_WORLD, &matIden);
}
//-----------------------------------------------------------------------------
// Name: restoreDeviceObjects()
// Desc: You are encouraged to develop applications with a single code path to
// respond to device loss. This code path is likely to be similar, if not
// identical, to the code path taken to initialize the device at startup.
//-----------------------------------------------------------------------------
HRESULT restoreDeviceObjects()
{
if( !g_pDevice ) return E_FAIL;
HRESULT hr = S_OK;
/*
DWORD VERTS_PER_EDGE = 64;
DWORD dwNumVertices = VERTS_PER_EDGE * VERTS_PER_EDGE;
DWORD dwNumIndices = 6 * ( VERTS_PER_EDGE - 1 ) * ( VERTS_PER_EDGE - 1 );
// Create and initialize index buffer
WORD* pIndices;
V_RETURN( g_pDevice->CreateIndexBuffer( dwNumIndices * sizeof( WORD ),
0, D3DFMT_INDEX16,
D3DPOOL_DEFAULT, &m_pIB, NULL ) );
V_RETURN( m_pIB->Lock( 0, 0, ( void** )&pIndices, 0 ) );
DWORD y;
for( y = 1; y < VERTS_PER_EDGE; y++ )
{
for( DWORD x = 1; x < VERTS_PER_EDGE; x++ )
{
*pIndices++ = ( WORD )( ( y - 1 ) * VERTS_PER_EDGE + ( x - 1 ) );
*pIndices++ = ( WORD )( ( y - 0 ) * VERTS_PER_EDGE + ( x - 1 ) );
*pIndices++ = ( WORD )( ( y - 1 ) * VERTS_PER_EDGE + ( x - 0 ) );
*pIndices++ = ( WORD )( ( y - 1 ) * VERTS_PER_EDGE + ( x - 0 ) );
*pIndices++ = ( WORD )( ( y - 0 ) * VERTS_PER_EDGE + ( x - 1 ) );
*pIndices++ = ( WORD )( ( y - 0 ) * VERTS_PER_EDGE + ( x - 0 ) );
}
}
V_RETURN( m_pIB->Unlock() );
// Create and initialize vertex buffer
V_RETURN( g_pDevice->CreateVertexBuffer( dwNumVertices * sizeof( D3DXVECTOR2 ), 0, 0,
D3DPOOL_DEFAULT, &m_pVB, NULL ) );
D3DXVECTOR2* pVertices;
V_RETURN( m_pVB->Lock( 0, 0, ( void** )&pVertices, 0 ) );
for( y = 0; y < VERTS_PER_EDGE; y++ )
{
for( DWORD x = 0; x < VERTS_PER_EDGE; x++ )
{
*pVertices++ = D3DXVECTOR2( ( ( float )x / ( float )( VERTS_PER_EDGE - 1 ) - 0.5f ) * D3DX_PI,
( ( float )y / ( float )( VERTS_PER_EDGE - 1 ) - 0.5f ) * D3DX_PI );
}
}
V_RETURN( hr = m_pVB->Unlock() );
LPD3DXBUFFER pCode;
D3DVERTEXELEMENT9 decl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
D3DDECL_END()
};
V_RETURN( g_pDevice->CreateVertexDeclaration( decl, &m_pVertexDeclaration ) );
DWORD dwShaderFlags = 0;
#ifdef DEBUG_VS
dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
#endif
#ifdef DEBUG_PS
dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
#endif
V_RETURN( D3DXCompileShaderFromFileW( L"HLSLwithoutFX.vsh", NULL, NULL, "Ripple",
"vs_2_0", dwShaderFlags, &pCode,
NULL, &m_pConstantTable ) );
hr = g_pDevice->CreateVertexShader( ( DWORD* )pCode->GetBufferPointer(), &m_pVertexShader );
pCode->Release();
if( FAILED( hr ) )
return hr;
*/
/* g_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
g_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
g_pDevice->SetRenderState( D3DRS_MULTISAMPLEANTIALIAS, TRUE );*/
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: invalidateDeviceObjects()
// Desc: If the lost device can be restored, the application prepares the
// device by destroying all video-memory resources and any
// swap chains. This is typically accomplished by using the SAFE_RELEASE
// macro.
//-----------------------------------------------------------------------------
HRESULT invalidateDeviceObjects()
{
if( !g_pDevice ) return E_FAIL;
/*SAFE_RELEASE( m_pVertexShader );
SAFE_RELEASE( m_pConstantTable );
SAFE_RELEASE( m_pVertexDeclaration );
SAFE_RELEASE( m_pIB );
SAFE_RELEASE( m_pVB );*/
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
virtual HRESULT render()
{
if( !g_pDevice ) return E_FAIL;
HRESULT hr = S_OK;
clearScene( D3DXCOLOR( 0.0f, 0.25f, 0.25f, 0.55f ), 1.0f, 0 );
D3DXMATRIX matIden;
D3DXMatrixIdentity(&matIden);
if( SUCCEEDED(beginScene()) )
{
D3DXMATRIXA16 mWorldViewProj = D3DXMATRIXA16((float*)&ViewMatrix()) * D3DXMATRIXA16((float*)&ProjMatrix());
// DX10 spec only guarantees Sincos function from -100 * Pi to 100 * Pi
float fBoundedTime = (float) m_fTime - (floor( (float) m_fTime / (2.0f * D3DX_PI)) * 2.0f * D3DX_PI);
//m_pConstantTable->SetMatrix( g_pDevice, "mWorldViewProj", &mWorldViewProj );
//m_pConstantTable->SetFloat( g_pDevice, "fTime", fBoundedTime );
g_pEffect->SetMatrix("matVP", &mWorldViewProj);
g_pEffect->SetVector("lightPos", &D3DXVECTOR4(0.0f, -1.0f, 0.0f, 0.0f));
//g_pEffect->SetFloat("fTime", fBoundedTime);
mOperatorMesh->Draw(matIden);
endScene();
}
hr = present();
m_lastRendered = m_fTime;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: clearScene()
// Desc: Clear the render target and depth stencil
//-----------------------------------------------------------------------------
void clearScene( D3DXCOLOR ClearColor, float Z, DWORD Stencil )
{
g_pDevice->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, (DWORD)ClearColor, Z, Stencil );
}
//-----------------------------------------------------------------------------
// Name: clearRenderTarget()
// Desc: Clear the render target
//-----------------------------------------------------------------------------
void clearRenderTarget( D3DXCOLOR ClearColor )
{
g_pDevice->Clear( 0, 0, D3DCLEAR_TARGET,(DWORD)ClearColor, 1.0f, 0 );
}
//-----------------------------------------------------------------------------
// Name: clearScene()
// Desc: Clear the render target
//-----------------------------------------------------------------------------
void clearDepthStencil( float Z, DWORD Stencil )
{
g_pDevice->Clear( 0, 0, D3DCLEAR_TARGET, 0, Z, Stencil );
}
//-----------------------------------------------------------------------------
// Name: beginScene()
// Desc: Begin the scene
//-----------------------------------------------------------------------------
HRESULT beginScene()
{
return g_pDevice->BeginScene();
}
//-----------------------------------------------------------------------------
// Name: endScene()
// Desc: End the scene
//-----------------------------------------------------------------------------
HRESULT endScene()
{
return g_pDevice->EndScene();
}
//-----------------------------------------------------------------------------
// Name: present()
// Desc: Present the backbuffer contents to the display
//-----------------------------------------------------------------------------
HRESULT present()
{
HRESULT hr;
hr = g_pDevice->Present( 0, 0, 0, 0 );
// The following code refer to "Direct3D (DirectX 9.0) Code Samples Page6: Lost Device Recovery".
// URL: http://www.codesampler.com/dx9src.htm
//
// If Present fails with D3DERR_DEVICELOST the application needs to be
// notified so it cleanup resources and reset the device.
//
if( D3DERR_DEVICELOST == hr )
{
// Yield some CPU time to other processes
Sleep( 100 ); // 100 milliseconds
//
// Test the cooperative level to see if it's okay to render.
// The application can determine what to do on encountering a lost
// device by querying the return value of the TestCooperativeLevel
// method.
//
if( FAILED( hr = g_pDevice->TestCooperativeLevel() ) )
{
// The device has been lost but cannot be reset at this time.
// Therefore, rendering is not possible and we'll have to return
// and try again at a later time.
if( hr == D3DERR_DEVICELOST )
{
if (m_bDeviceLost == false)
{
try
{
g_pEffect->OnLostDevice();
m_bDeviceLost = true;
}
catch(...)
{
MessageBox(NULL, L"Error occured in Application::DeviceLost()", L"Error", NULL);
}
}
return hr;
}
// The device has been lost but it can be reset at this time.
if( hr == D3DERR_DEVICENOTRESET )
{
if (m_bDeviceLost == true)
{
try
{
//
// If the device can be restored, the application prepares the
// device by destroying all video-memory resources and any
// swap chains.
//
invalidateDeviceObjects();
//
// Then, the application calls the Reset method.
//
// Reset is the only method that has an effect when a device
// is lost, and is the only method by which an application can
// change the device from a lost to an operational state.
// Reset will fail unless the application releases all
// resources that are allocated in D3DPOOL_DEFAULT, including
// those created by the IDirect3DDevice9::CreateRenderTarget
// and IDirect3DDevice9::CreateDepthStencilSurface methods.
//
hr = g_pDevice->Reset( &m_d3dpp );
if( FAILED( hr ) )
return hr;
hr = g_pEffect->OnResetDevice();
if (FAILED( hr))
return hr;
//
// Finally, a lost device must re-create resources (including
// video memory resources) after it has been reset.
//
restoreDeviceObjects();
m_bDeviceLost = false;
}
catch (...)
{
MessageBox(NULL, L"Error occured in Application::DeviceGained()", L"Error", NULL);
}
}
}
}
}
return hr;
}
virtual void paintEvent(QPaintEvent *e)
{
Q_UNUSED(e);
render();
}
void onResize( UINT nWidth, UINT nHeight )
{
HRESULT hr = S_OK;
if( !g_pDevice ) return;
m_d3dpp.BackBufferWidth = nWidth;
m_d3dpp.BackBufferHeight = nHeight;
invalidateDeviceObjects();
hr = g_pDevice->Reset(&m_d3dpp);
restoreDeviceObjects();
// Camera ---------------------------------------------------
setAspect( width() / (float)height() );
render();
}
private:
//! Used to create the D3DDevice
IDirect3D9* m_pD3D;
//! Our rendering device
//IDirect3DDevice9* m_pDevice;
//! D3D Device Parameterss
D3DPRESENT_PARAMETERS m_d3dpp;
/*LPDIRECT3DVERTEXBUFFER9 m_pVB;
LPDIRECT3DINDEXBUFFER9 m_pIB;
LPDIRECT3DVERTEXSHADER9 m_pVertexShader;
LPD3DXCONSTANTTABLE m_pConstantTable;
LPDIRECT3DVERTEXDECLARATION9 m_pVertexDeclaration;*/
SkinnedMesh *mOperatorMesh;
};
void SkinnedMesh::UpdateMatrices(Bone* bone, D3DXMATRIX *parentMatrix)
{
if(bone == NULL)return;
D3DXMatrixMultiply(&bone->CombinedTransformationMatrix,
&bone->TransformationMatrix,
parentMatrix);
if(bone->pFrameSibling)UpdateMatrices((Bone*)bone->pFrameSibling, parentMatrix);
if(bone->pFrameFirstChild)UpdateMatrices((Bone*)bone->pFrameFirstChild, &bone->CombinedTransformationMatrix);
}
void SkinnedMesh::Render(Bone *bone)
{
if(bone == NULL)bone = (Bone*)m_pRootBone;
//If there is a mesh to render...
if(bone->pMeshContainer != NULL)
{
BoneMesh *boneMesh = (BoneMesh*)bone->pMeshContainer;
if (boneMesh->pSkinInfo != NULL)
{
// set up bone transforms
int numBones = boneMesh->pSkinInfo->GetNumBones();
for(int i=0;i < numBones;i++)
{
D3DXMatrixMultiply(&boneMesh->currentBoneMatrices[i],
&boneMesh->boneOffsetMatrices[i],
boneMesh->boneMatrixPtrs[i]);
}
D3DXMATRIX view, proj, identity;
g_pEffect->SetMatrixArray("FinalTransforms", boneMesh->currentBoneMatrices, boneMesh->pSkinInfo->GetNumBones());
D3DXMatrixIdentity(&identity);
//Render the mesh
for(int i=0;i < (int)boneMesh->NumAttributeGroups;i++)
{
int mtrlIndex = boneMesh->attributeTable[i].AttribId;
g_pDevice->SetMaterial(&(boneMesh->materials[mtrlIndex]));
g_pDevice->SetTexture(0, boneMesh->textures[mtrlIndex]);
g_pEffect->SetMatrix("matW", &identity);
g_pEffect->SetTexture("texDiffuse", boneMesh->textures[mtrlIndex]);
D3DXHANDLE hTech = g_pEffect->GetTechniqueByName("Skinning");
g_pEffect->SetTechnique(hTech);
g_pEffect->Begin(NULL, NULL);
g_pEffect->BeginPass(0);
boneMesh->MeshData.pMesh->DrawSubset(mtrlIndex);
g_pEffect->EndPass();
g_pEffect->End();
}
}
else
{
//Normal Static Mesh
g_pEffect->SetMatrix("matW", &bone->CombinedTransformationMatrix);
D3DXHANDLE hTech = g_pEffect->GetTechniqueByName("Lighting");
g_pEffect->SetTechnique(hTech);
//Render the mesh
int numMaterials = (int)boneMesh->materials.size();
for(int i=0;i < numMaterials;i++)
{
g_pDevice->SetMaterial(&boneMesh->materials[i]);
g_pEffect->SetVector( "materialColor",
( D3DXVECTOR4* )&(
boneMesh->materials[i].Diffuse ) );
g_pEffect->SetTexture("texDiffuse", boneMesh->textures[i]);
g_pEffect->Begin(NULL, NULL);
g_pEffect->BeginPass(0);
boneMesh->OriginalMesh->DrawSubset(i);
g_pEffect->EndPass();
g_pEffect->End();
}
}
}
if(bone->pFrameSibling != NULL)Render((Bone*)bone->pFrameSibling);
if(bone->pFrameFirstChild != NULL)Render((Bone*)bone->pFrameFirstChild);
}
void SkinnedMesh::SetupBoneMatrixPointers(Bone *bone)
{
if(bone->pMeshContainer != NULL)
{
BoneMesh *boneMesh = (BoneMesh*)bone->pMeshContainer;
if(boneMesh->pSkinInfo != NULL)
{
int NumBones = boneMesh->pSkinInfo->GetNumBones();
boneMesh->boneMatrixPtrs = new D3DXMATRIX*[NumBones];
for(int i=0;i < NumBones;i++)
{
Bone *b = (Bone*)D3DXFrameFind(m_pRootBone, boneMesh->pSkinInfo->GetBoneName(i));
if(b != NULL)boneMesh->boneMatrixPtrs[i] = &b->CombinedTransformationMatrix;
else boneMesh->boneMatrixPtrs[i] = NULL;
}
}
}
if(bone->pFrameSibling != NULL)SetupBoneMatrixPointers((Bone*)bone->pFrameSibling);
if(bone->pFrameFirstChild != NULL)SetupBoneMatrixPointers((Bone*)bone->pFrameFirstChild);
}
void SkinnedMesh::Draw(const D3DXMATRIX& mat)
{
D3DXMATRIX m(mat);
UpdateMatrices((Bone*)m_pRootBone, &m);
Render(NULL);
}
Thanks in advance for any assistance.
Jack