2014-04-17 6 views
1

Je veux initialiser le vertex normal pour utiliser l'éclairage, mais je ne sais pas comment y parvenir.vertex normal pour les triangles de dodécaèdre

Voici le programme que j'ai réalisé en utilisant DirectX 9 et C++. Il simule une orbite terrestre simple sans implémenter d'éclairage et sans vertex normal aussi.

ce que j'ai besoin est le sommet normal dans le tableau sommets et initialiser indices tableau

// include the basic windows header files and the Direct3D header file 
    #include <windows.h> 
    #include <windowsx.h> 
    #include <d3d9.h> 
    #include <d3dx9.h> 
    #include <math.h> 


    // define the screen resolution 
    #define SCREEN_WIDTH 800 
    #define SCREEN_HEIGHT 600 

    // include the Direct3D Library files 
#pragma comment (lib, "d3d9.lib") 
    #pragma comment (lib, "d3dx9.lib") 

    // global declarations 
    LPDIRECT3D9 d3d; 
    LPDIRECT3DDEVICE9 d3ddev; 
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; // the pointer to the vertex buffer 
    LPDIRECT3DINDEXBUFFER9 i_buffer = NULL; // the pointer to the index buffer 

    // function prototypes 
    void initD3D(HWND hWnd); 
    void render_frame(void); 
    void cleanD3D(void); 
    void init_graphics(void); 

    struct CUSTOMVERTEX {FLOAT X, Y, Z; DWORD COLOR;}; 
    #define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE) 

    // the WindowProc function prototype 
    LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); 


    // the entry point for any Windows program 
    int WINAPI WinMain(HINSTANCE hInstance, 
       HINSTANCE hPrevInstance, 
       LPSTR lpCmdLine, 
       int nCmdShow) 
    { 
    HWND hWnd; 
    WNDCLASSEX wc; 

    ZeroMemory(&wc, sizeof(WNDCLASSEX)); 

    wc.cbSize = sizeof(WNDCLASSEX); 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = WindowProc; 
    wc.hInstance = hInstance; 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.lpszClassName = L"WindowClass"; 

    RegisterClassEx(&wc); 

    hWnd = CreateWindowEx(NULL, L"WindowClass", L"Our Direct3D Program", 
         WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 
         NULL, NULL, hInstance, NULL); 

    ShowWindow(hWnd, nCmdShow); 

    initD3D(hWnd); 

    MSG msg; 

    while(TRUE) 
    { 
    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
    { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 
    } 

    if(msg.message == WM_QUIT) 
     break; 

    render_frame(); 
    } 

    cleanD3D(); 

    return msg.wParam; 
} 


    // this is the main message handler for the program 
    LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch(message) 
    { 
    case WM_DESTROY: 
     { 
      PostQuitMessage(0); 
      return 0; 
     } break; 
    } 

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


    // this function initializes and prepares Direct3D for use 
    void initD3D(HWND hWnd) 
    { 
    d3d = Direct3DCreate9(D3D_SDK_VERSION); 

    D3DPRESENT_PARAMETERS d3dpp; 

    ZeroMemory(&d3dpp, sizeof(d3dpp)); 
    d3dpp.Windowed = TRUE; 
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 
    d3dpp.hDeviceWindow = hWnd; 
    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; 
    d3dpp.BackBufferWidth = SCREEN_WIDTH; 
    d3dpp.BackBufferHeight = SCREEN_HEIGHT; 
    d3dpp.EnableAutoDepthStencil = TRUE; 
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 

    d3d->CreateDevice(D3DADAPTER_DEFAULT, 
        D3DDEVTYPE_HAL, 
        hWnd, 
        D3DCREATE_SOFTWARE_VERTEXPROCESSING, 
        &d3dpp, 
        &d3ddev); 

    init_graphics(); 

    d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE); // turn off the 3D lighting 
    d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // turn off culling 
    d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE); // turn on the z-buffer 
    } 


    // this is the function used to render a single frame 
    void render_frame(void) 
    { 
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); 
    d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); 

    d3ddev->BeginScene(); 

    d3ddev->SetFVF(CUSTOMFVF); 

    // set the view transform 
    D3DXMATRIX matView; // the view transform matrix 
    D3DXMatrixLookAtLH(&matView, 
    &D3DXVECTOR3 (1.0f, 9.0f, 50.0f), // the camera position 
    &D3DXVECTOR3 (1.0f, 1.0f, 1.0f),  // the look-at position 
    &D3DXVECTOR3 (1.0f, 2.0f, 1.0f)); // the up direction 
    d3ddev->SetTransform(D3DTS_VIEW, &matView); // set the view transform to matView 

    // set the projection transform 
    D3DXMATRIX matProjection; // the projection transform matrix 
    D3DXMatrixPerspectiveFovLH(&matProjection, 
          D3DXToRadian(60), // the horizontal field of view 
          (FLOAT)SCREEN_WIDTH/(FLOAT)SCREEN_HEIGHT, // aspect ratio 
          1.0f, // the near view-plane 
          100.0f); // the far view-plane 
    d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection 

    // set the world transform 
    static float index = 0.0f; index+=0.03f; // an ever-increasing float value 
    D3DXMATRIX matRotateY; // a matrix to store the rotation for each triangle 
D3DXMATRIX matTranslateX_venus; 
D3DXMATRIX matTranslateX_merkurius; 
D3DXMATRIX matTranslateX_sun; 
D3DXMATRIX matScale_merkurius; 
D3DXMATRIX matScale_sun; 
D3DXMATRIX matTranslateX_earth; 
D3DXMATRIX matTranslateX_mars; 

    D3DXMatrixRotationY(&matRotateY, index); // the rotation matrix 
    D3DXMatrixTranslation(&matTranslateX_venus,16.0f,0.0f,0.0f); 
    D3DXMatrixTranslation(&matTranslateX_earth,24.0f,0.0f,0.0f); 
    D3DXMatrixTranslation(&matTranslateX_mars,32.0f,0.0f,0.0f); 
    D3DXMatrixTranslation(&matTranslateX_merkurius,8.0f,0.0f,0.0f); 
    D3DXMatrixTranslation(&matTranslateX_sun,0.0f,0.0f,0.0f); 
    D3DXMatrixScaling(&matScale_merkurius, 0.5f, 0.5f, 0.5f); 
    D3DXMatrixScaling(&matScale_sun, 2.5f, 2.5f, 2.5f); 
    // set the world transform 


    // select the vertex buffer to display 
    d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); 
    d3ddev->SetIndices(i_buffer); 

    // draw the pyramid 

    d3ddev->SetTransform(D3DTS_WORLD, &(matScale_sun*matTranslateX_sun *matRotateY)); 
    d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 12, 0, 20); 


    d3ddev->SetTransform(D3DTS_WORLD, &(matTranslateX_venus * matRotateY)); 
    d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 12, 0, 12, 0, 20); 

    d3ddev->SetTransform(D3DTS_WORLD, &(matScale_merkurius*matTranslateX_merkurius 
    *   matRotateY)); 
    d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 24, 0, 12, 0, 20); 

    d3ddev->SetTransform(D3DTS_WORLD, &(matTranslateX_earth * matRotateY)); 
    d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 36, 0, 12, 0, 20); 

    d3ddev->SetTransform(D3DTS_WORLD, &(matTranslateX_mars * matRotateY)); 
    d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 48, 0, 12, 0, 20); 
    d3ddev->EndScene(); 

    d3ddev->Present(NULL, NULL, NULL, NULL); 
    } 


    // this is the function that cleans up Direct3D and COM 
    void cleanD3D(void) 
    { 
    v_buffer->Release(); 
    i_buffer->Release(); 
    d3ddev->Release(); 
    d3d->Release(); 
    } 


    // this is the function that puts the 3D models into video RAM 
    void init_graphics(void) 
    { 
// create the vertices using the CUSTOMVERTEX 
float t = (1.0 + sqrt(5.0))/2.0; 
struct CUSTOMVERTEX vertices[] = 
{ 
    {-1, t, 0, D3DCOLOR_XRGB(255,255,0), }, 
    {1, t, 0, D3DCOLOR_XRGB(255,255,0), }, 
    {-1, -t, 0, D3DCOLOR_XRGB(255,255,0), }, 
    {1, -t, 0, D3DCOLOR_XRGB(255,255,0), }, 
    {0, -1, t, D3DCOLOR_XRGB(255,255,0), }, 
    {0, 1, t, D3DCOLOR_XRGB(255,255,0), }, 
    {0, -1, -t, D3DCOLOR_XRGB(255,255,0), }, 
    {0, 1, -t, D3DCOLOR_XRGB(255,255,0), }, 
    {t, 0, -1, D3DCOLOR_XRGB(255,255,0), }, 
    {t, 0, 1, D3DCOLOR_XRGB(255,255,0), }, 
    {-t, 0, -1, D3DCOLOR_XRGB(255,255,0), }, 
    {-t, 0, 1, D3DCOLOR_XRGB(255,255,0), }, 

    {-1, t, 0, D3DCOLOR_XRGB(88,90,97), }, 
    {1, t, 0, D3DCOLOR_XRGB(88,90,97), }, 
    {-1, -t, 0, D3DCOLOR_XRGB(88,90,97), }, 
    {1, -t, 0, D3DCOLOR_XRGB(88,90,97), }, 
    {0, -1, t, D3DCOLOR_XRGB(88,90,97), }, 
    {0, 1, t, D3DCOLOR_XRGB(88,90,97), }, 
    {0, -1, -t, D3DCOLOR_XRGB(88,90,97), }, 
    {0, 1, -t, D3DCOLOR_XRGB(88,90,97), }, 
    {t, 0, -1, D3DCOLOR_XRGB(88,90,97), }, 
    {t, 0, 1, D3DCOLOR_XRGB(88,90,97), }, 
    {-t, 0, -1, D3DCOLOR_XRGB(88,90,97), }, 
    {-t, 0, 1, D3DCOLOR_XRGB(88,90,97), }, 

    {-1, t, 0, D3DCOLOR_XRGB(136,108,57), }, 
    {1, t, 0, D3DCOLOR_XRGB(136,108,57), }, 
    {-1, -t, 0, D3DCOLOR_XRGB(136,108,57), }, 
    {1, -t, 0, D3DCOLOR_XRGB(136,108,57), }, 
    {0, -1, t, D3DCOLOR_XRGB(136,108,57), }, 
    {0, 1, t, D3DCOLOR_XRGB(136,108,57), }, 
    {0, -1, -t, D3DCOLOR_XRGB(136,108,57), }, 
    {0, 1, -t, D3DCOLOR_XRGB(136,108,57), }, 
    {t, 0, -1, D3DCOLOR_XRGB(136,108,57), }, 
    {t, 0, 1, D3DCOLOR_XRGB(136,108,57), }, 
    {-t, 0, -1, D3DCOLOR_XRGB(136,108,57), }, 
    {-t, 0, 1, D3DCOLOR_XRGB(136,108,57), }, 

    {-1, t, 0, D3DCOLOR_XRGB(14,51,180), }, 
    {1, t, 0, D3DCOLOR_XRGB(14,51,180), }, 
    {-1, -t, 0, D3DCOLOR_XRGB(14,51,180), }, 
    {1, -t, 0, D3DCOLOR_XRGB(14,51,180), }, 
    {0, -1, t, D3DCOLOR_XRGB(14,51,180), }, 
    {0, 1, t, D3DCOLOR_XRGB(14,51,180), }, 
    {0, -1, -t, D3DCOLOR_XRGB(14,51,180), }, 
    {0, 1, -t, D3DCOLOR_XRGB(14,51,180), }, 
    {t, 0, -1, D3DCOLOR_XRGB(14,51,180), }, 
    {t, 0, 1, D3DCOLOR_XRGB(14,51,180), }, 
    {-t, 0, -1, D3DCOLOR_XRGB(14,51,180), }, 
    {-t, 0, 1, D3DCOLOR_XRGB(14,51,180), }, 

    {-1, t, 0, D3DCOLOR_XRGB(192,49,1), }, 
    {1, t, 0, D3DCOLOR_XRGB(192,49,1), }, 
    {-1, -t, 0, D3DCOLOR_XRGB(192,49,1), }, 
    {1, -t, 0, D3DCOLOR_XRGB(192,49,1), }, 
    {0, -1, t, D3DCOLOR_XRGB(192,49,1), }, 
    {0, 1, t, D3DCOLOR_XRGB(192,49,1), }, 
    {0, -1, -t, D3DCOLOR_XRGB(192,49,1), }, 
    {0, 1, -t, D3DCOLOR_XRGB(192,49,1), }, 
    {t, 0, -1, D3DCOLOR_XRGB(192,49,1), }, 
    {t, 0, 1, D3DCOLOR_XRGB(192,49,1), }, 
    {-t, 0, -1, D3DCOLOR_XRGB(192,49,1), }, 
    {-t, 0, 1, D3DCOLOR_XRGB(192,49,1), }, 


}; 

// create a vertex buffer interface called v_buffer 
d3ddev->CreateVertexBuffer(60*sizeof(CUSTOMVERTEX), 
          0, 
          CUSTOMFVF, 
          D3DPOOL_MANAGED, 
          &v_buffer, 
          NULL); 

    VOID* pVoid; // a void pointer 

    // lock v_buffer and load the vertices into it 
    v_buffer->Lock(0, 0, (void**)&pVoid, 0); 
    memcpy(pVoid, vertices, sizeof(vertices)); 
    v_buffer->Unlock(); 

    // create the indices using an int array 
    short indices[] = 
    { 
    // 5 faces around p0 
    0, 11, 5, 
    0, 5, 1, 
    0, 1, 7, 
    0, 7, 10, 
    0, 10, 11, 
    // 5 adjacent faces 
    1, 5, 9, 
    5, 11, 4, 
    11, 10, 2, 
    10, 7, 6, 
    7, 1, 8, 
    // 5 faces around point p3 
    3, 9, 4, 
    3, 4, 2, 
    3, 2, 6, 
    3, 6, 8, 
    3, 8, 9, 
    // 5 adjacent faces 
    4, 9, 5, 
    2, 4, 11, 
6, 2, 10, 
    8, 6, 7, 
    9, 8, 1 
    }; 

    // create a index buffer interface called i_buffer 
d3ddev->CreateIndexBuffer(60*sizeof(short), 
         0, 
         D3DFMT_INDEX16, 
         D3DPOOL_MANAGED, 
         &i_buffer, 
         NULL); 

    // lock i_buffer and load the indices into it 
    i_buffer->Lock(0, 0, (void**)&pVoid, 0); 
memcpy(pVoid, indices, sizeof(indices)); 
    i_buffer->Unlock(); 
} 

Répondre

0

Vous avez deux options

  1. Calculez le sommet vous Normales et ajoutez-le à votre déclaration de sommet. Dans ce cas, vous devrez dessiner chaque face séparément car un sommet est partagé par plusieurs faces. si totalement vous avez besoin de 12 (faces) * 5 (chaque face a 5 vertitudes) = 60 sommets. les sommets d'un même visage ont les mêmes normales, donc il faudrait calculer 12 normales totalement.

  2. Créez un D3DXMesh par D3DXCreateMeshFVF et appelez D3DXComputeNormals pour laisser Direct3D calculer les normales pour vous.

Pour utiliser l'éclairage dans Direct3D

  1. Activer l'éclairage.
  2. Définir le sommet avec des normales (ou sans si vous utilisez l'option 2).
  3. Créez de la lumière et des matériaux (les matériaux décrivent comment votre surface réfléchira la lumière)
  4. Réglez la lumière et les matériaux.

référence pour Dodecahedron

+0

je ne peux pas utiliser monsieur maillé. je dois le calculer. alors pouvez-vous m'apprendre comment le calculer. S'il vous plaît donnez-moi un exemple de mon code. – Bastut

Questions connexes