在使用固定管道的頂點混合時候,會出現種種問題,比如:在指定D3DFVF_XYZBn的時候,權重是寫n個還是n-1個,矩陣的索引該怎麼設置才正確,DWORD類型的索引值應該跟在誰後面,還有D3DFVF_LASTBETA_UBYTE4這個FVF到底該怎麼使用才正確,矩陣面板上的256個索引怎麼才能隨心所欲的使用,接下來就根據程序一一解決這些疑惑。
一 問題以及答案
1 權重到底該寫幾個?
答案是如果FVF中包含D3DFVF_XYZBn,那麼權重就只需要n-1個即可,如果再多寫一個,或許能顯示出來並且位置正常,但是有可能其他不正常,例如顏色不是你想要的。
2 矩陣的索引該怎麼設置纔對?
這個要分情況,當FVF中包含D3DFVF_XYZBn並且不包含D3DFVF_LASTBETA_UBYTE4的時候,這個時候矩陣索引的設置要根據渲染狀態來確定。
首先開啓頂點混合,需要下面的狀態:
g_pDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE,TRUE );
g_pDevice->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_2WEIGHTS );
第一句是開啓頂點索引混合,第二個開啓頂點混合,注意D3DVBF_2WEIGHTS這個東西,可以在D3DVERTEXBLENDFLAGS枚舉中看到相關的定義
typedef enum D3DVERTEXBLENDFLAGS {
D3DVBF_DISABLE = 0,
D3DVBF_1WEIGHTS = 1,
D3DVBF_2WEIGHTS = 2,
D3DVBF_3WEIGHTS = 3,
D3DVBF_TWEENING = 255,
D3DVBF_0WEIGHTS = 256
} D3DVERTEXBLENDFLAGS, *LPD3DVERTEXBLENDFLAGS;
這裏令人比較氣憤的是微軟真他媽的誤導人,D3DVBF_2WEIGHTS
的這裏的真實意思索引爲0,1,2的矩陣參與頂點混合,而不是我們理所當然的認爲是就2個權重(也就是2個矩陣參與頂點混合)
自然我們會想到既然矩陣的索引已經規定的那麼死了,索引範圍頂多是0-3,那麼後面的DWORD再去規定矩陣的索引有意義嗎?還有沒有必要加上DWORD類型的矩陣索引?
答案是這個DWORD表示的矩陣索引是完全沒意義的,也就是說我們可以隨便給DWORD賦值。但是這個DWORD還必須得加這也是感覺微軟設計蛋疼得地方。
3 DWORD
類型的矩陣索引值要跟在哪?
DWORD
是個32bit的整形,32位分成了每8bit一個小組,從低字節到高字節一共4個字節,低字節的8bit指定了第一個權重的矩陣索引,依次類推。
DWORD
類型的矩陣索引必須跟在最後一個權重的後面。這是嚴格的,必須遵守的。
4 D3DFVF_LASTBETA_UBYTE4它到底是幹啥的?
這個東西要說有用也有用,沒用也可以不用。當有D3DFVF_LASTBETA_UBYTE4的時候,在指定矩陣索引值的時候我們可以突破0-3的限制,可以在0-255之間隨意些,並且此時DWORD指定的矩陣索引就是真正的矩陣索引值,你不可以像之前那麼亂寫。
二 驗證
1 第三個權重的驗證
struct BoneVertex1
{
floatx,y,z;
floatw1,w2;
DWORD dwInd;
DWORD dwC;
BoneVertex1(floatx1,float y1,floatz1,float f1,floatf2,DWORD dwI,DWORD dwL)
{
x = x1;y = y1;z = z1;
w1 = f1;w2 = f2;
dwInd = dwI;dwC = dwL;
}
};
#define D3DFVF_BONE1 (D3DFVF_XYZB3 | D3DFVF_DIFFUSE)
struct BoneVertex2
{
floatx,y,z;
floatw1,w2,w3;
DWORD dwInd;
DWORD dwC;
BoneVertex2(floatx1,float y1,floatz1,float f1,floatf2,float f3,DWORD dwI,DWORD dwL)
{
x = x1;y = y1;z = z1;
w1 = f1;w2 = f2;w3=f3;
dwInd = dwI;dwC = dwL;
}
};
#define D3DFVF_BONE2 (D3DFVF_XYZB3 | D3DFVF_DIFFUSE)
BoneVertex1和BoneVertex2的區別是BoneVertex2多了一個權重,在這裏驗證的第三個權重到底有用沒?
頂點緩存初始化:
DWORD dwF = (0x0) +(0x1<<8) + (0x2<<16);
//DWORD dwF =(0x1) + (0x3<<8) + (0x7<<16);
g_pDevice->CreateVertexBuffer(2*sizeof(BoneVertex1),0,D3DFVF_BONE1,D3DPOOL_MANAGED,&g_pVB1,NULL);
BoneVertex1* pV1 = NULL;
g_pVB1->Lock(0,0,(void**)&pV1,0);
pV1[0] = BoneVertex1(-5.0f,0.0f,0.0f, 0.2f,0.3f, dwF,D3DCOLOR_XRGB(255,0,0));
pV1[1] = BoneVertex1(5.0f,-3.0f,0.0f, 0.2f,0.3f, dwF,D3DCOLOR_XRGB(255,0,0));
g_pVB1->Unlock();
g_pDevice->CreateVertexBuffer(sizeof(BoneVertex2)*2,0,D3DFVF_BONE2,D3DPOOL_MANAGED,&g_pVB2,NULL);
BoneVertex2* pV2 = NULL;
g_pVB2->Lock(0,0,(void**)&pV2,0);
pV2[0] =BoneVertex2(-5.0f,0.0f,0.0f, 0.2f,0.3f,0.2f, dwF,D3DCOLOR_XRGB(255,0,0));
pV2[1] =BoneVertex2(5.0f,-3.0f,0.0f, 0.2f,0.3f,0.2f, dwF,D3DCOLOR_XRGB(255,0,0));
g_pVB2->Unlock();
BoneVertex1的圖:
BoneVertex2的圖
可以看到的是兩者都能正常顯示位置,但是BoneVertex2的顏色不是指定的顏色,並且隨意更改第三個權重對繪製結果沒影響,這就說明了第三個權重是多餘的,有害的。
2 更改DWORD dwF = (0x1) + (0x3<<8) + (0x7<<16);
繪製結果跟上面一樣,說明這個時候這個索引沒用。
3 針對BoneVertex4的測試
當把DWOD類型的索引值更改爲DWORD dwF = (0x1) + (0x3<<8) +(0x7<<16);
的時候,繪製的圖是這樣的:
當把索引值改爲DWORDdwF = (0x0) + (0x1<<8) + (0x2<<16);的時候,繪製的圖是這樣的:
當把索引值該爲DWORDdwF = (0x1) + (0x3<<8) + (0x7<<16);
矩陣設置爲:
g_pDevice->SetTransform(D3DTS_WORLDMATRIX(1),&mm1);
g_pDevice->SetTransform(D3DTS_WORLDMATRIX(3),&mm2);
g_pDevice->SetTransform(D3DTS_WORLDMATRIX(7),&mm3);
繪製的圖是這樣的:
現在什麼問題都已經明瞭了。
三 總結的可行性方案
以後遇到就這麼寫頂點格式:
1
struct BoneVertex1
{
floatx,y,z;
floatw1,w2;
DWORD dwInd;
DWORD dwC;
BoneVertex1(floatx1,float y1,floatz1,float f1,floatf2,DWORD dwI,DWORD dwL)
{
x = x1;y = y1;z = z1;
w1 = f1;w2 = f2;
dwInd = dwI;dwC = dwL;
}
};
#define D3DFVF_BONE1 (D3DFVF_XYZB3 | D3DFVF_DIFFUSE)
2
struct BoneVertex4
{
float x,y,z;
float w1,w2;
DWORD dwInd;
DWORD dwC;
BoneVertex4(float x1,float y1,float z1,float f1,float f2,DWORD dwI,DWORD dwL)
{
x = x1;y = y1;z = z1;
w1 = f1;w2 = f2;
dwInd = dwI;dwC = dwL;
}
};
#define D3DFVF_BONE4 (D3DFVF_XYZB3 | D3DFVF_LASTBETA_UBYTE4 | D3DFVF_DIFFUSE )
3 感想
微軟不管做什麼都是想搞的一統天下,有些文檔也是錯的,有些API爲了功能強大而設計的異常複雜,一個參數就有可能引出很多問題,這種做法真的很蛋疼。
四 貼出完整的帶代碼
//DxInit.h
#ifndef DDXX_DXINIT_H
#define DDXX_DXINIT_H
#include <d3dx9.h>
#include <d3d9.h>
#include <iostream>
#include <string>
using namespace std;
extern LPDIRECT3DDEVICE9 g_pDevice;
extern D3DDEVTYPE g_DevType;
extern D3DDISPLAYMODE g_Display;
extern LPDIRECT3D9 g_pD3D9;
extern D3DCAPS9 g_caps;
bool InitD3D(intnHeight,int nWidth,boolbWindow,HWND hwnds);
template<class T>void Release(T t);
template<class T>void Delete(T t);
#endif
//DxInit.cpp
#include "DXInit.h"
D3DDEVTYPE g_DevType =D3DDEVTYPE_HAL;
D3DDISPLAYMODE g_Display;
LPDIRECT3D9 g_pD3D9 = NULL;
D3DCAPS9 g_caps;
bool InitD3D(intnHeight,int nWidth,boolbWindow,HWND hwnds)
{
// createDirect3D9 object
g_pD3D9 =Direct3DCreate9(D3D_SDK_VERSION);
if(g_pD3D9 == NULL )
{
MessageBox(NULL,"Direct3D9 failed to create!","Error",MB_OK);
returnfalse;
}
//get theprimal display mode
HRESULT hAdapter= NULL;
hAdapter = g_pD3D9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&g_Display);
if(FAILED(hAdapter) )
{
MessageBox(NULL,"Get adapater mode failed!","Error",MB_OK);
returnfalse;
}
//check forhardware vertex processing
HRESULT hCaps;
int vp;
hCaps = g_pD3D9->GetDeviceCaps(D3DADAPTER_DEFAULT,g_DevType,&g_caps);
if(g_caps.DevCaps& D3DDEVCAPS_HWTRANSFORMANDLIGHT)
vp =D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp =D3DCREATE_SOFTWARE_VERTEXPROCESSING;
//fill theparaments for window
D3DPRESENT_PARAMETERS d3dpp;
::ZeroMemory(&d3dpp,sizeof(d3dpp) );
if(bWindow)
{
d3dpp.Windowed = TRUE;
d3dpp.BackBufferHeight = 0;
d3dpp.BackBufferWidth = 0;
d3dpp.BackBufferFormat =g_Display.Format;
d3dpp.FullScreen_RefreshRateInHz= D3DPRESENT_RATE_DEFAULT;
}
else
{
d3dpp.Windowed = FALSE;
d3dpp.BackBufferHeight =nHeight*2;
d3dpp.BackBufferWidth = nWidth*2;
d3dpp.BackBufferFormat =g_Display.Format;
d3dpp.FullScreen_RefreshRateInHz= g_Display.RefreshRate;
}
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hwnds;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat =D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
//createDevice
HRESULT hDev = NULL;
hDev =g_pD3D9->CreateDevice(D3DADAPTER_DEFAULT,g_DevType,hwnds,vp,&d3dpp,&g_pDevice);
if(FAILED(hDev) )
{
d3dpp.AutoDepthStencilFormat= D3DFMT_D16;
hDev =g_pD3D9->CreateDevice(D3DADAPTER_DEFAULT,g_DevType,hwnds,vp,&d3dpp,&g_pDevice);
if(FAILED(hDev) )
{
Release(g_pD3D9);
Release(g_pDevice);
MessageBox(NULL,"Create device failed!","ERROR",MB_OK);
returnfalse;
}
}
g_pD3D9->Release();
return true;
}
template<class T>void Release(T t)
{
if( t!= NULL)
{
t->Release();
t = NULL;
}
}
template<class T>void Delete(T t)
{
if (t!= NULL)
{
deletet;
t = NULL;
}
}
//blend.h
#ifndef DDXX_VERTEX_H
#define DDXX_VERTEX_H
#include <d3d9.h>
#include <d3dx9.h>
struct GridVertex
{
D3DXVECTOR3 vecPos;
DWORD dwCol;
GridVertex(D3DXVECTOR3& v1,DWORDcL)
{
vecPos = v1;
dwCol = cL;
}
};
#define D3DFVF_GRID (D3DFVF_XYZ| D3DFVF_DIFFUSE)
struct BoneVertex1
{
floatx,y,z;
floatw1,w2;
DWORD dwInd;
DWORD dwC;
BoneVertex1(floatx1,float y1,floatz1,float f1,floatf2,DWORD dwI,DWORD dwL)
{
x = x1;y = y1;z = z1;
w1 = f1;w2 = f2;
dwInd = dwI;dwC = dwL;
}
};
#define D3DFVF_BONE1 (D3DFVF_XYZB3 | D3DFVF_DIFFUSE)
struct BoneVertex2
{
floatx,y,z;
floatw1,w2,w3;
DWORD dwInd;
DWORD dwC;
BoneVertex2(floatx1,float y1,floatz1,float f1,floatf2,float f3,DWORD dwI,DWORD dwL)
{
x = x1;y = y1;z = z1;
w1 = f1;w2 = f2;w3=f3;
dwInd = dwI;dwC = dwL;
}
};
#define D3DFVF_BONE2 (D3DFVF_XYZB3 | D3DFVF_DIFFUSE)
struct BoneVertex3
{
floatx,y,z;
floatw1,w2;
DWORD dwC;
BoneVertex3(floatx1,float y1,floatz1,float f1,floatf2,DWORD dwL )
{
x = x1;y = y1;z = z1;
w1 = f1;w2 = f2;
dwC = dwL;
}
};
#define D3DFVF_BONE3 (D3DFVF_XYZB3 | D3DFVF_DIFFUSE)
struct BoneVertex4
{
floatx,y,z;
floatw1,w2;
DWORD dwInd;
DWORD dwC;
BoneVertex4(floatx1,float y1,floatz1,float f1,floatf2,DWORD dwI,DWORD dwL)
{
x = x1;y = y1;z = z1;
w1 = f1;w2 = f2;
dwInd = dwI;dwC = dwL;
}
};
#define D3DFVF_BONE4(D3DFVF_XYZB3 | D3DFVF_LASTBETA_UBYTE4 | D3DFVF_DIFFUSE )
#endif
//main.cpp
#include "blend.h"
#include "DxInit.h"
#include <Windows.h>
bool InitObject();
bool InitScene();
void RenderScene();
void QuitDirectX();
LRESULT CALLBACKWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
TCHAR *AppName = TEXT("dX");
TCHAR *WndName = TEXT("app");
const int g_nHeight = 480;
const int g_nWidth = 640;
const bool g_bWindow =true;
LPDIRECT3DDEVICE9 g_pDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
LPDIRECT3DVERTEXBUFFER9g_pVB1 = NULL;
LPDIRECT3DVERTEXBUFFER9g_pVB2 = NULL;
LPDIRECT3DVERTEXBUFFER9g_pVB3 = NULL;
LPDIRECT3DVERTEXBUFFER9g_pVB4 = NULL;
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCEhPreInstance,LPSTR cmdLine,int nShow)
{
WNDCLASSEX wndEx;
wndEx.cbSize = sizeof(WNDCLASSEX);
wndEx.style = CS_CLASSDC;
wndEx.lpfnWndProc = WndProc;
wndEx.cbClsExtra = 0;
wndEx.cbWndExtra = 0;
wndEx.hInstance = hInstance;
wndEx.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndEx.hCursor = LoadCursor(NULL,IDC_ARROW);
wndEx.hbrBackground =(HBRUSH)COLOR_ACTIVEBORDER;
wndEx.lpszMenuName = NULL;
wndEx.lpszClassName = AppName;
wndEx.hIconSm = NULL;
if(!RegisterClassEx(&wndEx) )
{
MessageBox(NULL,TEXT("Register windos failed!"),TEXT("ERROR"),MB_OK);
return0;
}
HWND hwnd = NULL;
hwnd =CreateWindowEx(0,AppName,WndName,WS_OVERLAPPEDWINDOW,
100,100,g_nWidth,g_nHeight,
NULL,NULL,hInstance,NULL);
if(hwnd== NULL)
{
MessageBox(NULL,TEXT("Create windos failed!"),TEXT("ERROR"),MB_OK);
return0;
}
if(!InitD3D(g_nHeight,g_nWidth,g_bWindow,hwnd) )
{
QuitDirectX();
return0;
}
if(!InitObject() )
{
QuitDirectX();
return0;
}
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
MSG msg;
ZeroMemory(&msg,sizeof(MSG));
while(msg.message!= WM_QUIT)
{
if(PeekMessage(&msg,NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
RenderScene();
}
UnregisterClass(AppName,hInstance);
QuitDirectX();
return0;
}
LRESULT CALLBACKWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
caseWM_DESTROY:
PostQuitMessage(0);
break;
caseWM_KEYDOWN:
if(wParam== VK_ESCAPE)
DestroyWindow(hwnd);
break;
}
returnDefWindowProc(hwnd,msg,wParam,lParam);
}
bool InitScene()
{
g_pDevice->CreateVertexBuffer(sizeof(GridVertex)*804,0,D3DFVF_GRID,D3DPOOL_MANAGED,&g_pVB,NULL);
GridVertex* pGrid = NULL;
g_pVB->Lock(0,0,(void**)&pGrid,0);
for(int i=0;i<100;i++)
{
pGrid[8*i] = GridVertex(D3DXVECTOR3(-100.0f,100.0f-i,0.0f),D3DCOLOR_XRGB(255,255,0));
pGrid[8*i+1] =GridVertex(D3DXVECTOR3(100.0f,100.0f-i,0.0f),D3DCOLOR_XRGB(255,255,0));
pGrid[8*i+2] =GridVertex(D3DXVECTOR3(-100.0f,-100.0f+i,0.0f),D3DCOLOR_XRGB(255,255,0));
pGrid[8*i+3] =GridVertex(D3DXVECTOR3(100.0f,-100.0f+i,0.0f),D3DCOLOR_XRGB(255,255,0));
pGrid[8*i+4] =GridVertex(D3DXVECTOR3(-100.0f+i,100.0f,0.0f),D3DCOLOR_XRGB(255,255,0));
pGrid[8*i+5] =GridVertex(D3DXVECTOR3(-100.0f+i,-100.0f,0.0f),D3DCOLOR_XRGB(255,255,0));
pGrid[8*i+6] =GridVertex(D3DXVECTOR3(100.0f-i,100.0f,0.0f),D3DCOLOR_XRGB(255,255,0));
pGrid[8*i+7] =GridVertex(D3DXVECTOR3(100.0f-i,-100.0f,0.0f),D3DCOLOR_XRGB(255,255,0));
}
pGrid[800] =GridVertex(D3DXVECTOR3(-100.0f,0.0f,0.0f),D3DCOLOR_XRGB(255,0,0));
pGrid[801] =GridVertex(D3DXVECTOR3(100.0f,0.0f,0.0f),D3DCOLOR_XRGB(255,0,0));
pGrid[802] =GridVertex(D3DXVECTOR3(0.0f,100.0f,0.0f),D3DCOLOR_XRGB(255,0,0));
pGrid[803] =GridVertex(D3DXVECTOR3(0.0f,-100.0f,0.0f),D3DCOLOR_XRGB(255,0,0));
g_pVB->Unlock();
// must turnoff the light so that the point can be drawn in its color
//好像是關燈根據漫反射顏色計算,開燈則是根據材質和光照來計算
//g_pDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
D3DXVECTOR3 vPosition(0.0f, 0.0f,-20.0f);
D3DXVECTOR3 vTarget(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vUp(0.0f, 1.0f, 0.0f);
D3DXMATRIX vView;
D3DXMatrixLookAtLH(&vView,&vPosition,&vTarget,&vUp);
g_pDevice->SetTransform(D3DTS_VIEW,&vView);
D3DXMATRIX mProj;
//D3DXMatrixOrthoLH(&vProj,(FLOAT)g_nWidth,(FLOAT)g_nHeight,1.0f,1000.0f);
D3DXMatrixPerspectiveFovLH(&mProj,D3DX_PI* 0.5f,
(float)g_nWidth/ (float)g_nHeight, 1.0f,1000.0f);
g_pDevice->SetTransform(D3DTS_PROJECTION,&mProj);
g_pDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
return true;
}
bool InitObject()
{
InitScene();
//DWORD dwF =(0x0) + (0x1<<8) + (0x2<<16);
DWORD dwF = (0x1) + (0x3<<8) +(0x7<<16);
g_pDevice->CreateVertexBuffer(2*sizeof(BoneVertex1),0,D3DFVF_BONE1,D3DPOOL_MANAGED,&g_pVB1,NULL);
BoneVertex1* pV1 = NULL;
g_pVB1->Lock(0,0,(void**)&pV1,0);
pV1[0] = BoneVertex1(-5.0f,0.0f,0.0f, 0.2f,0.3f, dwF,D3DCOLOR_XRGB(255,0,0));
pV1[1] = BoneVertex1(5.0f,-3.0f,0.0f, 0.2f,0.3f, dwF,D3DCOLOR_XRGB(255,0,0));
g_pVB1->Unlock();
g_pDevice->CreateVertexBuffer(sizeof(BoneVertex2)*2,0,D3DFVF_BONE2,D3DPOOL_MANAGED,&g_pVB2,NULL);
BoneVertex2* pV2 = NULL;
g_pVB2->Lock(0,0,(void**)&pV2,0);
pV2[0] =BoneVertex2(-5.0f,0.0f,0.0f, 0.2f,0.3f,0.2f, dwF,D3DCOLOR_XRGB(255,0,0));
pV2[1] =BoneVertex2(5.0f,-3.0f,0.0f, 0.2f,0.3f,0.2f, dwF,D3DCOLOR_XRGB(255,0,0));
g_pVB2->Unlock();
g_pDevice->CreateVertexBuffer(sizeof(BoneVertex3)*2,0,D3DFVF_BONE3,D3DPOOL_MANAGED,&g_pVB3,NULL);
BoneVertex3* pV3 = NULL;
g_pVB3->Lock(0,0,(void**)&pV3,NULL);
/*pV3[0] =BoneVertex3(-5.0f,0.0f,0.0f, 0.2f,0.3f, D3DCOLOR_XRGB(255,0,0));
pV3[1] = BoneVertex3(5.0f,-3.0f,0.0f, 0.2f,0.3f, D3DCOLOR_XRGB(255,0,0));*/
pV3[0] = BoneVertex3(-5.0f,0.0f,0.0f, 0.2f,0.3f, dwF);
pV3[1] = BoneVertex3(5.0f,-3.0f,0.0f, 0.2f,0.3f, dwF);
g_pVB3->Unlock();
g_pDevice->CreateVertexBuffer(sizeof(BoneVertex4)*2,0,D3DFVF_BONE4,D3DPOOL_MANAGED,&g_pVB4,NULL);
BoneVertex4 *pV4 = NULL;
g_pVB4->Lock(0,0,(void**)&pV4,0);
pV4[0] = BoneVertex4(-5.0f,0.0f,0.0f, 0.2f,0.3f, dwF,D3DCOLOR_XRGB(255,0,255));
pV4[1] = BoneVertex4(5.0f,-3.0f,0.0f, 0.2f,0.3f, dwF,D3DCOLOR_XRGB(255,0,255));
g_pVB4->Unlock();
return true;
}
void RenderScene()
{
DWORD DDXCLEAR =D3DCLEAR_TARGET|D3DCLEAR_STENCIL|D3DCLEAR_ZBUFFER;
g_pDevice->Clear(0,NULL,DDXCLEAR,D3DCOLOR_XRGB(255,255,255),1.0f,0);
g_pDevice->BeginScene();
g_pDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
D3DXMATRIX matWorld;
D3DXMatrixIdentity(&matWorld);
g_pDevice->SetTransform(D3DTS_WORLD,&matWorld);
g_pDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE,FALSE );
g_pDevice->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_0WEIGHTS );
HRESULT hr;
hr =g_pDevice->SetStreamSource(0,g_pVB,0,sizeof(GridVertex));
g_pDevice->SetFVF(D3DFVF_GRID);
g_pDevice->DrawPrimitive(D3DPT_LINELIST,0,402);
//g_pDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,268);
D3DXVECTOR3 vv1 =D3DXVECTOR3(10.0f,0.0f,0.0f);
D3DXVECTOR3 vv2 =D3DXVECTOR3(0.0f,10.0f,0.0f);
D3DXVECTOR3 vv3 =D3DXVECTOR3(8.0f,8.0f,0.0f);
D3DXMATRIX mm1,mm2,mm3;
D3DXMatrixTranslation(&mm1,vv1.x,vv1.y,vv1.z);
D3DXMatrixTranslation(&mm2,vv2.x,vv2.y,vv2.z);
D3DXMatrixTranslation(&mm3,vv3.x,vv3.y,vv3.z);
/*g_pDevice->SetTransform(D3DTS_WORLDMATRIX(0),&mm1);
g_pDevice->SetTransform(D3DTS_WORLDMATRIX(1),&mm2);
g_pDevice->SetTransform(D3DTS_WORLDMATRIX(2),&mm3);*/
g_pDevice->SetTransform(D3DTS_WORLDMATRIX(1),&mm1);
g_pDevice->SetTransform(D3DTS_WORLDMATRIX(3),&mm2);
g_pDevice->SetTransform(D3DTS_WORLDMATRIX(7),&mm3);
g_pDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE,TRUE );
g_pDevice->SetRenderState(D3DRS_VERTEXBLEND,D3DVBF_2WEIGHTS );
//顏色和位置是理想的
/*hr =g_pDevice->SetStreamSource(0,g_pVB1,0,sizeof(BoneVertex1));
g_pDevice->SetFVF(D3DFVF_BONE1);
g_pDevice->DrawPrimitive(D3DPT_LINELIST,0,1);*/
//位置正常,顏色不是理想的
/*hr = g_pDevice->SetStreamSource(0,g_pVB2,0,sizeof(BoneVertex2));
g_pDevice->SetFVF(D3DFVF_BONE2);
g_pDevice->DrawPrimitive(D3DPT_LINELIST,0,1);*/
//不顯示
/*hr =g_pDevice->SetStreamSource(0,g_pVB3,0,sizeof(BoneVertex3));
hr =g_pDevice->SetFVF(D3DFVF_BONE3);
hr =g_pDevice->DrawPrimitive(D3DPT_POINTLIST,0,1);*/
//這個需要嚴格指定矩陣索引值才能正確顯示
hr =g_pDevice->SetStreamSource(0,g_pVB4,0,sizeof(BoneVertex4));
g_pDevice->SetFVF(D3DFVF_BONE4);
g_pDevice->DrawPrimitive(D3DPT_LINELIST,0,1);
g_pDevice->EndScene();
g_pDevice->Present(NULL,NULL,NULL,NULL);
}
void QuitDirectX()
{
}