SpriteBatch.Begin()

Sep 26, 2013 at 8:57 PM
So I have this XNA Snippet
basicEffect = new BasicEffect(GraphicsDevice)
{
    TextureEnabled = true,
    VertexColorEnabled = true,
};
spriteBatch.Begin(0, null, null, null, null, basicEffect);
Now that the 6th parameter of SpriteBatch.Begin() is no longer an Effect but a std::function<void()> set custom shaders

can someone explain to me show you would set this to use basicEffect?

Just learning DirectXTK any help would be greatly appreciated.

Thank you.
Coordinator
Sep 26, 2013 at 9:36 PM
Edited Sep 27, 2013 at 4:23 AM
DirectXTK's SpriteBatch creates it's own BasicEffect instance, so you do not need to pass one.

The setCustomShaders parameters is a callback so you can change the Direct3D 11 device state just before drawing. Typically this uses a 'lambda' syntax for simplicity, but it's just a function pointer.

You should check out the SimpleSample for SpriteBatch usage

Simple Sample for Windows 8
Simple Sample for Windows 8.1 Preview
Simple Sample for Win32 desktop
Simple Sample for Windows phone
Coordinator
Sep 26, 2013 at 10:02 PM
Sep 27, 2013 at 5:52 AM
Thanks so much Chuck and Shawn, my whole favorites bar across the top of my IE window is filled with links to your guys samples/blogs/pages. No lie the whole thing. You two are both and inspiration and thank you very much for all the great examples and knowledge you have provided the community. Shawn I have been staring at that exact page all day. Chuck I have the windows phone 8 and the windows 8.1 preview simple samples downloaded. That is actually what I'm working off of. I'm trying to take that and in render.cpp on the call to render I'm trying to take Shawn's "Draw sprites in 3D" with spritebatch blog/code that I believe he made for XNA and convert to work with the DirectXTK spritebatch.
auto device = m_d3dDevice.Get();
auto context = m_d3dContext.Get();

// Calucate View Matrix
XMVECTOR eye = XMVectorSet(0.0f, 0.7f, 1.5f, 0.0f);
XMVECTOR at = XMVectorSet(0.0f, -0.1f, 0.0f, 0.0f);
XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMMATRIX view = XMMatrixLookAtRH(eye, at, up);

// Setup BasicEffect
std::unique_ptr<DirectX::BasicEffect> basicEffect(new BasicEffect(device));
basicEffect->SetTextureEnabled(true);
basicEffect->SetVertexColorEnabled(true);
basicEffect->SetWorld(XMMatrixScaling(1, -1, 1) * XMMatrixTranslation(0.f, 45.f, 0.f));
basicEffect->SetView(view);
basicEffect->SetProjection(XMMatrixTranslation(-0.5f, -0.5f, 0) * XMMatrixOrthographicOffCenterRH(0, m_renderTargetSize.Width, m_renderTargetSize.Height, 0, 0, 1));

m_sprites->Begin(DirectX::SpriteSortMode_Deferred, nullptr, nullptr, nullptr, nullptr, basicEffect);
m_sprites->Draw(m_texture2.Get(), XMFLOAT2(10, 0), nullptr, Colors::White);
m_sprites->End(); 
This my poor attempt to make something that compiles, obviously it does not since basicEffect is not a function pointer or lambda expression.

Anything to get me pointed in the right direction would be great.

Thanks again!
Coordinator
Sep 27, 2013 at 6:38 AM
Edited Sep 27, 2013 at 7:24 AM
I haven't tried to compile this, but I think you want something like:

Custom Effect Initialize
ComPtr<ID3D11InputLayout> inputLayout;
std::unique_ptr<DirectX::BasicEffect> basicEffect;

// Setup BasicEffect
basicEffect.reset( new BasicEffect(device) );
basicEffect->SetTextureEnabled(true);
basicEffect->SetVertexColorEnabled(true);

// Setup InputLayout
void const* shaderByteCode;
size_t byteCodeLength;

basicEffect->GetVertexShaderBytecode(&shaderByteCode, &byteCodeLength);

device->CreateInputLayout(VertexPositionColorTexture::InputElements,
                          VertexPositionColorTexture::InputElementCount,
                          shaderByteCode, byteCodeLength,
                          inputLayout.GetAddressOf() );
Custom Effect SpriteBatch Draw
// Calculate View Matrix
static const XMVECTORF32 s_eye = { 0.0f, 0.7f, 1.5f, 0.0f };
static const XMVECTORF32 s_at = { 0.0f, -0.1f, 0.0f, 0.0f };
static const XMVECTORF32 s_up = { 0.0f, 1.0f, 0.0f, 0.0f };
XMMATRIX view = XMMatrixLookAtRH(s_eye, s_at, s_up);

// Update BasicEffect
basicEffect->SetWorld(XMMatrixScaling(1, -1, 1) * XMMatrixTranslation(0.f, 45.f, 0.f));
basicEffect->SetView(view);
basicEffect->SetProjection(XMMatrixTranslation(-0.5f, -0.5f, 0) * XMMatrixOrthographicOffCenterRH(0, m_renderTargetSize.Width, m_renderTargetSize.Height, 0, 0, 1));

// Draw with custom effect applied
m_sprites->Begin(DirectX::SpriteSortMode_Deferred, nullptr, nullptr, nullptr, nullptr, [=]
{
    basicEffect->Apply( context );
    context->IASetInputLayout( inputLayout.Get() );
});
m_sprites->Draw(m_texture2.Get(), XMFLOAT2(10, 0), nullptr, Colors::White);
m_sprites->End();
This example, however, really isn't particularly interesting because BasicEffect can't do much more than the standard sprite shader can do (there's no vertex normal in the sprite data). This custom effect thing really only makes sense if you were creating a specific vertex shader & pixel shader to apply.

In your original code above, the only difference between a standard sprite draw and your attempted use of BasicEffect is effectively providing a custom transform matrix. You don't need a custom effect instance to do that as there's another parameter for that.
static const XMVECTORF32 s_eye = { 0.0f, 0.7f, 1.5f, 0.0f };
static const XMVECTORF32 s_at = { 0.0f, -0.1f, 0.0f, 0.0f };
static const XMVECTORF32 s_up = { 0.0f, 1.0f, 0.0f, 0.0f };
XMMATRIX view = XMMatrixLookAtRH(s_eye, s_at, s_up);
XMMATRIX world = XMMatrixScaling(1, -1, 1) * XMMatrixTranslation(0.f, 45.f, 0.f));
XMMATRIX proj = XMMatrixTranslation(-0.5f, -0.5f, 0) * XMMatrixOrthographicOffCenterRH(0, m_renderTargetSize.Width, m_renderTargetSize.Height, 0, 0, 1);
XMMATRIX worldViewProj = world * view * proj;

m_sprites->Begin(DirectX::SpriteSortMode_Deferred, nullptr, nullptr, nullptr, nullptr, nullptr, worldViewProj );
m_sprites->Draw(m_texture2.Get(), XMFLOAT2(10, 0), nullptr, Colors::White);
m_sprites->End();
BTW, I've updated the SpriteBatch page with this additional information.
Marked as answer by walbourn on 1/23/2014 at 11:25 PM
Sep 30, 2013 at 6:10 PM
I will give this a try, Thank you very much for your time!