请教有关DX中多流的问题

xiaolizi 2003-12-08 08:04:58
这是网上一篇文档中的例子,这里拿来show一下,希望原作者见谅:

其中在函数InitVB中函数
g_pd3dDevice->CreateVertexDeclaration(shaderDecl, &g_pVertexDeclaration);
调用失败,如果把
{ 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITIONT, 0 },改成{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },就正确,这里不知道为什么使用XYZRHW的顶点格式在创建VertexDeclaration的时候会失败???



源代码如下:

//////////////////////////////
#include <d3d9.h>
#include <d3dx9.h>

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")

template <typename T>
inline void SAFE_RELEASE(T& p)
{
if (p != 0)
{
p->Release();
p = 0;
}
}

IDirect3D9* g_pD3D = NULL;
IDirect3DDevice9* g_pd3dDevice = NULL;
IDirect3DVertexBuffer9* g_pVBPos = NULL;
IDirect3DVertexBuffer9* g_pVBCol = NULL;
IDirect3DVertexDeclaration9* g_pVertexDeclaration = NULL;


void InitD3D(HWND hWnd)
{
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;

g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice);

g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

D3DXMATRIX matWorld;
D3DXMatrixIdentity(&matWorld);
g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);

D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0, 0, -3), &D3DXVECTOR3(0, 0, 0), &D3DXVECTOR3(0, 1, 0));
g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);

D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4, 1, 0.1f, 10);
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}

void InitVB()
{
D3DVERTEXELEMENT9 shaderDecl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 },
{ 1, 0, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
{ 0xFF, 0, D3DDECLTYPE_UNUSED, 0, 0, 0 },
};

g_pd3dDevice->CreateVertexDeclaration(shaderDecl, &g_pVertexDeclaration);

D3DXVECTOR4 Positions[] =
{
D3DXVECTOR4( 100, 100, 1.0f, 1.0f ),
D3DXVECTOR4( 200, 100, 1.0f, 1.0f ),
D3DXVECTOR4( 100, 200, 1.0f, 1.0f ),
};

D3DCOLOR Colors[] =
{
D3DCOLOR_XRGB(0xFF, 0, 0),
D3DCOLOR_XRGB(0, 0xFF, 0),
D3DCOLOR_XRGB(0, 0, 0xFF),
};

g_pd3dDevice->CreateVertexBuffer(3 * sizeof(D3DXVECTOR4), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &g_pVBPos, NULL);
g_pd3dDevice->CreateVertexBuffer(3 * sizeof(D3DCOLOR), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &g_pVBCol, NULL);


void* pPositions;
g_pVBPos->Lock(0, 0, &pPositions, 0);
memcpy(pPositions, Positions, sizeof(Positions));
g_pVBPos->Unlock();

void* pColor;
g_pVBCol->Lock(0, 0, &pColor, 0);
memcpy(pColor, Colors, sizeof(Colors));
g_pVBCol->Unlock();
}

void Cleanup()
{
// 释放两个流
g_pd3dDevice->SetStreamSource( 0, NULL, 0, sizeof(D3DXVECTOR4));
g_pd3dDevice->SetStreamSource( 1, NULL, 0, sizeof(D3DCOLOR));

// 删除VS
g_pVertexDeclaration->Release();

SAFE_RELEASE(g_pVBPos);
SAFE_RELEASE(g_pVBCol);

SAFE_RELEASE(g_pd3dDevice);
SAFE_RELEASE(g_pD3D);
}

void Render()
{
g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0x33, 0x66, 0x99), 1.0f, 0);

g_pd3dDevice->BeginScene();

HRESULT hr;
hr = g_pd3dDevice->SetVertexDeclaration(g_pVertexDeclaration);

hr = g_pd3dDevice->SetStreamSource( 0, g_pVBPos, 0, sizeof(D3DXVECTOR4));
hr = g_pd3dDevice->SetStreamSource( 1, g_pVBCol, 0, sizeof(D3DCOLOR));
hr = g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );

g_pd3dDevice->EndScene();

g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}

return DefWindowProc(hWnd, msg, wParam, lParam);
}

LPCTSTR wcName(TEXT("Multistream"));

INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = MsgProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));
wc.lpszMenuName = NULL;
wc.lpszClassName = wcName;
RegisterClass(&wc);

HWND hWnd(CreateWindow(wcName, wcName, WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, GetDesktopWindow(), NULL, wc.hInstance, NULL));

InitD3D(hWnd);
InitVB();

ShowWindow(hWnd, SW_SHOWDEFAULT);
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
{
Render();
}
}

Cleanup();
UnregisterClass(wcName, wc.hInstance);

return 0;
}

////////////////////////////
以下是摘自dx help文档有关D3DDECLUSAGE_POSITIONT的说明,不知道我的code中错在哪儿?:

Vertex Declarations with D3DDECLUSAGE_POSITIONT
Presence of a vertex element with (D3DUSAGE_POSITIONT, 0) is used to indicate to the device that the vertex data coming in has already been through vertex processing (like an FVF with D3DFVF_XYZRHW bit set). At Draw time, if the currently set declaration has an element with the (D3DUSAGE_POSITIONT, 0) semantic, the entire vertex processing is skipped (just as if an FVF with D3DFVF_XYZRHW bit has been set).

There are some restrictions on vertex declarations with (D3DDECLUSAGE_POSITIONT, 0):

Only stream zero can be used is such declarations.
Vertex elements must be sorted by increasing stream offset.
Stream offset must be DWORD aligned.
The same (Usage, Usage Index) pair should be listed only once.
Only D3DDECLMETHOD_DEFAULT method can be used.
Other vertex elements cannot have (D3DDECLUSAGE_POSITION, 0) semantic.
In addition, there are some restrictions on such declaration, related to the device driver version. These restrictions are in effect because Direct3D sends such declarations directly to the driver without doing any conversion.

...全文
60 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaolizi 2003-12-10
  • 打赏
  • 举报
回复
To P_hantom(Phantom)
以下是dx文档对D3DDECLUSAGE_POSITIONT的说明,按照这个说明应该是正确的

D3DDECLUSAGE_POSITIONT
Vertex data contains transformed position data. (D3DDECLUSAGE_POSITIONT with UsageIndex = 0) specifies transformed position. When a declaration containing this is set, the pipeline does not perform vertex processing.

你上面提到的“至于 D3DDECLTYPE_FLOAT4 这个问题,要看看除了 Position 以外的几个声明,看看他们的占字节大小和起始位置是不是正确,有可能抱错不是 Position ,而是在别的地方。”这个就不太明白了,能否具体点?

IONPhantom 2003-12-10
  • 打赏
  • 举报
回复
D3DDECLUSAGE_POSITIONT 表示这几个字节的用法是 Position,是用来和 VertexShader 连接的声明。至于 D3DDECLTYPE_FLOAT4 这个问题,要看看除了 Position 以外的几个声明,看看他们的占字节大小和起始位置是不是正确,有可能抱错不是 Position ,而是在别的地方。
xiaolizi 2003-12-09
  • 打赏
  • 举报
回复
To pzh508(小猪)

"而CreateVertexDeclaration函数的顶点是没有经过T&L变换的顶点,所以会失败"
这个dx文档上好像没有说明阿,另外如果说CreateVertexDeclaration不支持经过TL转换的顶点,又为何还有D3DDECLUSAGE_POSITIONT的用法呢?
pzh508 2003-12-09
  • 打赏
  • 举报
回复
XYZRHW的顶点格式表示已经经过变换处理的顶点(即T&L变换),而CreateVertexDeclaration函数的顶点是没有经过T&L变换的顶点,所以会失败

8,304

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧