[C++ - DirectX9.0c - Direct3D] Depth test e normali

di il
3 risposte

[C++ - DirectX9.0c - Direct3D] Depth test e normali

Ciao ragazzi, qui ho bisogno di qualcuno che s'intenda di Direct3D...

Ho due problemi da risolvere...

1) Con D3DXCreateSphere() ho creato una sfera con le normali e va tutto benissimo. Poi ho creato una box con D3DXCreateBox() ma è come se non avesse le normali. Non so il perchè!

Ecco la funzione InitD3D():
HRESULT InitD3D(HWND hWnd, int width, int height, BOOL fullscreenflag) {
    // Creiamo il nostro Device Direct3D
    if ((pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) {
        MessageBox(0, "Le librerie DirectX non sono state installate.", "ERRORE", MB_ICONEXCLAMATION | MB_OK);
        return E_FAIL;
    }

    D3DPRESENT_PARAMETERS D3Dpp;        // Puntiamo alla nostra struttura Device Direct3D
    ZeroMemory(&D3Dpp, sizeof(D3Dpp));  // Azzeriamo la memoria del puntatore
    D3Dpp.Windowed                  = TRUE;                     // Impostiamo la modalità
    D3Dpp.SwapEffect                = D3DSWAPEFFECT_FLIP;    // Impostiamo la tecnica di prestazione
    D3Dpp.BackBufferFormat          = D3DFMT_UNKNOWN;           // Impostiamo il numero di colori
    D3Dpp.BackBufferCount           = 1;
    D3Dpp.hDeviceWindow             = hWnd;
    D3Dpp.Flags                     = 0;
    D3Dpp.FullScreen_RefreshRateInHz= D3DPRESENT_RATE_DEFAULT;
    D3Dpp.PresentationInterval      = D3DPRESENT_INTERVAL_DEFAULT;
    D3Dpp.AutoDepthStencilFormat    = D3DFMT_D16;
    D3Dpp.EnableAutoDepthStencil    = TRUE;
    if (fullscreenflag) {
        D3Dpp.Windowed         = FALSE;
        D3Dpp.BackBufferFormat = D3DFMT_X8R8G8B8; // / D3DFMT_R8G8_B8G8 = 32 bit
        // D3DFMT_R8G8B8 = 24 bit
        // D3DFMT_X1R5G5B5 / D3DFMT_R5G6B5 / D3DFMT_X4R4G4B4 = 16 bit
        D3Dpp.BackBufferWidth  = width;
        D3Dpp.BackBufferHeight = height;
    }

    // Creiamo il nostro Device Direct3D
    if(FAILED(pD3D -> CreateDevice(D3DADAPTER_DEFAULT,                   // Usiamo la scheda video del sistema
                                   D3DDEVTYPE_HAL,                       // Impostiamo l'accelerazione software
                                   hWnd,                                 // L'handle della finestra
                                   D3DCREATE_SOFTWARE_VERTEXPROCESSING,  // Specifica la velocità della scheda video
                                   &D3Dpp,                               // La struttura del Device 3D
                                   &pD3DD)))                             // Il Rendering Device
    {
        MessageBox(0, "Impossibile creare un Device DirectX.", "ERRORE", MB_ICONEXCLAMATION | MB_OK);
        return E_FAIL;
    }

    /**** NEW ****/

    pD3DD -> SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
    /*

    D3DCULL_CW = Visualizza solo i poligoni costruiti in senso orario, poichè quando dovrete girare
                 la figura non potete vedere la parte davanti
    D3DCULL_CCW = L'esatto contrario
    D3DCULL_NONE = Visualizza sia i poligoni costruiti in senso orario che i poligoni costruiti in
                   senso antiorario. L'unico problema è che le figure dietro vanno a sovrapporre
                   quelle davanti.

    Alla fine consiglio solo la D3DCULL_CW (impostatodi default), che sto usando in questo programma

    */

    pD3DD->SetRenderState(D3DRS_ZENABLE, TRUE);
  //  pD3DD->SetRenderState(D3DRS_D, TRUE);

    // Abilitiamo lo shade mode
    pD3DD->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);

    SetupD3DLights();

    /** END NEW **/

    pD3DD -> SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
    /*

    D3DFILL_SOLID     = Visualizza figure piene (impostato di default)
    D3DFILL_POINT     = Visualizza solo i punti delle figure
    D3DFILL_WIREFRAME = Visualizza solo le linee che compongono i poligoni

    */

    D3DXCreateFontA(pD3DD,                      // Device
                    -12,                        // Grandezza font (altezza) *
                    0,                          //                (larghezza)
                    FW_BOLD,                    // Grossezza (normale)
                    0,
                    FALSE,                      // Corsivo
                    ANSI_CHARSET,               // Caratteri ANSI. Se vengono usati simboli usare SYMBOL_CHARSET
                    CLIP_DEFAULT_PRECIS,
                    ANTIALIASED_QUALITY,
                    DEFAULT_PITCH | FF_DONTCARE,
                    "Courier New",          // Nome font
                    &pFont);                    // Puntatore del font
    // *NB: se il numero è negativo la grandezza del font prenderà le misure standard del font,
    // altrimenti saranno decise dal sistema

    D3DXCreateSphere(pD3DD,       // Device
                     1.0f,        // Raggio
                     30,          // Slice
                     30,          // Stack
                     &pMesh[0],   // Puntatore alla nostra sfera
                     NULL);

    D3DXCreateBox(pD3DD,    // Device
                  5.0f,     // Larghezza
                  1.0f,     // Altezza
                  5.0f,     // Profondità
                  &pMesh[1],// Puntatore alla nostra box
                  NULL);

    return S_OK;
}
Ecco la funzione DrawD3DScene():
HRESULT DrawD3DScene(void) {
    if (pD3DD == NULL) {
        MessageBox(0, "Errore nel caricamento del Device.", "ERRORE", MB_ICONEXCLAMATION | MB_OK);
        return E_FAIL;
    }

    // Impostiamo la pulizia dello schermo a nero
    pD3DD -> Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 0, 255), 1.0f, 0);

    if (SUCCEEDED(pD3DD -> BeginScene())) { // Inizio
        SetupD3DCamera();

        D3DXMATRIXA16 mWorld, mWorld2;
        D3DXMATRIXA16 mTrans, mRot;

        D3DMATERIAL9 Mtrl, Mtrl2;
        ZeroMemory(&Mtrl, sizeof(D3DMATERIAL9));
        ZeroMemory(&Mtrl2, sizeof(D3DMATERIAL9));

       D3DXMatrixIdentity(&mWorld);

        D3DXMatrixTranslation(&mTrans, xTrans, yTrans, zTrans);
        D3DXMatrixRotationYawPitchRoll(&mRot, yRot, xRot, zRot);

        // Sequenza: scaling, rotazione, traslazione

        D3DXMatrixMultiply(&mWorld, &mRot, &mTrans);

        // D3DXMatrixReflect() = Fa l'effetto riflesso
        // D3DXMatrixShadow() = Fa l'effetto ombra
        // D3DXMatrixRotationAxis() = Rotazione attorno un asse a scelta

        pD3DD -> SetTransform(D3DTS_WORLD, &mWorld);

        Mtrl.Diffuse.r = Mtrl.Ambient.r = 1.0f;
        Mtrl.Diffuse.g = Mtrl.Ambient.g = 0.5f;
        Mtrl.Diffuse.b = Mtrl.Ambient.b = 0.0f;
        pD3DD -> SetMaterial(&Mtrl);

        pMesh[0] -> DrawSubset(0);


        D3DXMatrixIdentity(&mWorld2);

        D3DXMatrixTranslation(&mWorld2, 0.0f, -3.0f, 5.0f);

        pD3DD -> SetTransform(D3DTS_WORLD, &mWorld2);

        Mtrl2.Diffuse.r = Mtrl2.Ambient.r = 1.0f;
        Mtrl2.Diffuse.g = Mtrl2.Ambient.g = 1.0f;
        Mtrl2.Diffuse.b = Mtrl2.Ambient.b = 1.0f;
        pD3DD -> SetMaterial(&Mtrl2);

        pMesh[1] -> DrawSubset(0);


        D3DPrint(580, 430, 0xFFFFFFFF, "FPS: %d", FPS); // Ho già dichiarato FPS in globale

        pD3DD -> EndScene(); // Fine scena
    } else {
        MessageBox(0, "Impossibile creare la scena.", "ERRORE", MB_ICONEXCLAMATION | MB_OK);
        return E_FAIL;
    }

    pD3DD -> Present(NULL, NULL, NULL, NULL);

    return S_OK;
}
2) Ho notato che anche se la sfera è posizionata davanti alla box la sfera si vede dietro. Il depth test / z beffer penso di averlo settato correttamente, bho?

Grazie a tutti.

3 Risposte

Devi accedere o registrarti per scrivere nel forum
3 risposte