DirectX:如何将效果应用于使用ID3DXSprite.Draw(...)绘制的纹理

时间:2011-04-30 12:03:25

标签: xna directx shader effect

我想为 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();

注意:效果已正确加载!

2 个答案:

答案 0 :(得分:1)

好吧,首先你拥有的XNA代码是针对XNA 3.1,而且它是错误的This blog post解释了如何为XNA 3.1和4.0(其间的API changes)执行此操作。

在XNA 3.1中,使用SpriteSortMode.Immediate时,SpriteBatch会在Begin来电中设置其着色器和其他设备状态,而不是End来电。这使您有机会在实际绘制之前替换部分设备状态(在DrawEnd中,具体取决于它何时刷新)。然后你应该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);
}