话说学D3D已经有2个月了,一个礼拜之前才刚刚进入实践阶段,终于画出了我第一个三角形,庆祝下~~不过晚了点。。
这个程序是用自己编写的类实现的,用到VertexBuffer的同时也用了一个IndexBuffer,当初调试的时候因为IB里的顶点顺序反了,所以三角形显示的是反面,看不见。。我那个着急啊,最后问题还是找到了,程序也运行成功了,心也就平静了下来。
别的不说了,上源代码:
hero.h文件
//#pragma once
#include "windows.h"
#include "d3d9.h"
#include "d3d9types.h"
struct MYVERTEX
{
FLOAT x,y,z,rhw;
DWORD color;
};
#define MYFVF (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
#define SafeRelease(p) if(p!=NULL){p->Release();p=NULL;}
class hero
{
LPDIRECT3D9 m_pD3D;
LPDIRECT3DDEVICE9 m_pD3DDevice;
LPDIRECT3DVERTEXBUFFER9 m_pVB;
LPDIRECT3DINDEXBUFFER9 m_pIB;
public:
hero(void);
virtual HRESULT Init(HWND xhwnd);
virtual HRESULT Load();
virtual HRESULT Render();
virtual HRESULT Clean();
virtual HRESULT Destroy();
~hero(void);
};
hero.cpp文件
#include "hero.h"
#include "windows.h"
#include "d3d9.h"
#include "d3d9types.h"
hero::hero(void)
{
}
HRESULT hero::Init(HWND xhwnd)
{
m_pD3D=Direct3DCreate9(D3D_SDK_VERSION);
if(m_pD3D==NULL) return E_FAIL;
D3DDISPLAYMODE d3ddm;
if(FAILED(m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddm))) return E_FAIL;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed=TRUE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat=d3ddm.Format;
if(FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,xhwnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&m_pD3DDevice)))
return E_FAIL;
return S_OK;
}
HRESULT hero::Load()
{
VOID *pVertices;
WORD *pIndices;
MYVERTEX cVertices[]=
{
{400.0f,150.0f,0.5f,1.0f,0xffff0000,},
{226.8f,450.0f,0.5f,1.0f,0xffff0000,},
{573.2f,450.0f,0.5f,1.0f,0xffff0000,},
};
WORD cIndices[]={0,2,1};
if(FAILED(m_pD3DDevice->CreateVertexBuffer(3*sizeof(MYVERTEX),0,MYFVF,D3DPOOL_DEFAULT,&m_pVB,NULL)))
return E_FAIL;
if(FAILED(m_pD3DDevice->CreateIndexBuffer(3*sizeof(WORD),0,D3DFMT_INDEX16,D3DPOOL_DEFAULT,&m_pIB,NULL)))
return E_FAIL;
if(FAILED(m_pVB->Lock(0,sizeof(cVertices),(void **)&pVertices,0))) return E_FAIL;
memcpy(pVertices,cVertices,sizeof(cVertices));
m_pVB->Unlock();
if(FAILED(m_pIB->Lock(0,sizeof(cIndices),(void **)&pIndices,0))) return E_FAIL;
memcpy(pIndices,cIndices,sizeof(cIndices));
m_pIB->Unlock();
return S_OK;
}
HRESULT hero::Render()
{
if(m_pD3DDevice==NULL) return E_FAIL;
m_pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,0xff000000,1.0f,0);
m_pD3DDevice->BeginScene();
m_pD3DDevice->SetStreamSource(0,m_pVB,0,sizeof(MYVERTEX));
m_pD3DDevice->SetFVF(MYFVF);
m_pD3DDevice->SetIndices(m_pIB);
m_pD3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN,0,0,3,0,1);
m_pD3DDevice->EndScene();
m_pD3DDevice->Present(NULL,NULL,NULL,NULL);
return S_OK;
}
HRESULT hero::Clean()
{
if(m_pD3D==NULL || m_pD3DDevice==NULL) return E_FAIL;
SafeRelease(m_pIB);
SafeRelease(m_pVB);
return S_OK;
}
HRESULT hero::Destroy()
{
if(m_pVB!=NULL || m_pIB!=NULL) return E_FAIL;
SafeRelease(m_pD3DDevice);
SafeRelease(m_pD3D);
return S_OK;
}
hero::~hero(void)
{
}
main.cpp文件
#include "windows.h"
#include "d3d9.h"
#include "d3d9types.h"
#include "hero.h"
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
wchar_t szWcName[]=L"MyWindow";
BOOL bActive=TRUE;
int WINAPI WinMain(HINSTANCE hThis,HINSTANCE hPrev,LPSTR lpszArgs,int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASS mywc;
hero *myhero;
mywc.hInstance=hThis;
mywc.lpszClassName=szWcName;
mywc.lpfnWndProc=WndProc;
mywc.style=0;
mywc.hIcon=LoadIcon(NULL,MAKEINTRESOURCE(IDI_APPLICATION));
mywc.hCursor=LoadCursor(NULL,IDC_ARROW);
mywc.lpszMenuName=NULL;
mywc.cbClsExtra=0;
mywc.cbWndExtra=0;
mywc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
if(!RegisterClass(&mywc)) return 0;
DWORD dwWindowStyle=WS_POPUP|WS_BORDER|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_VISIBLE;
DWORD dwWidth=800;
DWORD dwHeight=600;
RECT rc;
SetRect(&rc,0,0,dwWidth,dwHeight);
AdjustWindowRect(&rc,dwWindowStyle,FALSE);
hwnd=CreateWindow(szWcName,L"New Hero Class Direct3D Test",dwWindowStyle,CW_USEDEFAULT,CW_USEDEFAULT,rc.right-rc.left,rc.bottom-rc.top,NULL,NULL,hThis,NULL);
BOOL bGotMsg;
myhero=new hero();
if(SUCCEEDED(myhero->Init(hwnd)))
{
ShowWindow(hwnd,nWinMode);
if(SUCCEEDED(myhero->Load()))
{
do{
if(bActive) bGotMsg=PeekMessage(&msg,NULL,0U,0U,PM_REMOVE);
else bGotMsg=GetMessage(&msg,NULL,0U,0U);
if(bGotMsg)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if(bActive)
{
if(FAILED(myhero->Render()))
{
delete myhero;
return 0;
}
}
}while(WM_QUIT!=msg.message);
}
else
{
delete myhero;
return 0;
}
}
else
{
delete myhero;
return 0;
}
if(FAILED(myhero->Clean()))
{
delete myhero;
return 0;
}
if(FAILED(myhero->Destroy()))
{
delete myhero;
return 0;
}
delete myhero;
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
PostQuitMessage(WM_QUIT);
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(WM_QUIT);
break;
case VK_F1:
bActive=FALSE;
MessageBox(hwnd,L"help",L"help",MB_OK);
bActive=TRUE;
}
break;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
运行效果: