DirectX: как применить эффект к текстуре, нарисованной с помощью ID3DXSprite.Draw (..) - PullRequest
0 голосов
/ 30 апреля 2011

Я хочу написать очень простой Эффект для 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 ]

1 голос
/ 30 апреля 2011

Ну, во-первых, у вас есть код XNA для XNA 3.1, и он неправильный . В этом блоге объясняется, как это сделать для XNA 3.1 и 4.0 (API меняет между).

В XNA 3.1 при использовании SpriteSortMode.Immediate, SpriteBatch будет устанавливать свои шейдеры и другое состояние устройства в вызове Begin, а не в вызове End. Это дает вам возможность заменить части состояния устройства до того, как на самом деле происходит рисование (в Draw или End, в зависимости от того, когда оно мигает). И затем вы должны End ваш эффект после вас End пакета спрайтов (так что сначала все отрисовывается).

Теперь, в DirectX, я бы предположил, что виноват тот же неправильный порядок ваших вызовов End. В частности, обратитесь к этой части документации для второго параметра ID3DXEffect::Begin

определяет, сохраняется ли состояние, измененное эффектом, и восстанавливается. Значение по умолчанию 0 указывает, что ID3DXEffect :: Begin и ID3DXEffect :: End будут сохранять и восстанавливать все состояния, измененные эффектом

В результате, когда вы End получаете эффект, он сбрасывает устройство обратно к обычному рисованию спрайтов, прежде чем вы вызовете End на ID3DXSprite, что фактически и отправляет ваш пакет спрайтов. нарисован.

Я думаю, причина того, что ваш неправильно упорядоченный код работает на XNA, в том, что XNA, вероятно, делает эквивалент передачи D3DXFX_DONOTSAVESTATE, когда начинается эффект, под капотом.

0 голосов
/ 17 октября 2013

Использование Sprite с эффектом HLSL: (для разработчиков игр 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);
}
...