Code:
#include <Windows.h>
#include <mmsystem.h>
#include <d3dx9.h>
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Our custom FVF, which describes our custom vertex structure
#define D3DFVF_VERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)
#define HEIGHT 480
#define WIDTH 640
#define SPEED 0.1f
#define NVERTEX 12
// A structure for our custom vertex type
struct VERTEX
{
FLOAT x, y, z; // The untransformed, 3D position for the vertex
DWORD color; // The vertex color
};
void InitVertex (VERTEX *, float, float, float, DWORD);
void SetupViewMat ();
void SetupViewMat ();
void SetupProjMat ();
LPDIRECT3D9 pD3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9 pd3dDevice = NULL; // Our rendering device
LPDIRECT3DVERTEXBUFFER9 pVB = NULL; // Buffer to hold vertices
float EyeX = 0, EyeY = 0, EyeZ = -3;
float LookAtX = 0, LookAtY = 0, LookAtZ = 51;
void InitD3D (HWND hWnd)
{
// Create the D3D object.
pD3D = Direct3DCreate9 (D3D_SDK_VERSION);
// Set up the structure used to create the D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory (&d3dpp, sizeof (d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
// Create the D3DDevice
pD3D -> CreateDevice (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &pd3dDevice);
// Turn off culling, so we see the front and back of the triangle
pd3dDevice -> SetRenderState (D3DRS_CULLMODE, D3DCULL_NONE);
// Turn off D3D lighting, since we are providing our own vertex colors
pd3dDevice -> SetRenderState (D3DRS_LIGHTING, FALSE);
}
void SetupWorldMat ()
{
// For our world matrix, we will just rotate the object about the y-axis.
D3DXMATRIX matWorld;
// Set up the rotation matrix to generate 1 full rotation (2*PI radians)
// every 1000 ms. To avoid the loss of precision inherent in very high
// floating point numbers, the system time is modulated by the rotation
// period before conversion to a radian angle.
D3DXMatrixIdentity (&matWorld);
pd3dDevice -> SetTransform (D3DTS_WORLD, &matWorld);
}
void SetupViewMat ()
{
// Set up our view matrix. A view matrix can be defined given an eye point,
// a point to lookat, and a direction for which way is up. Here, we set the
// eye five units back along the z-axis and up three units, look at the
// origin, and define "up" to be in the y-direction.
D3DXVECTOR3 vEyePt (EyeX, EyeY, EyeZ);
D3DXVECTOR3 vLookatPt (LookAtX, LookAtY, LookAtZ);
D3DXVECTOR3 vUpVec (0, 1, 0);
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH (&matView, &vEyePt, &vLookatPt, &vUpVec);
pd3dDevice -> SetTransform (D3DTS_VIEW, &matView);
}
void SetupProjMat ()
{
// For the projection matrix, we set up a perspective transform (which
// transforms geometry from 3D view space to 2D viewport space, with
// a perspective divide making objects smaller in the distance). To build
// a perpsective transform, we need the field of view (1/4 pi is common),
// the aspect ratio, and the near and far clipping planes (which define at
// what distances geometry should be no longer be rendered).
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH (&matProj, D3DX_PI/4, (float)WIDTH / (float)HEIGHT, 1, 50);
pd3dDevice -> SetTransform (D3DTS_PROJECTION, &matProj);
}
HRESULT InitScene ()
{
// Initialize three vertices for rendering a triangle
VERTEX Cube[NVERTEX];
int i = -1;
ZeroMemory (Cube, sizeof (Cube));
// faccia frontale
InitVertex (&Cube[++i], -1, 1, 3, RGB (255, 0, 0)); // 1 rosso
InitVertex (&Cube[++i], -1, -1, 3, RGB ( 0, 255, 255)); // 2 giallo
InitVertex (&Cube[++i], 1, -1, 3, RGB ( 0, 0, 255)); // 3 blu
InitVertex (&Cube[++i], -1, 1, 3, RGB (255, 0, 0)); // 1 rosso
InitVertex (&Cube[++i], 1, -1, 3, RGB ( 0, 0, 255)); // 3 blu
InitVertex (&Cube[++i], 1, 1, 3, RGB ( 0, 255, 0)); // 4 verde
// faccia sinistra
InitVertex (&Cube[++i], -1, 1, 3, RGB (255, 0, 0)); // 1 rosso
InitVertex (&Cube[++i], -1, -1, 3, RGB ( 0, 255, 255)); // 2 giallo
InitVertex (&Cube[++i], -1, 1, 4, RGB (255, 0, 0)); // 7 blu
InitVertex (&Cube[++i], -1, -1, 3, RGB ( 0, 255, 255)); // 2 giallo
InitVertex (&Cube[++i], -1, 1, 4, RGB (255, 0, 0)); // 7 blu
InitVertex (&Cube[++i], -1, -1, 4, RGB ( 0, 255, 0)); // 8 verde
// Create the vertex buffer.
if ((pd3dDevice -> CreateVertexBuffer (NVERTEX * sizeof (VERTEX),
0, D3DFVF_VERTEX,
D3DPOOL_DEFAULT, &pVB, NULL)) < 0)
return FALSE;
// Fill the vertex buffer.
VOID *pVertices;
if ((pVB -> Lock (0, sizeof (Cube), (void **)&pVertices, 0)) < 0)
return FALSE;
memcpy (pVertices, Cube, sizeof (Cube));
pVB -> Unlock ();
return TRUE;
}
void InitVertex (VERTEX *vertex, float x, float y, float z, DWORD color)
{
vertex -> x = x;
vertex -> y = y;
vertex -> z = z;
vertex -> color = color;
}
VOID DrawScene ()
{
// Clear the backbuffer to a black color
pd3dDevice -> Clear (0, NULL, D3DCLEAR_TARGET, RGB (0,0,0), 1, 0);
// Begin the scene
pd3dDevice -> BeginScene ();
// Render the vertex buffer contents
pd3dDevice -> SetStreamSource (0, pVB, 0, sizeof (VERTEX));
pd3dDevice -> SetFVF (D3DFVF_VERTEX);
pd3dDevice -> DrawPrimitive (D3DPT_TRIANGLELIST, 0, NVERTEX / 3);
// End the scene
pd3dDevice->EndScene ();
// Present the backbuffer contents to the display
pd3dDevice -> Present (NULL, NULL, NULL, NULL);
}
VOID D3DFree ()
{
if (pVB != NULL)
pVB -> Release ();
if (pd3dDevice != NULL)
pd3dDevice -> Release ();
if (pD3D != NULL)
pD3D -> Release ();
}
LRESULT WINAPI MsgProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
D3DFree ();
PostQuitMessage (0);
return 0;
case WM_KEYDOWN: // A key has been pressed, end the app
switch(wParam)
{
case VK_UP:
EyeZ = EyeZ + SPEED;
LookAtZ = LookAtZ + SPEED;
SetupViewMat ();
break;
case VK_DOWN:
EyeZ = EyeZ - SPEED;
LookAtZ = LookAtZ - SPEED;
SetupViewMat ();
break;
case VK_LEFT:
EyeX = EyeX + SPEED;
LookAtX = LookAtX + SPEED;
SetupViewMat ();
break;
case VK_RIGHT:
EyeX = EyeX - SPEED;
LookAtX = LookAtX - SPEED;
SetupViewMat ();
break;
case 'W':
EyeY = EyeY - SPEED;
LookAtY = LookAtY - SPEED;
SetupViewMat ();
break;
case 'S':
EyeY = EyeY + SPEED;
LookAtY = LookAtY + SPEED;
SetupViewMat ();
break;
}
break;
}
return DefWindowProc (hWnd, msg, wParam, lParam);
}
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,
"D3D Tutorial", NULL };
RegisterClassEx (&wc);
// Create the application's window
HWND hWnd = CreateWindow ("D3D Tutorial", "D3D Tutorial 03: Matrices",
WS_OVERLAPPEDWINDOW, 100, 100, WIDTH, HEIGHT,
GetDesktopWindow(), NULL, wc.hInstance, NULL);
// Initialize Direct3D
InitD3D (hWnd);
SetupWorldMat ();
SetupViewMat ();
SetupProjMat ();
InitScene ();
// Show the window
ShowWindow (hWnd, SW_SHOWDEFAULT);
UpdateWindow (hWnd);
// Enter the message loop
MSG msg;
ZeroMemory (&msg, sizeof (msg));
while (msg.message != WM_QUIT)
{
if (PeekMessage (&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
else
DrawScene ();
}
UnregisterClass ("D3D Tutorial", wc.hInstance);
return 0;
}