2
\$\begingroup\$

I'm rendering a bunch of 2D content using SpriteBatches to a default XNA viewport. A simple 2D camera is used to move around the scene, which generates a transformation matrix passed to each SpriteBatch.Begin()-call.

I want to draw custom polygons on top of my SpriteBatches, which I'm doing via DrawIndexedPrimitives (straightforward, as well). I'm using a BasicEffect to shade them.

How can I best match up the SpriteBatch's implicit view and projection matrices with the BasicEffect's matrices? Currently, I create the matrices for the Effect from scratch, using the Viewport's properties. How can I get around this? Can I access the Viewport's matrices and pass them into the BasicEffect?

So far, Google has come up empty on this.

\$\endgroup\$
1
\$\begingroup\$

So there is a DirectX library called the DirectX Tool Kit which is a porting of the underlying XNA code written by people who were members of the XNA team. Below is the code relevant to you question.

SpriteBatch.cpp


PrepareForRendering()

// Set the transform matrix.
XMMATRIX transformMatrix = (mRotation == DXGI_MODE_ROTATION_UNSPECIFIED)
                           ? mTransformMatrix
                           : ( mTransformMatrix * GetViewportTransform(deviceContext, mRotation) );

mContextResources->constantBuffer.SetData(deviceContext, transformMatrix);

GetViewportTransform()

// Generates a viewport transform matrix for rendering sprites using x-right y-down screen pixel coordinates.
XMMATRIX SpriteBatch::Impl::GetViewportTransform(_In_ ID3D11DeviceContext* deviceContext, DXGI_MODE_ROTATION rotation )
{
    // Look up the current viewport.
    if ( !mSetViewport )
    {
        UINT viewportCount = 1;

        deviceContext->RSGetViewports(&viewportCount, &mViewPort);

        if (viewportCount != 1)
            throw std::exception("No viewport is set");
    }
    
    // Compute the matrix.
    float xScale = (mViewPort.Width  > 0) ? 2.0f / mViewPort.Width  : 0.0f;
    float yScale = (mViewPort.Height > 0) ? 2.0f / mViewPort.Height : 0.0f;

    switch( rotation )
    {
    case DXGI_MODE_ROTATION_ROTATE90:
        return XMMATRIX
        (
             0,       -yScale,  0,  0,
             -xScale, 0,        0,  0,
             0,       0,        1,  0,
             1,       1,        0,  1
        );

    case DXGI_MODE_ROTATION_ROTATE270:
        return XMMATRIX
        (
             0,       yScale,   0,  0,
             xScale,  0,        0,  0,
             0,       0,        1,  0,
            -1,      -1,        0,  1
        );

    case DXGI_MODE_ROTATION_ROTATE180:
        return XMMATRIX
        (
            -xScale,  0,       0,  0,
             0,       yScale,  0,  0,
             0,       0,       1,  0,
             1,      -1,       0,  1
        );

    default:
        return XMMATRIX
        (
             xScale,  0,       0,  0,
             0,      -yScale,  0,  0,
             0,       0,       1,  0,
            -1,       1,       0,  1
        );
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ DirectX Tool Kit source is available on CodePlex. \$\endgroup\$ – Chuck Walbourn Jan 13 '15 at 23:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.