在使用固定管道的顶点混合时候,会出现种种问题,比如:在指定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
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() { }