我想为 DirectX 程序编写一个非常简单的效果,该程序使用 ID3DXSprite 界面绘制 2D-Hud 即可。在XNA中,我只是打电话给
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);
effect.Begin();
effect.CurrentTechnique.Passes[0].Begin();
spriteBatch.Draw(texture, new Rectangle(0, 0, 300, 300), Color.White);
effect.CurrentTechnique.Passes[0].End();
effect.End();
spriteBatch.End();
但是在C ++中,几乎相同的代码不起作用
pSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_DONOTSAVESTATE | D3DXSPRITE_SORT_TEXTURE);
anEffect->SetTechnique(technique);
anEffect->Begin(&passes, 0);
anEffect->BeginPass(0);
pSprite->Draw(pTexture, NULL, NULL, &position, 0xFFFFFFFF);
anEffect->EndPass();
anEffect->End();
pSprite->End();
注意:效果已正确加载!
答案 0 :(得分:1)
好吧,首先你拥有的XNA代码是针对XNA 3.1,而且它是错误的。 This blog post解释了如何为XNA 3.1和4.0(其间的API changes)执行此操作。
在XNA 3.1中,使用SpriteSortMode.Immediate
时,SpriteBatch
会在Begin
来电中设置其着色器和其他设备状态,而不是End
来电。这使您有机会在实际绘制之前替换部分设备状态(在Draw
或End
中,具体取决于它何时刷新)。然后你应该End
你的效果 你End
精灵批次(所以一切都先被绘制)。
现在,在DirectX中,我建议您End
来电的错误顺序是错误的。具体请参考documentation的此部分,以获取ID3DXEffect::Begin
确定是否保存并恢复了效果修改的状态。默认值0指定ID3DXEffect :: Begin和ID3DXEffect :: End将保存并恢复效果修改的所有状态
结果是,当您End
效果时,它会在您End
上调用ID3DXSprite
之前将设备重置为正常的精灵绘图,这实际上就是发送您的精灵批处理。
我猜你错误排序的代码在XNA上工作的原因是XNA可能在启动效果时相当于传递D3DXFX_DONOTSAVESTATE
。
答案 1 :(得分:-1)
使用具有HLSL效果的Sprite :(对于C ++游戏开发者)
以下示例代码说明了精灵绘制如何与HLSL效果文件一起使用
伪代码:
ID3DXEffect* g_pEffect = NULL; // D3DX effect interface
void loadTextureEffect() {
D3DXCreateTextureFromFile(gD3dDevice,L"image.png",&gTextureBackdrop);
DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE;
D3DXCreateEffectFromFile( gD3dDevice, "shader.fx", NULL, NULL, dwShaderFlags,
NULL, &g_pEffect, NULL );
}
void Render()
{
unsigned int passes;
gD3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
gD3dDevice->BeginScene();
gSprite->Begin(0);
g_pEffect->SetTechnique("PostProcess");
g_pEffect->SetTexture( "Tex0", gTextureBackdrop );
float blurFactor = 25;
g_pEffect->SetValue("TextureBlur",&blurFactor ,sizeof(float));
g_pEffect->Begin(&passes, 0);
for(unsigned int pass = 0; pass < passes; ++pass)
{
g_pEffect->BeginPass(pass);
D3DXVECTOR3 spritePos(0.0f, 0.0f, 0.0f);
gD3dDevice->SetTexture(0,gTextureBackdrop);
gSprite->Draw(gTextureBackdrop, 0, 0, &spritePos, 0xffffffff);
gSprite->End();
g_pEffect->CommitChanges();
g_pEffect->EndPass();
}
g_pEffect->End();
gD3dDevice->EndScene();
gD3dDevice->Present(NULL,NULL,NULL,NULL);
}