0

これに対する簡単な答えがどこかにあると確信しています。私は現在、.png 画像を頂点の長方形のテクスチャとして正しくレンダリングするプログラムを持っています。これはすべて正常に機能し、正しく表示されます。

私の質問は、別の画像を使用して画面上に 2 番目のテクスチャをレンダリングするにはどうすればよいですか? 最も簡単で最適な方法 (それらはおそらく異なることはわかっています!) 追加する 2 番目の画像は、背景画像として機能します。CUSTOMVERTEX 構造、頂点バッファー、別の頂点データ、変換マトリックス、テクスチャ ステージ設定などを複製してみました。残念ながら、私はまだテクスチャリングを学んでおり、正しいアプローチがありません。完全に別の頂点設定が必要ですか?

以下のコードは、これまでの作業コードを反映しており、頂点の四角形にオーバーレイされたテクスチャとして画像を表示しています。背景用に別のテクスチャをセットアップしてレンダリングするには、何を追加すればよいですか?

    //////////////////////////////////////////////////////
    // I N V A D E R S
    //////////////////////////////////////////////////////


    #include <Windows.h>    // Windows library (for window functions, menus, dialog boxes, etc)
    #include <d3dx9.h>      // Direct 3D library (for all Direct 3D functions).


    //-----START-----DEFINE GLOBAL ELEMENTS----------//
    LPDIRECT3D9             D3D_Object           = NULL; // Name of the Direct3D Obeject. Used to create the D3DDevice
    LPDIRECT3DDEVICE9       D3D_Device           = NULL; // Name of the rendering device
    LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer      = NULL; // Buffer to hold vertices for the rectangle
    LPDIRECT3DTEXTURE9      D3D_Tex_Background   = NULL; // The texture for the background
    LPDIRECT3DTEXTURE9      D3D_Tex_Invader      = NULL; // The texture for the invader

    float g_InvaderX = -50, g_InvaderY = 0, g_InvaderZ = 0;  // starting cooordinates of object

    // A structure for our custom vertex type, containing the vertex & texture coordinates
    struct CUSTOMVERTEX
    {
        D3DXVECTOR3 position;   // Vertex coordinates
        FLOAT u, v;             // Texture coordinates
    };

    // The structure of a vertex in our vertex buffer...
    #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_TEX1)  // it will contain xyz coordinates & a texture


    //////////////////////////////////////////////////////
    // Setup Direct3D
    //////////////////////////////////////////////////////
    HRESULT SetupD3D(HWND hWnd)     
    {
        // Create the D3D object.
        if (NULL == (D3D_Object = Direct3DCreate9(D3D_SDK_VERSION))) return E_FAIL;

        // Set up the structure used to create the D3D Device
        D3DPRESENT_PARAMETERS d3dpp;
        ZeroMemory(&d3dpp, sizeof(d3dpp));
        d3dpp.Windowed = TRUE;                      // application will be windowed
        d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;   // back to front buffer behavior - DISCARD = random data used for error checking
        d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;    // back buffer format - UNKNOWN = use current display resolution to retain consistency
        d3dpp.EnableAutoDepthStencil = TRUE;        // D3D device to create and manage depth and stencil buffer automatically
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;  // format of the surfaces which hold the depth & stencil buffers - D16 = 16Bit colours


        // Create the D3D Device - on successful completion return a pointer to the created device D3D_Device
        if (FAILED(D3D_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
                                        D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                        &d3dpp, &D3D_Device)))
        {
            return E_FAIL;      // return error if D3D Device creation has failed
        }

        return S_OK;
    }


    //////////////////////////////////////////////////////
    // DIRECT3D CLEANUP
    //
    // Release (delete) all the resources used by this program.
    // Only release things if they are valid (i.e. have a valid pointer).
    // If not, the program will crash at this point.
    //////////////////////////////////////////////////////
    void CleanUp()
    {
        // Delete the textures
        if (D3D_Tex_Background != NULL)  D3D_Tex_Background -> Release();
        if (D3D_Tex_Invader != NULL)     D3D_Tex_Invader -> Release();

        // Release other D3D Device resources
        if (g_pVertexBuffer != NULL) g_pVertexBuffer -> Release();
        if (D3D_Device != NULL)      D3D_Device -> Release();
        if (D3D_Object != NULL)      D3D_Object  -> Release();
    }


    //////////////////////////////////////////////////////
    // Setup the camera
    //////////////////////////////////////////////////////
    void SetupMatrices()
    {
        // Setup View Matrix
         D3DXVECTOR3 vCamera(5.0f, 5.0f, -100.0f);  
         D3DXVECTOR3 vLookat(5.0f, 5.0f, 0.0f);
         D3DXVECTOR3 vUpVector(0.0f, 1.0f, 0.0f);
         D3DXMATRIX matrixView;
         D3DXMatrixLookAtLH(&matrixView, &vCamera, &vLookat, &vUpVector);
         D3D_Device -> SetTransform(D3DTS_VIEW, &matrixView);

         // Setup Projection Matrix
         // This transforms 2D geometry into a 3D space
         D3DXMATRIX matrixProjection;
         D3DXMatrixPerspectiveFovLH(&matrixProjection, D3DX_PI/4, 1.0f, 1.0f, 800.0f);
         D3D_Device -> SetTransform(D3DTS_PROJECTION, &matrixProjection);
    }


    //////////////////////////////////////////////////////
    // SETUP GEOMETRY - 
    // Define a square using the required verticies
    //////////////////////////////////////////////////////
    HRESULT SetupGeometry()
    {
        // Calculate the number of vertices required for the desired graphic
        int Vertices = 2 * 3;   // Six vertices required for the 2 triangles which make up the square.

        // Calculate the size in bytes of the buffer which will hold the vertex information
        // based on the number of verticies required and the elements contained within the CUSTOMVERTEX structure
        int BufferSize = Vertices * sizeof(CUSTOMVERTEX);

        // Create the vertex buffer which will store the vertex data to render
        // (buffer size, special instructions, vertex buffer format, target memory location for buffer,pointer to vertex buffer, future use only)
        if (FAILED(D3D_Device -> CreateVertexBuffer(BufferSize, 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVertexBuffer, NULL)))
        {
            return E_FAIL; // if the vertex buffer could not be created.
        }

    //////////////////////////////////////////////////////
    // Fill vertex buffer with required vertex & texture info
    //////////////////////////////////////////////////////
        CUSTOMVERTEX *pVertices;            // Create a pointer to the first vertex in the buffer.
        if (FAILED(g_pVertexBuffer -> Lock(0, 0, (void**)&pVertices, 0)))  // lock the buffer to prevent interference, allow access using the
        {                                                                  // &pVerticies pointer

            return E_FAIL;  // if the pointer to the vertex buffer could not be established.
        }

        // Fill the vertex buffers with data concerning both vertex and texture locations

        // Triangle 1
        // Vertex 0
        pVertices[0].position.x = 0;    // Vertex coordinates
        pVertices[0].position.y = 0;
        pVertices[0].position.z = 0;
        pVertices[0].u        = 0;      // texture coordinates
        pVertices[0].v        = 1;

        // Vertex 1
        pVertices[1].position.x = 0;
        pVertices[1].position.y = 10;
        pVertices[1].position.z = 0;
        pVertices[1].u        = 0;
        pVertices[1].v        = 0;

        // Vertex 2
        pVertices[2].position.x = 10;
        pVertices[2].position.y = 0;
        pVertices[2].position.z = 0;
        pVertices[2].u        = 1;
        pVertices[2].v        = 1;

        // Triangle 2
        // Vertex 3
        pVertices[3].position.x = 10;
        pVertices[3].position.y = 0;
        pVertices[3].position.z = 0;
        pVertices[3].u        = 1;
        pVertices[3].v        = 1;

        // Vertex 4
        pVertices[4].position.x = 0;
        pVertices[4].position.y = 10;
        pVertices[4].position.z = 0;
        pVertices[4].u        = 0;
        pVertices[4].v        = 0;

        // Vertex 5
        pVertices[5].position.x = 10;
        pVertices[5].position.y = 10;
        pVertices[5].position.z = 0;
        pVertices[5].u        = 1;
        pVertices[5].v        = 0;

        // Unlock the vertex buffer...
        g_pVertexBuffer -> Unlock();

        return S_OK;
    }


    //////////////////////////////////////////////////////
    // Load the textures for the invaders and background
    //////////////////////////////////////////////////////
    void LoadTextures()
    {
            //D3DXCreateTextureFromFile(D3D_Device,         // Direct3D Device name
            //                        "background.jpg",     // Source file in program folder
            //                        &D3D_Tex_Background);     // address of target texture object


            D3DXCreateTextureFromFile(D3D_Device, 
                                      "invader300x300.png", 
                                      &D3D_Tex_Invader);        
    }


    //////////////////////////////////////////////////////
    // Render
    //////////////////////////////////////////////////////
    void Render()
    {
        // Clearing the current frame & Z buffers
        // (rectangles to clear, rectangle coords, clear current buffer & Z buffer, RGB background colour of screen, initial z buffer value, initial
        // stencil buffer value)
        D3D_Device -> Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

        // Once current frame has been cleared, begin drawing new frame
        // lock is created at this point to prevent anything else drawing on the frame
        if (SUCCEEDED(D3D_Device -> BeginScene()))
        {   

            // Construct a translation matrix to move the Invader
            D3DXMATRIX TranslateMatrix;
            D3DXMatrixTranslation(&TranslateMatrix, g_InvaderX, g_InvaderY, g_InvaderZ);
            D3D_Device -> SetTransform(D3DTS_WORLD, &TranslateMatrix);


            // Render the contents of the vertex buffer.
            D3D_Device -> SetStreamSource(0, g_pVertexBuffer, 0, sizeof(CUSTOMVERTEX));
            D3D_Device -> SetFVF(D3DFVF_CUSTOMVERTEX);
            D3D_Device -> DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);


            // Select the invader texture, and initialise the texture stage state...
            D3D_Device -> SetTexture(0,                 // the texture stage being set
                                     D3D_Tex_Invader);  // the object associated with the texture image
            D3D_Device -> SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
            D3D_Device -> SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);


            // Update the invader's x co-ordinate.
            //if (g_RectX <=14.5)                           
            g_InvaderX += 0.5f;

            // Drawing of the scene has finished
            D3D_Device -> EndScene();
        }

        // Present the back frame buffer contents to the screen (front frame buffer swaped with back fram buffer)
        D3D_Device -> Present(NULL, NULL, NULL, NULL);
    }


    //////////////////////////////////////////////////////
    // Windows Message Handling
    //////////////////////////////////////////////////////
    LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        switch (msg)
        {
            case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            }
        }

        return DefWindowProc(hWnd, msg, wParam, lParam);
    }


    //////////////////////////////////////////////////////
    // Create the application window
    //////////////////////////////////////////////////////
    int WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int)
    {
        // Register the window class
        WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
                         GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                         "Invaders", NULL};
        RegisterClassEx(&wc);

        // Create the application window
        HWND hWnd = CreateWindow( "Invaders",           // Window class's name
                                  "I N V A D E R S",    // Title bar text
                                  WS_OVERLAPPEDWINDOW,  // The window style
                                  100,                  // window horizontal position
                                  500,                  // window vertical position
                                  800,                  // window width
                                  800,                  // window height
                                  GetDesktopWindow(),   // the parent window's module
                                  NULL,                 // the window's menu handle
                                  wc.hInstance,         // the instance handle
                                  NULL);




        // Initialize Direct3D
        if (SUCCEEDED(SetupD3D(hWnd)))
        {
            // Create the scene geometry
            if (SUCCEEDED(SetupGeometry()))
            {
                // Load the required texture(s) from files into memeory 
                LoadTextures();

                // Display the window onscreen
                ShowWindow(hWnd, SW_SHOWDEFAULT);
                UpdateWindow(hWnd);

                // Initialse the Viewpoint / Camera based on defined settings
                SetupMatrices();

                // Enter message loop to handle any messages MS Windows sends to the application
                MSG msg;
                ZeroMemory(&msg, sizeof(msg));
                while (msg.message != WM_QUIT)
                {
                    if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
                    {
                        TranslateMessage(&msg);
                        DispatchMessage(&msg);
                    }
                    else
                        Render();
                }
            }
        }

        CleanUp(); // release resources used ( delete all dynamically allocated objects)

        UnregisterClass("Server", wc.hInstance);

        return 0;
    }   // end WinMain
4

1 に答える 1

2

directx を使用したプログラミングについて、より基本的な理解が必要なようです。thisまたはthisのようないくつかのチュートリアルを実行してみてください。それらは静かで便利です。

具体的な質問: 画面に描画された画像を使用して 2D ゲームを作成したいようです。したがって、D3DFVF_XYZRHW( doc ) を使用する方が簡単です。変換されていない頂点を 2D 座標でレンダリングできるからです。背景をレンダリングするには、最初に画像を適用してフルスクリーン サイズのクワッドを描画します。その後、その前に船をレンダリングします。船が描画されていない場合は、Z バッファリングが背景がその前にあると判断し、切り取った可能性があります。2D ゲームの場合は、ZBuffering を無効にするか、頂点の深さを設定します。

于 2013-01-28T09:49:45.073 に答える