This report discusses the small task when I started to learn DirectX. The following is the task details:
Codes
#include <windows.h>
#include "d3dUtility.h"
#include <d3dx9.h>
// Globals
IDirect3DDevice9* Device = 0;
const int Width = 500;
const int Height = 500;
IDirect3DVertexBuffer9* Quad = 0;
IDirect3DTexture9* Tex = 0;
ID3DXMesh* Objects;//cylinder
ID3DXMesh* Objects2;//sphere
D3DXMATRIX ObjWorldMatrices;
D3DXMATRIX ObjWorldMatrices2;
// spot light
D3DLIGHT9 Spot;
static D3DMATERIAL9 Mtrls = d3d::WHITE_MTRL;
static D3DMATERIAL9 MtrlsCylinder = d3d::WHITE_MTRL;
static IDirect3DBaseTexture9* tempTexture = NULL;
D3DXMATRIX Worlds;
static float x = 1.0f;
static float y = 2.0f;
static float z = -10.0f;
static float angle = (3.0f * D3DX_PI) / 2.0f;
static int count = 0;
static float time = 0.0f;
struct Vertex
{
Vertex(){}
Vertex(
float x, float y, float z,
float nx, float ny, float nz,
float u, float v)
{
_x = x; _y = y; _z = z;
_nx = nx; _ny = ny; _nz = nz;
_u = u; _v = v;
}
float _x, _y, _z;
float _nx, _ny, _nz;
float _u, _v; // texture coordinates
static const DWORD FVF; //not sure what's this?
};
const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
// Framework Functions
bool Setup()
{
// Create the quad vertex buffer and fill it with the
// quad geoemtry.
Device->CreateVertexBuffer(
6 * sizeof(Vertex),
D3DUSAGE_WRITEONLY,
Vertex::FVF,
D3DPOOL_MANAGED,
&Quad,
0);
Vertex* v;
Quad->Lock(0, 0, (void**)&v, 0);
// quad built from two triangles, note texture coordinates:
v[0] = Vertex(-25.0f, -25.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
v[1] = Vertex(-25.0f, 25.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
v[2] = Vertex(25.0f, 25.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
v[3] = Vertex(-25.0f, -25.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
v[4] = Vertex(25.0f, 25.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
v[5] = Vertex(25.0f, -25.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);
Quad->Unlock();
// Create the texture and set filters.
D3DXCreateTextureFromFile(
Device,
"grass.png",
&Tex);
D3DXMatrixTranslation(&Worlds, 0.0f, 0.0f, 5.0f);
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
//cylinder
D3DXCreateCylinder(
Device,
1.0f, // radius at negative z end
1.0f, // radius at positive z end
5.0f, // length of cylinder
20, // slices
20, // stacks
&Objects,
0);
// build the ObjWorldMatrices which translates by (0.0f, 0.0f, 1.25f)
D3DXMatrixTranslation(&ObjWorldMatrices, 0.0f, 0.0f, 1.25f);
//sphere
D3DXCreateSphere(
Device,
0.4f, // radius
10, // slices
10, // stacks
&Objects2,
0);
//ÉèÖÃͶӰ¾ØÕó
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(
&proj, //output
D3DX_PI * 0.5f, // 90 - degree
(float)Width / (float)Height,//aspect
1.0f,//½ü²Ã¼ôÃæλÖÃZ
1000.0f);//Ô¶²Ã¼ôÃæλÖÃZ
Device->SetTransform(D3DTS_PROJECTION, &proj);//projection transformation
// use lighting
Device->SetRenderState(D3DRS_LIGHTING, true);
Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);//Gouraud
return true;
}
void Cleanup()
{
d3d::Release<IDirect3DVertexBuffer9*>(Quad);
d3d::Release<IDirect3DTexture9*>(Tex);
d3d::Release<ID3DXMesh*>(Objects);
d3d::Release<ID3DXMesh*>(Objects2);
}
bool Display(float timeDelta)
{
if (Device)
{
D3DXVECTOR3 position(x, y, z);
// the camera is targetted at the origin of the world
D3DXVECTOR3 target(0.0f, 0.0f, 1.25f);
// the worlds up vector
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMATRIX V;
// up - position ¾ÍÊÇÏà»úµÄ³¯Ïò
D3DXMatrixLookAtLH(&V, &position, &target, &up);
Device->SetTransform(D3DTS_VIEW, &V);
//rotate with itself
D3DXMATRIX Rx, Ry, Rz;
static float xx, yy, zz;
D3DXMatrixRotationX(&Rx, xx);
D3DXMatrixRotationY(&Ry, yy);
D3DXMatrixRotationZ(&Rz, zz);
// rotate around the cylinder
D3DXMATRIX p2;
p2 = Rx * Rz;
D3DXMatrixTranslation(&ObjWorldMatrices2, cosf(angle) *5.0f, sinf(angle)*5.0f, 5.0f);
ObjWorldMatrices2 = p2*ObjWorldMatrices2;
//set up spot light
/*D3DXVECTOR3 pos(0.0f, 0.0f, -100.0f);*/
D3DXVECTOR3 pos(cosf(angle) *10.0f, sinf(angle)*10.0f, -100.0f);
time += timeDelta;
/*if (time > 10)
return true;*/
angle += timeDelta;
if (angle >= 6.28f)
angle = 0.0f;
xx += timeDelta;
yy += timeDelta;
zz += timeDelta;
D3DXVECTOR3 dir(0.0f, 0.0f, 1.0f);
D3DXCOLOR c = d3d::WHITE;
Spot = d3d::InitSpotLight(&pos, &dir, &c);
//enable a spot light
Device->SetLight(0, &Spot);
Device->LightEnable(0, true);
// Set light related render states.
Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
Device->SetRenderState(D3DRS_SPECULARENABLE, true);
Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
Device->BeginScene();
// texture
Device->SetTexture(0,Tex);
Device->SetStreamSource(0, Quad, 0, sizeof(Vertex));
Device->SetFVF(Vertex::FVF);
Device->SetTransform(D3DTS_WORLD, &Worlds);
Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
// cylinder
Device->SetTexture(0, tempTexture);
Device->SetMaterial(&MtrlsCylinder);
Device->SetTransform(D3DTS_WORLD, &ObjWorldMatrices);
Objects->DrawSubset(0);
//sphere
Device->SetTexture(0, NULL);
Device->SetMaterial(&Mtrls);
Device->SetTransform(D3DTS_WORLD, &ObjWorldMatrices2);
Objects2->DrawSubset(0);
Device->EndScene();
Device->Present(0, 0, 0, 0);
}
return true;
}
//
// WndProc
//
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
::PostQuitMessage(0);
break;
case WM_CHAR:
switch (wParam) {
case('R'):
MtrlsCylinder = d3d::RED_MTRL;
break;
case('r') :
MtrlsCylinder = d3d::RED_MTRL;
break;
case('G') :
MtrlsCylinder = d3d::GREEN_MTRL;
break;
case('g') :
MtrlsCylinder = d3d::GREEN_MTRL;
break;
case('B'):
MtrlsCylinder = d3d::BLUE_MTRL;
break;
case('b') :
MtrlsCylinder = d3d::BLUE_MTRL;
break;
case('W') :
MtrlsCylinder = d3d::WHITE_MTRL;
break;
case('w') :
MtrlsCylinder = d3d::WHITE_MTRL;
break;
case ('X'):
z += 1.0f;
break;
case ('Z'):
z -= 1.0f;
break;
case ('C') :
x += 1.0f;
break;
case ('V') :
x -= 1.0f;
break;
case ('T') :
tempTexture = Tex;
break;
case ('t') :
tempTexture = Tex;
break;
case ('S') : {
count++;
int temp = count % 3;
if (temp == 0) {
x = 1.0f; y = 2.0f; z = -10.0f;
}
else if (temp == 1) {
x = cosf(angle) *5.0f;
y = sinf(angle)*5.0f;
z = 5.0f;
}
else {
x = cosf(angle) *10.0f;
y = sinf(angle)*10.0f;
z = -100.0f;
}
break;
}
}
}
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}
//
// WinMain
//
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE prevInstance,
PSTR cmdLine,
int showCmd)
{
if (!d3d::InitD3D(hinstance,
Width, Height, true, D3DDEVTYPE_HAL, &Device))
{
::MessageBox(0, "InitD3D() - FAILED", 0, 0);
return 0;
}
if (!Setup())
{
::MessageBox(0, "Setup() - FAILED", 0, 0);
return 0;
}
d3d::EnterMsgLoop(Display);
Cleanup();
Device->Release();
return 0;
}
For the complete codes, you can get it from Github