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.