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

发布于 2024-11-04 09:26:02 字数 955 浏览 6 评论 0原文

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

注意:效果已正确加载!

I want to write a very simple Effect for a DirectX program which uses the ID3DXSprite interface to draw a 2D-Hud. In XNA I simply called

        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();

But in C++, nearly the same code doesnt work

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();

NOTE: The effect is loaded correctly!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最美不过初阳 2024-11-11 09:26:02

好吧,首先,您拥有的 XNA 代码适用于 XNA 3.1,并且它是错误的这篇博文解释了如何为 XNA 3.1 和 4.0 执行此操作(API 更改)。

在 XNA 3.1 中,当使用 SpriteSortMode.Immediate 时,SpriteBatch 将在 Begin 调用中设置其着色器和其他设备状态,而不是在结束通话。这使您有机会在实际绘制之前替换部分设备状态(在 DrawEnd 中,具体取决于它何时刷新)。然后你应该结束你的效果结束精灵批次(所以所有东西都会先绘制) 。

现在,在 DirectX 中,我认为 End 调用的相同错误顺序也是罪魁祸首。具体请参阅文档的这一部分对于 ID3DXEffect::Begin 的第二个参数

确定是否保存并恢复由效果修改的状态。默认值0指定ID3DXEffect::Begin和ID3DXEffect::End将保存和恢复该效果修改的所有状态

结果是,当您End效果时,会将设备重置回正常的精灵绘制,在对 ID3DXSprite 调用 End 之前,这实际上是发送要绘制的精灵批次。

我猜想,您的错误排序代码在 XNA 上运行的原因是,当开始效果时,XNA 可能会在后台执行相当于传递 D3DXFX_DONOTSAVESTATE 的操作。

Well, first of all the XNA code you have is for XNA 3.1, and it's wrong. This blog post explains how to do it for both XNA 3.1 and 4.0 (the API changes in between).

In XNA 3.1, when using SpriteSortMode.Immediate, SpriteBatch will set up its shaders and other device state in the Begin call, instead of in the End call. This gives you the opportunity to replace parts of the device state before drawing actually takes place (in Draw or End, depending on when it flushes). And then you are supposed to End your effect after you End the sprite batch (so everything gets drawn first).

Now, in DirectX, I would suggest that the same incorrect ordering of your End calls is to blame. Specifically refer to this part of the documentation for the second parameter to ID3DXEffect::Begin

determines if state modified by an effect is saved and restored. The default value 0 specifies that ID3DXEffect::Begin and ID3DXEffect::End will save and restore all state modified by the effect

The upshot is that, when you End the effect, it is resetting the device back to normal sprite drawing, before you call End on the ID3DXSprite, which is what is actually sending your sprite batch to be drawn.

I would guess that the reason your incorrectly-ordered code works on XNA is that XNA is probably doing the equivalent of passing D3DXFX_DONOTSAVESTATE, when beginning the effect, under the hood.

为人所爱 2024-11-11 09:26:02

Sprite 与 HLSL 效果的使用:(适用于 C++ 游戏开发人员)

下面是示例代码,解释了 sprite 绘制如何与 HLSL 效果文件一起使用

伪代码:< /em>

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);
}

Usage of Sprite with HLSL Effect: (for C++ Game Developers)

Below is the sample code which explains how sprite draw can work with HLSL effect files

Pseudo Code:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文