• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            DirectX 9的坐標系統變換

             

            世界坐標系到攝影坐標系的變換

            攝影坐標系的原點為世界坐標系中的觀察位置eye點,z軸與觀察方向(從eye點出發到at點的向量)一致。
            由于僅由一個坐標原點的位置和一個z坐標軸的方向不足以完全確定一個坐標系,因此,還需要指定一個up向量來定位攝影坐標系的y軸方向。這個在世界坐標系中給出的up向量是不必與觀察方向垂直的,只是指明攝影坐標系應該以向上的方向還是以向下的方向作為y軸。

            Builds a left-handed, look-at matrix.

            D3DXMATRIX * D3DXMatrixLookAtLH(
            D3DXMATRIX * pOut,
            CONST D3DXVECTOR3 * pEye,
            CONST D3DXVECTOR3 * pAt,
            CONST D3DXVECTOR3 * pUp
            );

            Parameters

            pOut
            [in, out] Pointer to the D3DXMATRIX structure that is the result of the operation.
            pEye
            [in] Pointer to the D3DXVECTOR3 structure that defines the eye point. This value is used in translation.
            pAt
            [in] Pointer to the D3DXVECTOR3 structure that defines the camera look-at target.
            pUp
            [in] Pointer to the D3DXVECTOR3 structure that defines the current world's up, usually [0, 1, 0].

            Return Values

            Pointer to a D3DXMATRIX structure that is a left-handed, look-at matrix.

            Remarks

            The return value for this function is the same value returned in the pOut parameter. In this way, the D3DXMatrixLookAtLH function can be used as a parameter for another function.

            This function uses the following formula to compute the returned matrix.

            zaxis = normal(At - Eye)
            xaxis = normal(cross(Up, zaxis))
            yaxis = cross(zaxis, xaxis)

            xaxis.x yaxis.x zaxis.x 0
            xaxis.y yaxis.y zaxis.y 0
            xaxis.z yaxis.z zaxis.z 0
            -dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1


            要正確運行以下的示例程序,需要在工程中包含d3dx9.lib,或者在main函數前加入
            #pragma comment(lib, "d3dx9.lib")
            以指示編譯器鏈接d3dx9.lib。

            代碼示例:

            #include <d3dx9math.h>
            #include <stdio.h>

            #pragma warning(disable : 4305)

            int main()
            {
                D3DXVECTOR3 p(3.0, 3.0, 3.0);       
            // point with world coordinate
                D3DXVECTOR3 eye(1.0, 0.0, 0.0);     // camera position with world coordinate
                D3DXVECTOR3 at(0.0, 0.0, 0.0);      // look at target with world coordinate
                D3DXVECTOR3 up(0.0, 1.0, 0.0);      // define the current world's up

                D3DXMATRIX m;   
            // transform matrix from world coordinate to camera coordinate

                // Builds a left-handed, look-at matrix.
                D3DXMatrixLookAtLH(&m, &eye, &at, &up);

                
            // print out matrix
                printf("   |%f   %f    %f    %f|\n", m._11, m._12, m._13, m._14);
                printf("   |%f   %f    %f    %f|\n", m._21, m._22, m._23, m._24);
                printf("m =|%f   %f    %f    %f|\n", m._31, m._32, m._33, m._34);
                printf("   |%f   %f    %f    %f|\n", m._41, m._42, m._43, m._44);

                printf("\n\n\n");

                D3DXVec3TransformCoord(&p, &p, &m);

                printf("p(%f, %f, %f)", p.x, p.y, p.z);
                printf("\n\n\n");

                
            return 0;
            }

            輸出:

                   |0.000000   0.000000    -1.000000    0.000000|
                   |-0.000000   1.000000    0.000000    0.000000|
            m = |1.000000   0.000000    0.000000    0.000000|
                   |-0.000000   -0.000000    1.000000    1.000000|

            p(3.000000, 3.000000, -2.000000)



            透視投影變換

            為了顯示三維物體,必須將三維物體透視投影到平面上,以獲得一個二維的平面圖象,同時還要保存物體的深度信息(z軸上的位置信息)。

            Builds a left-handed perspective projection matrix based on a field of view.

            D3DXMATRIX * D3DXMatrixPerspectiveFovLH(
            D3DXMATRIX * pOut,
            FLOAT fovy,
            FLOAT Aspect,
            FLOAT zn,
            FLOAT zf
            );

            Parameters

            pOut
            [in, out] Pointer to the D3DXMATRIX structure that is the result of the operation.
            fovy
            [in] Field of view in the y direction, in radians.
            Aspect
            [in] Aspect ratio, defined as view space width divided by height.
            zn
            [in] Z-value of the near view-plane.
            zf
            [in] Z-value of the far view-plane.

            Return Values

            Pointer to a D3DXMATRIX structure that is a left-handed perspective projection matrix.

            Remarks

            The return value for this function is the same value returned in the pOut parameter. In this way, the D3DXMatrixPerspectiveFovLH function can be used as a parameter for another function.

            This function computes the returned matrix as shown:

            xScale     0          0               0
            0 yScale 0 0
            0 0 zf/(zf-zn) 1
            0 0 -zn*zf/(zf-zn) 0

            where:
            yScale = cot(fovY/2)

            xScale = yScale / aspect ratio


            視截體的平面計算

            在世界坐標系中選擇觀察者位置,并確定視角的方向和視線的遠近距離,視截體的6個側面也就決定下來,由于三維物體一開始是在世界坐標系中給出的,因此視截體在世界坐標系中的6個平面的計算就顯得相當重要,因為可由這6個視截體的平面法向量計算出世界空間中的哪些三維物體應該顯示出來。

            完全可以根據觀察者的坐標位置、觀察視角的大小和遠近平面的方位,直接計算出6個視截體平面在世界坐標系中的方程。不過,DirectX并沒有直接提供一個函數來計算這些平面的方程,但可以根據攝影變換和透視投影變換矩陣,反向計算出視截體的各個平面在世界坐標系中的方程。

            世界空間中的視截體在攝影變換和透視投影變換后,變成攝影空間中的立方體[-1, 1] x [-1, 1] x [0, 1],即6個視截體平面的方程分別為x=-1,x=1,y=-1,y=1,z=0和z=1。

            代碼示例:

            #include <d3dx9math.h>
            #include <stdio.h>

            #pragma warning(disable : 4305)

            int main()
            {
                
            // build camera reference frame
                D3DXVECTOR3 eye(0.0, 0.0, 3.0); // camera position with world coordinate
                D3DXVECTOR3 at(0.0, 0.0, 30.0); // look at target with world coordinate
                D3DXVECTOR3 up(0.0, 1.0, 3.0);  // define the current world's up

                D3DXMATRIX view_matrix; 
            // transform matrix from world coordinate to camera coordinate

                // Builds a left-handed, look-at matrix.
                D3DXMatrixLookAtLH(&view_matrix, &eye, &at, &up);

                D3DXMATRIX proj_matrix;
                
            // Builds a left-handed perspective projection matrix based on a field of view.
                D3DXMatrixPerspectiveFovLH(&proj_matrix, D3DX_PI/3, 2.0, 2.0, 8.0);

                printf("calculate frustum plane equation in world reference frame:\n\n");

                D3DXMATRIX M = view_matrix * proj_matrix;

                D3DXPLANE plane[6];

                plane[0].a = M._11 + M._14;
                plane[0].b = M._21 + M._24;
                plane[0].c = M._31 + M._34;
                plane[0].d = M._41 + M._44;

                D3DXPlaneNormalize(&plane[0], &plane[0]);
                printf("left plane equation: a=%f, b=%f, c=%f, d=%f\n\n", plane[0].a, plane[0].b, plane[0].c, plane[0].d);

                plane[1].a = M._14 - M._11;
                plane[1].b = M._24 - M._21;
                plane[1].c = M._34 - M._31;
                plane[1].d = M._44 - M._41; 

                D3DXPlaneNormalize(&plane[1], &plane[1]);
                printf("right plane equation: a=%f, b=%f, c=%f, d=%f\n\n", plane[1].a, plane[1].b, plane[1].c, plane[1].d);

                plane[2].a = M._14 - M._12;
                plane[2].b = M._24 - M._22;
                plane[2].c = M._34 - M._32;
                plane[2].d = M._44 - M._42;

                D3DXPlaneNormalize(&plane[2], &plane[2]);
                printf("top plane equation: a=%f, b=%f, c=%f, d=%f\n\n", plane[2].a, plane[2].b, plane[2].c, plane[2].d);

                plane[3].a = M._12 + M._14;
                plane[3].b = M._22 + M._24;
                plane[3].c = M._32 + M._34;
                plane[3].d = M._42 + M._44;

                D3DXPlaneNormalize(&plane[3], &plane[3]);
                printf("bottom plane equation: a=%f, b=%f, c=%f, d=%f\n\n", plane[3].a, plane[3].b, plane[3].c, plane[3].d);

                plane[4].a = M._13;
                plane[4].b = M._23;
                plane[4].c = M._33;
                plane[4].d = M._43;

                D3DXPlaneNormalize(&plane[4], &plane[4]);
                printf("near plane equation: a=%f, b=%f, c=%f, d=%f\n\n", plane[4].a, plane[4].b, plane[4].c, plane[4].d);

                plane[5].a = M._14 - M._13;
                plane[5].b = M._24 - M._23;
                plane[5].c = M._34 - M._33;
                plane[5].d = M._44 - M._43;

                D3DXPlaneNormalize(&plane[5], &plane[5]);
                printf("far plane equation: a=%f, b=%f, c=%f, d=%f\n\n\n\n", plane[5].a, plane[5].b, plane[5].c, plane[5].d);

                
            return 0;
            }

            輸出:

            calculate frustum plane equation in world reference frame:

            left plane equation: a=0.654654, b=0.000000, c=0.755929, d=-2.267787

            right plane equation: a=-0.654654, b=0.000000, c=0.755929, d=-2.267787

            top plane equation: a=0.000000, b=-0.866025, c=0.500000, d=-1.500000

            bottom plane equation: a=0.000000, b=0.866025, c=0.500000, d=-1.500000

            near plane equation: a=0.000000, b=0.000000, c=1.000000, d=-5.000000

            far plane equation: a=0.000000, b=0.000000, c=-1.000000, d=11.000000

            透視投影空間到屏幕視口的變換

            視截體透視投影到[-1, -1] x [-1, 1] x [0, 1]立方體后,就需要將xy平面中的二維圖像變換到計算機的屏幕視口中進行顯示,同時還將z軸[0, 1]變換為[min_z, max_z],這就是透視投影空間到視口的坐標變換。對于DirectX來說,通常取min_z = 0和max_z = 1,即維持z軸的坐標值不變。

            在三維游戲開發中,一般使用D3DVIEWPORT9結構體和 IDirect3DDevice9::SetViewport Method設置視口的區域。

            posted on 2008-04-16 09:45 RedLight 閱讀(668) 評論(0)  編輯 收藏 引用 所屬分類: 3D渲染技術

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            導航

            統計

            公告


            Name: Galen
            QQ: 88104725

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            相冊

            My Friend

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            国产精品久久久久久一区二区三区| 久久无码AV中文出轨人妻| 99久久精品免费看国产一区二区三区| 日韩精品无码久久一区二区三| 久久国产亚洲精品| 囯产极品美女高潮无套久久久| 国产Av激情久久无码天堂| 国产午夜电影久久| 少妇高潮惨叫久久久久久| 国产精品99久久不卡| 日韩精品久久久肉伦网站| 久久se精品一区二区影院 | 久久亚洲AV成人无码软件| 99久久精品国内| 免费精品久久天干天干| 亚洲国产成人久久精品影视| 国产69精品久久久久9999APGF| 久久99精品久久久久久水蜜桃| 久久国产亚洲精品无码| 人妻无码精品久久亚瑟影视| 超级碰久久免费公开视频| 国产三级久久久精品麻豆三级| 婷婷久久精品国产| 久久精品中文字幕第23页| 久久精品国产精品国产精品污| 久久久婷婷五月亚洲97号色| 久久久无码精品亚洲日韩蜜臀浪潮| 久久e热在这里只有国产中文精品99| 国产精品久久久久影院色| 久久亚洲AV成人出白浆无码国产| 欧美亚洲国产精品久久| 亚洲精品乱码久久久久久中文字幕| 久久综合久久性久99毛片| 久久国产香蕉一区精品| 久久久久久A亚洲欧洲AV冫| 精品久久久久久无码中文字幕 | 亚洲国产精品无码成人片久久| 一级做a爰片久久毛片免费陪 | 精品国产婷婷久久久| 久久精品国产99久久丝袜| 激情五月综合综合久久69|