Cube.h
#ifndef _WX_D3D9_TEST_H_
#define _WX_D3D9_TEST_H_
#include <wx/wx.h>
#include <d3d9.h>
#include <d3dx9.h>
// Define a new application type
class MyApp: public wxApp
{
public:
bool OnInit();
};
class D3D9Canvas;
class MyFrame: public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void SetCanvas( D3D9Canvas *canvas ) { m_canvas = canvas; }
D3D9Canvas *GetCanvas() { return m_canvas; }
DECLARE_EVENT_TABLE()
private:
D3D9Canvas *m_canvas;
};
class D3D9Canvas : public wxWindow
{
public:
D3D9Canvas(wxWindow *parent, wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = 0,
const wxString& name = wxT("TestGLCanvas"));
~D3D9Canvas();
protected:
void OnPaint(wxPaintEvent& event);
void OnSize(wxSizeEvent& event);
void OnIdle( wxIdleEvent& event );
void OnEraseBackground(wxEraseEvent& event);
private:
void InitD3D();
void ResetProjectionMode();
void Render();
bool m_init;
DECLARE_EVENT_TABLE()
};
#endif // #ifndef _WX_D3D9_TEST_H_
Cube.cpp
#include "cube.h"
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
//-----------------------------------------------------------------------------
// GLOBALS
//-----------------------------------------------------------------------------
HWND g_hWnd = NULL;
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL;
float g_fTime;
#define D3DFVF_CUSTOMVERTEX ( D3DFVF_XYZ )
struct Vertex
{
float x, y, z;
};
Vertex g_cubeVertices[] =
{
{-1.0f, 1.0f,-1.0f},
{ 1.0f, 1.0f,-1.0f},
{-1.0f,-1.0f,-1.0f},
{ 1.0f,-1.0f,-1.0f},
{-1.0f, 1.0f, 1.0f},
{-1.0f,-1.0f, 1.0f},
{ 1.0f, 1.0f, 1.0f},
{ 1.0f,-1.0f, 1.0f},
{-1.0f, 1.0f, 1.0f},
{ 1.0f, 1.0f, 1.0f},
{-1.0f, 1.0f,-1.0f},
{ 1.0f, 1.0f,-1.0f},
{-1.0f,-1.0f, 1.0f},
{-1.0f,-1.0f,-1.0f},
{ 1.0f,-1.0f, 1.0f},
{ 1.0f,-1.0f,-1.0f},
{ 1.0f, 1.0f,-1.0f},
{ 1.0f, 1.0f, 1.0f},
{ 1.0f,-1.0f,-1.0f},
{ 1.0f,-1.0f, 1.0f},
{-1.0f, 1.0f,-1.0f},
{-1.0f,-1.0f,-1.0f},
{-1.0f, 1.0f, 1.0f},
{-1.0f,-1.0f, 1.0f}
};
enum
{
ID_Quit = 1,
ID_About,
};
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(ID_About, MyFrame::OnAbout)
END_EVENT_TABLE()
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame( _T("Hello World"), wxPoint(50,50), wxSize(800,600) );
frame->Show(TRUE);
SetTopWindow(frame);
return TRUE;
}
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
{
wxMenu *menuFile = new wxMenu;
menuFile->Append( ID_About, _T("&About...") );
menuFile->AppendSeparator();
menuFile->Append( ID_Quit, _T("E&xit") );
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( menuFile, _T("&File") );
SetMenuBar( menuBar );
m_canvas = new D3D9Canvas(this, wxID_ANY, wxDefaultPosition,
wxSize(800, 600), wxSUNKEN_BORDER);
CreateStatusBar();
SetStatusText( _T("Welcome to wxWidgets!") );
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(TRUE);
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(_T("This is a wxWidgets D3D9 Hello world sample"),
_T("About D3D9 Hello World"), wxOK | wxICON_INFORMATION, this);
}
// ---------------------------------------------------------------------------
// TestD3D9Canvas
// ---------------------------------------------------------------------------
BEGIN_EVENT_TABLE(D3D9Canvas, wxWindow)
EVT_SIZE(D3D9Canvas::OnSize)
EVT_PAINT(D3D9Canvas::OnPaint)
EVT_ERASE_BACKGROUND(D3D9Canvas::OnEraseBackground)
EVT_IDLE(D3D9Canvas::OnIdle)
END_EVENT_TABLE()
D3D9Canvas::D3D9Canvas(wxWindow *parent, wxWindowID id,
const wxPoint& pos, const wxSize& size, long style, const wxString& name)
: wxWindow(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name)
{
m_init = false;
g_hWnd = (HWND)GetHWND();
g_fTime = 0;
}
D3D9Canvas::~D3D9Canvas()
{
if( g_pVertexBuffer != NULL )
g_pVertexBuffer->Release();
if( g_pd3dDevice != NULL )
g_pd3dDevice->Release();
if( g_pD3D != NULL )
g_pD3D->Release();
}
void D3D9Canvas::OnIdle(wxIdleEvent &event)
{
event.RequestMore(true);
Render();
}
void D3D9Canvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
{
wxPaintDC dc(this);
// Initialize D3D
if (!m_init)
{
InitD3D();
ResetProjectionMode();
m_init= true;
}
}
void D3D9Canvas::OnSize(wxSizeEvent& event)
{
// Reset the D3D view aspect
ResetProjectionMode();
}
void D3D9Canvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
{
// Do nothing, to avoid flashing on MSW
}
void D3D9Canvas::InitD3D()
{
g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
D3DDISPLAYMODE d3ddm;
g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm );
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice );
g_pd3dDevice->CreateVertexBuffer( 24*sizeof(Vertex),0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVertexBuffer, NULL );
void *pVertices = NULL;
g_pVertexBuffer->Lock( 0, sizeof(g_cubeVertices), (void**)&pVertices, 0 );
memcpy( pVertices, g_cubeVertices, sizeof(g_cubeVertices) );
g_pVertexBuffer->Unlock();
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
}
void D3D9Canvas::ResetProjectionMode()
{
if(g_pd3dDevice == NULL)
return;
int w, h;
GetClientSize(&w, &h);
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DXToRadian( 45.0f ),
(float)w / float(h), 0.1f, 100.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
void D3D9Canvas::Render()
{
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_COLORVALUE(0.0f,0.0f,255.0f,1.0f), 1.0f, 0 );
g_fTime += 0.005;
D3DXMATRIX matWorld;
D3DXMATRIX matTrans;
D3DXMATRIX matRot;
D3DXMatrixTranslation( &matTrans, 0.0f, 0.0f, 5.0f );
D3DXMatrixRotationYawPitchRoll( &matRot,
D3DXToRadian(g_fTime),
D3DXToRadian(g_fTime),
D3DXToRadian(g_fTime) );
matWorld = matRot * matTrans;
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
g_pd3dDevice->BeginScene();
g_pd3dDevice->SetStreamSource( 0, g_pVertexBuffer, 0, sizeof(Vertex) );
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 4, 2 );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 8, 2 );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 12, 2 );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 16, 2 );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 20, 2 );
g_pd3dDevice->EndScene();
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}