c++ - DirectX 转换不工作

标签 c++ matrix directx

我刚刚开始我的 directx c++ 教程,我终于画了三角形,但是每当我尝试通过任何矩阵对其进行转换时,尽管我一步一步地按照教程进行操作并且我还在 MSDN 教程中查找它,但它永远不会奏效,但我没有弄清楚问题所在,这是完整的代码:

主要.cpp:

        #include <windows.h>
        #include <d3d9.h>
        #include <d3dx9.h>
        #include "define.h"

        LRESULT WINAPI WndProc( HWND, UINT, WPARAM, LPARAM );

        int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow )
        {

                HICON icon;
                icon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_APP_ICON));

                WNDCLASS wc;
                wc.cbClsExtra = 0;
                wc.cbWndExtra = 0;
                wc.hbrBackground = (HBRUSH)NULL;
                wc.hCursor = LoadCursor(hInst, IDC_ARROW);
                wc.hIcon = icon;
                wc.hInstance = hInst;
                wc.lpfnWndProc = WndProc;
                wc.lpszClassName = "Window Class";
                wc.lpszMenuName = NULL;
                wc.style = CS_VREDRAW | CS_HREDRAW;

                RegisterClass( &wc );

                HWND hWnd = CreateWindow("Window Class", "D3D Tutorial 01: CreateDevice",
                                       WS_OVERLAPPEDWINDOW, 0, 0, 1440, 900,
                                      NULL, NULL, hInst, NULL );


                ShowWindow( hWnd, SW_NORMAL);
                initD3D(hWnd);
                initGraphics();
                Render();

                MSG msg;
          // Check to see if any messages are waiting in the queue

                while(GetMessage(&msg, NULL, 0, 0))
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }

                return 0;
        }

        LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
        {
            switch( msg )
            {

                case WM_KEYDOWN:
                    {
                        if(wParam == 0x51)
                            PostQuitMessage(1);
                            return 0;
                            break;
                    }

                case WM_DESTROY:
                    {
                    PostQuitMessage(0);
                    clearD3D();
                    return 1;
                    break;
                    }

            default:
            {
                return DefWindowProc( hWnd, msg, wParam, lParam );
            }
        }
        }

        void initD3D(HWND hwnd)
        {

        d3d = Direct3DCreate9(D3D_SDK_VERSION);

        D3DPRESENT_PARAMETERS d3dparams;

        ZeroMemory(&d3dparams, sizeof(D3DPRESENT_PARAMETERS));
        d3dparams.hDeviceWindow = hwnd;
        d3dparams.Windowed = FALSE;
        d3dparams.BackBufferFormat = D3DFMT_A8R8G8B8;
        d3dparams.BackBufferHeight = 900;
        d3dparams.BackBufferWidth = 1440;
        d3dparams.SwapEffect = D3DSWAPEFFECT_FLIP;

        d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_NOWINDOWCHANGES, &d3dparams, &d3ddevice);

        d3ddevice->SetRenderState(D3DRS_LIGHTING, FALSE);

        }

        void Render()
        {

            // clear the window to a deep blue
            d3ddevice->Clear(NULL, 0, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 20, 40, 100), 1.0f, 0);

            d3ddevice->BeginScene();    // begins the 3D scene

            // do 3D rendering on the back buffer here

            d3ddevice->SetFVF(FVFcode);

            D3DXMatrixIdentity(&matrix);
            D3DXMatrixTranslation(&matrix, 900, 0, 0);
            d3ddevice->SetTransform(D3DTS_WORLD, &matrix);

            D3DXMATRIX out;
            D3DXVECTOR3 eye(2,3,3);
            D3DXVECTOR3 Lat(0,0,0);
            D3DXVECTOR3 up(0,1,0);
            D3DXMatrixLookAtLH(&out, &eye, &Lat, &up);

            d3ddevice->SetTransform(D3DTS_VIEW, &out);

            D3DXMATRIX pro;

            D3DXMatrixPerspectiveFovLH(&pro,
                                       D3DXToRadian(45),    // the horizontal field of view
                                       (FLOAT)1440 / (FLOAT)900, // aspect ratio
                                       1.0f,    // the near view-plane
                                       100.0f);    // the far view-plane

            d3ddevice->SetTransform(D3DTS_PROJECTION, &pro);


            d3ddevice->SetStreamSource(0, v_buffer, 0, sizeof(vertex));
            d3ddevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);


            d3ddevice->EndScene();    // ends the 3D scene

            d3ddevice->Present(NULL, NULL, NULL, NULL);   // displays the created frame on the screen
        }

        void initGraphics()
        {

        vertex v [] =
            {{320.0f, 50.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255)},
            {520.0f, 400.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0)},
            {120.0f, 400.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0)},
        };
        d3ddevice->CreateVertexBuffer( 3*sizeof(vertex), 0, FVFcode, D3DPOOL_DEFAULT, &v_buffer, NULL );

        VOID* pVoid;
        v_buffer->Lock(0, 0, (void**)&pVoid, 0);
        CopyMemory(pVoid, v, sizeof(v));
        v_buffer->Unlock();

        }

定义.h:

        #ifndef DEFINE_H_INCLUDED
        #define DEFINE_H_INCLUDED

        #define     IDI_APP_ICON    1
        #define     FVFcode         (D3DFVF_DIFFUSE | D3DFVF_XYZRHW)

        //all the declarations and prototypes:

        //Dx functions:

        void initD3D (HWND);
        void clearD3D (void);
        void Render(void);
        void initGraphics(void);

        //constants:

        LPDIRECT3D9 d3d;
        D3DXMATRIX matrix;
        LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
        LPDIRECT3DDEVICE9 d3ddevice;




        //Vertices Structure:

        struct vertex
        {

        float x, y,z, rhw;
        DWORD color;

        };


        void clearD3D ()
        {

        d3d->Release();
        d3ddevice->Release();
        v_buffer->Release();

        }


        #endif // DEFINE_H_INCLUDED

我只有另一个资源文件,我刚刚在其中导入了应用程序图标,我知道代码很长,需要花时间阅读,但很抱歉我找不到任何其他解决方案。我还有一个问题,我是否必须设置三个矩阵,世界 View 和投影,才能产生像使用世界矩阵改变三角形位置的效果,我是否必须设置其他两个矩阵,改变它或只有世界??最后,非常感谢任何回复者,感谢他付出的努力和时间。


编辑

整个代码中与转换相关的部分/部分 - 因为它太长了 - 是:

        d3ddevice->BeginScene();    // begins the 3D scene

        // do 3D rendering on the back buffer here

        d3ddevice->SetFVF(FVFcode);

        D3DXMATRIX matrix;
        D3DXMatrixIdentity(&matrix);
        D3DXMatrixTranslation(&matrix, 900, 0, 0);
        d3ddevice->SetTransform(D3DTS_WORLD, &matrix);

        D3DXMATRIX out;
        D3DXVECTOR3 eye(2,3,3);
        D3DXVECTOR3 Lat(0,0,0);
        D3DXVECTOR3 up(0,1,0);
        D3DXMatrixLookAtLH(&out, &eye, &Lat, &up);

        d3ddevice->SetTransform(D3DTS_VIEW, &out);

        D3DXMATRIX pro;

        D3DXMatrixPerspectiveFovLH(&pro,
                                   D3DXToRadian(45),    // the horizontal field of view
                                   (FLOAT)1440 / (FLOAT)900, // aspect ratio
                                   1.0f,    // the near view-plane
                                   100.0f);    // the far view-plane

        d3ddevice->SetTransform(D3DTS_PROJECTION, &pro);


        d3ddevice->SetStreamSource(0, v_buffer, 0, sizeof(vertex));
        d3ddevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);


        d3ddevice->EndScene();    // ends the 3D scene

最佳答案

所以让我们从基础开始:

世界矩阵

在这里定义

D3DXMATRIX matrix;
D3DXMatrixIdentity(&matrix);
D3DXMatrixTranslation(&matrix, 900, 0, 0);
d3ddevice->SetTransform(D3DTS_WORLD, &matrix);

这个矩阵定义了顶点从原点开始的变换。在这种情况下,您将顶点平移 900 个单位到正 X 轴。也就是说,如果您将它的位置呈现为 (0,0,0),它实际上将位于 (900,0,0)。

当您需要高效地转换静态网格时会使用此矩阵,因此您不必弄乱顶点缓冲区,只需使用单个矩阵,这样效率更高。这是您应该查看的矩阵,以便平移、旋转和倾斜。

View 矩阵

在这里定义:

D3DXMATRIX out;
D3DXVECTOR3 eye(2,3,3);
D3DXVECTOR3 Lat(0,0,0);
D3DXVECTOR3 up(0,1,0);
D3DXMatrixLookAtLH(&out, &eye, &Lat, &up);

d3ddevice->SetTransform(D3DTS_VIEW, &out);

这个矩阵定义了为了将顶点从世界空间转换到 View 空间而发生的转换。即顶点相对于相机的位置。如果您只想旋转或平移相机,那么您应该在此处进行更改。

投影矩阵

D3DXMATRIX pro;

D3DXMatrixPerspectiveFovLH(&pro,
                           D3DXToRadian(45),    // the horizontal field of view
                           (FLOAT)1440 / (FLOAT)900, // aspect ratio
                           1.0f,    // the near view-plane
                           100.0f);    // the far view-plane

d3ddevice->SetTransform(D3DTS_PROJECTION, &pro);

这个矩阵定义了顶点如何投影到屏幕空间。看这张图片:

Projection Matrix

将不会显示比近景平面更靠近相机或比远景平面更远的物体。在图像中,绿色球体不会显示,因为它在边界之外。

实践中的 FOV 角度意味着“缩放”(不完全是,但您可以这样想)。

当你需要一些工件时,这个矩阵会改变,比如缩放,PIP等等。

在您的情况下,您似乎只想更改世界矩阵。一个好的开始是使用 D3DXMatrixTransformation功能。

关于c++ - DirectX 转换不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23937619/

相关文章:

python - 如何使用 boost 元组返回两个 vector

android - 如何修复 CameraX 旋转支持

c++ - 如何在 Visual Studio 2013 中重新编译 .lib

c++ - 计算具有旋转前位置和旋转角度的点的绝对位置

c++ - DevIL 图像无法正确呈现

c++ - 如何从 C Microsoft PC 应用程序向 iPhone 发送 APNS 推送通知?

c++ - 关于构造函数中数据成员数组的大括号初始化的问题?

.net - Windows 放大 API、.NET 和矩阵

r - 将相同顺序的矩阵列表转换为数组

c++ - for 循环不能正常工作