Jump to content
  • Advertisement
Sign in to follow this  
noodleBowl

The Jump to D3D11: Orthographic projection

This topic is 2153 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to make the switch to DirectX11 and I'm having some trouble with some things. One thing that I need to be solved is how I can set up an orthographic projection?

 

My focus is on 2D and I feel like this is pretty important

 

I know from Direct X 9 you could do this and you have an Orthographic Projection

D3DXMATRIX out;
D3DXMatrixOrthoOffCenterLH(&out, 0.0f, 800.0f, 600.0f, 0.0f, 0.0f, 1.0f);
device->SetTransform(D3DTS_PROJECTION, &out);

But how is this done in DirectX11? I'm having trouble finding resources that can explain this properly

Share this post


Link to post
Share on other sites
Advertisement

Can you be clearer on what part of this you're having trouble with?  The old SetTransform calls and D3DTS_* states are gone in D3D11, but otherwise things work much the same (with the exception of cbuffers versus standalone constants) as they did with shaders in D3D9.  Have you experience using shaders in D3D9?  Are you looking for a matrix library to build the ortho matrix?  It's difficult to provide a meaningful answer without an understanding of what concepts you do or do not already know about here.

Share this post


Link to post
Share on other sites

quote

Honestly, when it comes to DirectX 11 there is not a lot I know in terms of the API.
I have never used shaders in DirectX 9, so with them being mandatory in DirectX 11 I'm not sure what to expect.

When it comes to setting up projections and other matrices I'm not even sure where to start. I definitely need a solid explanation or tutorial for setting up projections and matrix manipulation in DirectX 11

Share this post


Link to post
Share on other sites

Hi. Theres one in xna math file

There are a few functions that are part of the XNA Math library that are used to build projection matrices, . XMMatrixOrthographicOffCenterLH

there is I think a directmath header and lib for DX11.

Share this post


Link to post
Share on other sites

I would just write a shader function that does the same thing as D3DXMatrixOrthoOffCenterLH. It would take the parameters directly from a constant buffer. The formula is at the bottom of the page: http://msdn.microsoft.com/en-us/library/windows/desktop/bb205347(v=vs.85).aspx. This way you don't have to bother with matrix row/column ordering.

And for 2D, maybe an identity matrix would suffice?

Edited by tonemgub

Share this post


Link to post
Share on other sites

I would just write a shader function that does the same thing as D3DXMatrixOrthoOffCenterLH. It would take the parameters directly from a constant buffer. The formula is at the bottom of the page: http://msdn.microsoft.com/en-us/library/windows/desktop/bb205347(v=vs.85).aspx. This way you don't have to bother with matrix row/column ordering.

And for 2D, maybe an identity matrix would suffice?

What would be the motivation to do this in shaders? Projection matrix is usually the same for all objects in the scene (sometimes you need two, maybe three, but still the number is smaller than the number of objects). Even if your camera moves a lot, you need to build the proj matrix once per frame. If you move the code to a vertex shader, you will be building the matrix once per VERTEX. Once per very single vertex in your scene. Or you can also put it to a pixel shader.... ;)

Edited by Tom KQT

Share this post


Link to post
Share on other sites

You can always download the June 2012 DirectX SDK, and continue using the older deprecated D3DX matrix functions.

I haven't played with it myself, but DirectXMath looks like it is a replacement for the D3DX matrix functions, if you want to stick with something that is actively supported.

Share this post


Link to post
Share on other sites

Yes, the old D3DX matrix functions work perfectly fine with D3D11 - they're just a matrix library so there's really no dependencies on which D3D version you use them with (I've even successfully used them with OpenGL in the past).

Share this post


Link to post
Share on other sites

Just to add, you do not necessarily need an orthographic projection for 2d in DX11. You can do the transform yourself pretty easily on the CPU:

size_t Sprite::Draw(const Texture& d3dTexture, const math::Vector3& vPosition, const math::Vector3& /*vOrigin*/, const RECT& rSrcRect, const math::Vector2f& vScale, float /*fAngle*/)
{
    RECT rSrc(rSrcRect);

    const math::Vector2& vTextureSize(d3dTexture.GetSize());

    const math::Vector2 vSrcSize(rSrcRect.right - rSrcRect.left, rSrcRect.bottom - rSrcRect.top);
    const math::Vector2 vSize((int)(vSrcSize.x*vScale.x), (int)(vSrcSize.y*vScale.y));

    // calculate the sprites vertices in screen space
    // to speed up calculations, we multiply by 1.0 / screen size, which is calculated offline
    float leftVertex = vPosition.x  * m_vInvHalfScreenSize.x - 1.0f;
    float rightVertex = leftVertex + vSize.x * m_vInvHalfScreenSize.x;
    float topVertex = -vPosition.y * m_vInvHalfScreenSize.y + 1.0f;
    float bottomVertex = topVertex - vSize.y * m_vInvHalfScreenSize.y;

    const float leftCoord = rSrc.left / (float)vTextureSize.x;
    const float rightCoord = rSrc.right / (float)vTextureSize.x;
    const float topCoord = rSrc.top / (float)vTextureSize.y;
    const float bottomCoord = rSrc.bottom / (float)vTextureSize.y;

    SpriteVertex Vertices[] =
    {
        { leftVertex, topVertex, vPosition.z, leftCoord, topCoord, 1.0f, 1.0f, 1.0f, 1.0f },
        { rightVertex, topVertex, vPosition.z, rightCoord, topCoord, 1.0f, 1.0f, 1.0f, 1.0f },
        { rightVertex, bottomVertex, vPosition.z, rightCoord, bottomCoord, 1.0f, 1.0f, 1.0f, 1.0f },
        { leftVertex, bottomVertex, vPosition.z, leftCoord, bottomCoord, 1.0f, 1.0f, 1.0f, 1.0f }
    };

    SpriteVertex* pBuffer = static_cast<SpriteVertex*>(m_mapped.pData);
    memcpy(pBuffer + m_nextFreeId * 4, Vertices, sizeof(SpriteVertex)* 4);

    return m_nextFreeId++;
}

This way, the vertices are already transformed, and you can simply pass them through in your vertex shader. This example works when you draw sprites with pixel coordinates, if you have them already in relative screen space (from 0.0f to 1.0f) the conversion is even simplier. Of course it depends whether this makes sense, but depending on your programs structure, it can make things easier if you don't have to have a orthogonal matric available for every shader that eigther draws a sprite or performs a fullscreen pass.

Share this post


Link to post
Share on other sites

You have to look into cbuffers to be able to set the matrices on the pipeline however unlike in D3D9 there is no longer a Fixed Function pipeline which does transformations for VBs for you.

 

You will have to write a vertex shader to accomplish this in D3D11 and they arent that hard to write, there are enough sample out there to give you a basic tranform vertex shader and pixel shader.

 

The rastertek tutorials are a good way to get into D3D11 shaders and how the whole pipeline works: http://www.rastertek.com/tutindex.html If you want to work of familiar D3D9.c concepts use the http://www.codesampler.com/dx9src.htm D3D9 tutorials as they ease you into shader programming as well, since you know D3D9 skip to the part where they start using shaders.

Edited by NightCreature83

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!