directx12三维坐标系转二维坐标系

有时候需要在三维坐标系中绘制二维元素,像文字、表格等,需要使用二维坐标系,DirectX之前都说取图不精,也就是没法在整数位置画出一个对应这个整数坐标的像素,譬如我想在二维屏幕坐标(400,50)到(800,50)画出水平线,可能你画出来的线在坐标(400,49)到(800,49),或者画两条相邻像素的线,譬如垂直坐标51,结果出来就是后画的线覆盖了前面画的线,这个问题在最新版的DirectX12还一直存在,微软的工程师似乎也解决不了这个问题,因为directx的坐标范围是float类型,从[-1.0f,1.0f],这就导致了在转换为2D坐标系画文字、线等二维元素时精度误差一个像素,也就是半像素问题,不过,微软工程师本就是为游戏开发了DirectX,所以DirectX在一些工程精细作图方面还是不合适,如果你想要画精确的图元素,还是使用OpenGL吧,目前的DirectX12无法满足,跑题了,下面说说三维坐标转二维坐标系的问题,先看代码:

// 基于左上角是坐标原点 X正方向向右 Y正方向向下 与窗口坐标系相同
        // 这里的算法来自于古老的HGE引擎核心
        // Orthographic
        XMMATRIX mxOrthographic = XMMatrixScaling(1.0f, -1.0f, 1.0f); //上下翻转,配合之前的Quad的Vertex坐标一起使用
        //mxOrthographic = XMMatrixMultiply(mxOrthographic, XMMatrixTranslation(-0.5f, +0.5f, 0.0f)); //微量偏移,矫正像素位置(这行代码仍然无法矫正1像素误差,所以注释掉)
        mxOrthographic = XMMatrixMultiply(
            mxOrthographic
            , XMMatrixOrthographicOffCenterLH(stViewPort.TopLeftX
                , stViewPort.TopLeftX + stViewPort.Width
                , -(stViewPort.TopLeftY + stViewPort.Height)
                , -stViewPort.TopLeftY
                , stViewPort.MinDepth
                , stViewPort.MaxDepth)
        );
        // View * Orthographic 正交投影时,视矩阵通常是一个单位矩阵,这里之所以乘一下以表示与射影投影一致
        mxOrthographic = XMMatrixMultiply(
            XMMatrixIdentity()
            , mxOrthographic
        );

// 渲染矩形框
                // 设置矩形框的位置,即矩形左上角的坐标,注意因为正交投影的缘故,这里单位是像素
                XMMATRIX xmMVO = XMMatrixMultiply(
                    XMMatrixTranslation(0.0f, 0.0f, 0.0f)
                    , mxOrthographic);

                // 设置矩形框的大小,单位同样是像素
                xmMVO = XMMatrixMultiply(
                    XMMatrixScaling(300.0f, 300.f, 1.0f)
                    , xmMVO);

                //设置MVO
                XMStoreFloat4x4(&pMOV->m_mMVO, xmMVO);

代码应该很容易理解:

XMMatrixScaling(1.0f, -1.0f, 1.0f);是围绕X轴旋转180°,Y轴变成向下

mxOrthographic = XMMatrixMultiply(
            mxOrthographic
            , XMMatrixOrthographicOffCenterLH(stViewPort.TopLeftX
                , stViewPort.TopLeftX + stViewPort.Width
                , -(stViewPort.TopLeftY + stViewPort.Height)
                , -stViewPort.TopLeftY
                , stViewPort.MinDepth
                , stViewPort.MaxDepth)
        );就是把坐标中心移动到左上角,跟2D窗口的坐标就一致了,也是左上角是原点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值