D3D顶点混合时FVF的一些问题以及对微软的一些批评

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

}
时间: 2024-10-13 12:02:40

D3D顶点混合时FVF的一些问题以及对微软的一些批评的相关文章

D3D 9 通过 Alpha 测试与 Alpha 混合随意控制纹理透明度

网上不怎么见得到关于 D3D 9 的技术文章了,笔者最近在写一个 2D 的功能,希望通过某些设置来随意控制一张 2D 纹理贴图的透明度,网上找来找去,所有的文章,要不就是照抄市面教材,要么是照抄官方文档,稍微好一点的,就是在官方教材的基础上增加中文翻译,哎哟我去,找了两天啊,功能是实现了,可是心中的疑惑一直挥之不去,为啥 ?因为我的代码是照抄的啊,我只知道这样子设置可以得到这样子的效果,但是我特么不知道为啥啊,我特么要是下次再遇到同样的问题,我是不是又要再去抄一次代码 ? 好了,牢骚就发到这里吧

获取Ogre或D3D的渲染结果的效率问题

在Ogre中获取渲染结果可以使用RenderTarget的copyContentsToMemory方法, 例: char* src = new char[mWindow->getWidth() * mWindow->getHeight() * 4]; Ogre::PixelBox* pixbox = new Ogre::PixelBox(mWindow->getWidth(), mWindow->getHeight(), 1, Ogre::PF_X8R8G8B8, src );mW

Windows内核编程时的习惯与注意事项

Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html 一.内核编程注意细节: 在头文件中使用的是 <ntddk.h>,而非普通的 <windows.h>. 在应用层编程时,在内核编程时,要使用自己的WDK文档.https://docs.microsoft.com/zh-cn/windows-hardware/drivers/?redirectedfrom=MSDN 二.获取未公开API的方法: 特征码搜

工作机会少有时反而是一件好事

经常听到这种言论: 某某技术工作机会少, 只有另一种技术工作机会的几分之一. 然而再多的工作机会, 你也只能做一份工作啊. 工作机会少有时反而是一件好事. 以微软dynamics和自然语言处理NLP为例. 微软dynamics工作机会很少, 然而薪水和级别都不菲. 所以虽然工作机会少, 但是再多的工作机会你也只能做一份工作啊, 也只能拿一份薪水啊, 所以只要这份工作的薪水和级别高就可以了啊. 自然语言处理NLP是我接触这么多技术中工作机会最少的, 但是却是我觉得最好的工作: NLP圈子以邮件为主

【转载】深入理解Direct3D9

原文:Effulgent的<深入理解Direct3D9>整理版(转) 深入理解Direct3D9 深入理解D3D9对图形程序员来说意义重大,我把以前的一些学习笔记都汇总起来,希望对朋友们有些所帮助,因为是零散笔记,思路很杂,还请包涵. 其实只要你能完美理解D3DLOCK.D3DUSAGE.D3DPOOL.LOST DEVICE.QUERY.Present().BeginScene().EndScene()等概念,就算是理解D3D9了, 不知道大家有没有同感.有如下几个问题,如果你能圆满回答就算

【转载】DXUT11框架浅析(4)--调试相关

原文:DXUT11框架浅析(4)--调试相关 DXUT11框架浅析(4)--调试相关 1. D3D8/9和D3D10/11的调试区别 只要安装了DXSDK,有个调试工具DirectX ControlPanel,如下图所示.这里可以将Direct3D 9设置为调试运行时(Debug D3D9 Runtime)或零售运行时(RetailD3D9 Runtime).注意这里的设置是全局的,如果改成调试运行时,则所有用到D3D9的程序都会进入调试模式,这会使这些程序运行的很慢. 从Vista开始系统自己

Qt中嵌入Directx11(有句柄就可以)

最近要做个游戏场景编辑器,需要directx11配合gui框架使用,所以简单地弄了一个directx11嵌入到Qt窗体中的程序. 1 建立工程 建一个Qt的工程,配置好directx的包含目录和库目录(以及附加依赖项),Qt vs2013 add-in的话很方便,直接在vs2013里面加,Qt creator的话写到pro文件里,可以选择生成对应的ui文件,或者不生成. 2 代码结构 工程的结构 D3d11RenderWidget类继承自QWidegt,用于directx11渲染 MainWid

Direct-X学习笔记--深度缓存

今天来学习一下深度测试,不过这个东东貌似暂时就是了解一下原理啦,因为DX默认是打开深度测试的,即我们不需要额外进行设置就可以使用深度测试的功能,不过这个还是有必要了解一下,一是对DX的流程更加了解,二是我们可以手动设置深度测试的参数以及函数,达到一些自己想要实现的效果. 一.简介 三维的世界中,有各种物体,而这些物体难免会有遮挡,而且同一个物体不同部分也会有遮挡的关系,要想表现出来更加逼真的效果,就要用到深度缓冲(Z buffer),配套深度测试技术. 深度缓存也尝尝成为Z缓存,D3D为屏幕上每

Qt中嵌入Directx11

最近要做个游戏场景编辑器,需要directx11配合gui框架使用,所以简单地弄了一个directx11嵌入到Qt窗体中的程序. 1 建立工程 建一个Qt的工程,配置好directx的包含目录和库目录(以及附加依赖项),Qt vs2013 add-in的话很方便,直接在vs2013里面加,Qt creator的话写到pro文件里,可以选择生成对应的ui文件,或者不生成. 2 代码结构 工程的结构 D3d11RenderWidget类继承自QWidegt,用于directx11渲染 MainWid