Search code examples
c#xnaprojectionorthogonal

XNA: Orthographic Projection that matches Screen Coordinates


I am using XNA with SpriteBatch and custom drawn verticies in parallel. The goal is to have the same coordinate system for both techniques. That means I need a projection matrix that maps to screen coordinates: (0, 0) is in the top left screen corner, while width and height are determined by the screen resolution.

Matrix.CreateOrthographicOffCenter(0, width, 0, height, -1, 1);

Works well but has the center in the bottom-left corner.

Matrix.CreateOrthographicOffCenter(0, width, height, 0, -1, 1);

Does not display anything at all.

Trying to combine the first projection matrix with a translation and scaling y by -1 does not display anything at all either. Scaling by positive values works well, translation too. But as soon as I scale by a negative value I do not get any output at all.

Any ideas?

PS: For testing purpose I am drawing vertices far beyond the screen coordinates, so I would at least see something if there is some error in translation.


Solution

  • I use this code to initialize my 2D camera for drawing lines, and use a basic custom effect to draw.

        Vector2 center;
        center.X = Game.GraphicsDevice.Viewport.Width * 0.5f;
        center.Y = Game.GraphicsDevice.Viewport.Height * 0.5f;
    
        Matrix View = Matrix.CreateLookAt( new Vector3( center, 0 ), new Vector3( center, 1 ), new Vector3( 0, -1, 0 ) );
        Matrix Projection = Matrix.CreateOrthographic( center.X * 2, center.Y * 2, -0.5f, 1 );
    

    Effect

    uniform float4x4 xWorld;
    uniform float4x4 xViewProjection;
    
    void VS_Basico(in float4 inPos : POSITION,  in float4 inColor: COLOR0,  out float4      outPos: POSITION,    out float4 outColor:COLOR0 )
    {
        float4 tmp = mul (inPos, xWorld);
        outPos = mul (tmp, xViewProjection);
        outColor = inColor; 
    }
    
    technique Lines
    {
        pass Pass0
        {   
            VertexShader = compile vs_2_0 VS_Basico();
            FILLMODE = SOLID;
            CULLMODE = NONE;        
        }  
    }