3

首先,我要感谢所有维护 Stack Overflow 的用户,这对每个软件开发人员来说都是一个很棒的资源。

这些天我在一个项目中使用 DirectShow + DirectX 9,我正在尝试使用 D3DXCreateText() 方法以 3D 显示文本。这个方法给了我一个网格,我可以根据需要使用世界变换轻松变换它,并使用 DrawSubset() 方法显示它:

HDC hdc = CreateCompatibleDC(NULL);
HFONT font = CreateFont(0,0,0,0,FW_NORMAL,false,false,false,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"Calibri");
SelectObject(hdc, font);

ID3DXMesh *mesh;
D3DXCreateText(d3dDevice,hdc,"Hello World",0.001f,0.0f,&mesh,NULL,NULL);

--------------------- Now inside beginScene()

...
D3DXMATRIX translation;
D3DXMATRIX scaling;
D3DXMatrixTranslation(&translation,0,0,1);
D3DXMatrixScaling(&scaling,-0.1f,0.1f,0.1f);
d3dDevice->SetTransform(D3DTS_WORLD, &(translation * scaling));

mesh->DrawSubset(0);
...

一切似乎都很好,但我有一个问题:我不知道如何将这个网格填充为简单的颜色。我已经阅读了很多示例,甚至使用了 DirectX 9 SDK 附带的 3D 文本示例(他们使用 D3DMATERIAL9 来填充它),但它不起作用。

更具体地说,如果我只在屏幕上填充此文本,它会显示为亮白色(我无法更改它的颜色,但至少它是白色的)。如果我用纹理渲染一个四边形(我用它来显示使用 DirectShow 从相机捕获的帧),那么文本显示就像它也在使用这个纹理一样!:

...
d3dDevice->SetStreamSource(0, vertexBuffer, 0, sizeof(SCREENVERTEX));
d3dDevice->SetTexture(0, texture);
// World transformations for this VertexBuffer in here
d3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
...

你能帮我解决这个问题吗?

PS:我知道有一种方法可以将 dxDrawText() 方法与 D3DXVec3Project() 一起使用来实现类似的结果,但我需要一个真实的具有深度的 3D 文本。

--------------------------------------------------任何有兴趣的人的解决方案---------------------------------------------- ----

一方面,正如@NicoSchertler 建议的那样,我应该在使用 DrawPrimitive() 函数绘制纹理后将纹理设置为空:

d3dDevice->SetTexture(0, NULL);

这仅显示文本,但即使使用 SDK 示例中显示的 SetMaterial() 方法,您也无法绘制网格。所以,@Gnietschow 用一种方法来回答它:

d3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
d3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
d3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
d3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
d3dDevice->SetTextureStageState(0, D3DTSS_CONSTANT, /* D3DCOLOR HERE */);

这行得通!但是,请记住,在再次绘制另一个纹理之前,您必须重置使用 SetTextureStageState() 方法定义的每个属性(如果您不这样做,您将保持之前为文本定义的颜色)。这是通过这个(文档)完成的:

d3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
d3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
d3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
d3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);

希望这对任何人都有帮助,再次感谢你们的帮助:)。

4

1 回答 1

1

如果您只需要一种颜色,您可以通过纹理阶段设置它(与此问题相同):

d3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
d3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
d3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CONSTANT);
d3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_CONSTANT);
d3dDevice->SetTextureStageState(0, D3DTSS_CONSTANT, /* YOUR COLOR */);

如果您需要对文本进行复杂的着色或纹理处理,则必须转换网格的 fvf 并用适当的数据填充它。D3DXCreateText( doc ) 仅创建具有位置和法线的网格,但没有任何颜色和纹理坐标。

于 2013-05-29T08:16:00.247 回答