最近看的那本directx 的书的源码都是用函数,没用c++的类,用起来超不爽,所以自己来,封装了下,现在才看到《顶点的颜色》的那章,所以类还很不完整,以后慢慢改进。。
//Base.h
/**//////////////////////////////////////////////#ifndef BASE_H
#define BASE_H
#include <d3dx9.h>
namespace LTT
{
D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR, s, D3DXCOLOR e, float p);
const D3DMATERIAL9 WHITE_MTRL = InitMtrl(WHITE, WHITE, WHITE, BLACK, 8.0f);
const D3DMATERIAL9 RED_MTRL = InitMtrl(RED, RED, RED, BLACK, 8.0f);
const D3DMATERIAL9 GREEN_MTRL = InitMtrl(GREEN, GREEN, GREEN, BLACK, 8.0f);
const D3DMATERIAL9 BLUE_MTRL = InitMtrl(BLUE, BLUE, BLUE, BLACK, 8.0f);
const D3DMATERIAL9 YELLOW_MTRL = InitMtrl(YELLOW, YELLOW, YELLOW, BLACK, 8.0f);
const D3DXCOLOR WHITE( D3DCOLOR_XRGB(255, 255, 255) );
const D3DXCOLOR BLACK( D3DCOLOR_XRGB( 0, 0, 0) );
const D3DXCOLOR RED( D3DCOLOR_XRGB(255, 0, 0) );
const D3DXCOLOR GREEN( D3DCOLOR_XRGB( 0, 255, 0) );
const D3DXCOLOR BLUE( D3DCOLOR_XRGB( 0, 0, 255) );
const D3DXCOLOR YELLOW( D3DCOLOR_XRGB(255, 255, 0) );
const D3DXCOLOR CYAN( D3DCOLOR_XRGB( 0, 255, 255) );
const D3DXCOLOR MAGENTA( D3DCOLOR_XRGB(255, 0, 255) );
D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color);
}
#endif
/**//////////////////////////////////////////////
/////////Base.cpp
////////////////////////////////////////////#include "Base.h"
using namespace LTT;
namespace LTT
{
D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color)
{
D3DLIGHT9 light;
::ZeroMemory(&light, sizeof(light));
light.Type = D3DLIGHT_DIRECTIONAL;
light.Ambient = *color * 0.4f;
light.Diffuse = *color;
light.Specular = *color * 0.6f;
light.Direction = *direction;
return light;
}
D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d,
D3DXCOLOR, s, D3DXCOLOR e, float p)
{
D3DMATERIAL9 mtrl;
mtrl.Ambient = a;
mtrl.Diffuse = d;
mtrl.Specular = s;
mtrl.Emissive = e;
mtrl.Power = p;
return mtrl;
}
}
/**//////////////////////////////////////////////
////LTTFramework.h 框架类
#ifndef LTTFRAMEWORK_H
#define LTTFRAMEWORK_H
#include "Base.h"
namespace LTT
{
class Framework
{
public:
Framework(HINSTANCE hInstance);
virtual ~Framework();
bool InitD3D(HINSTANCE hInstance, int Height = 600, int Width = 800, bool Windowed = true);
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int EnterMsgLoop();
virtual bool Render(float timeDelta);
protected:
IDirect3DDevice9* device;
};
}
#endif
/**//////////////////////////////////////////////
////////////////////////////////////////////
/////////////LTTFramework.cpp#include "LTTFramework.h"
using namespace LTT;
namespace LTT
{
Framework::Framework(HINSTANCE hInstance)
{
InitD3D(hInstance);
}
Framework::~Framework()
{}
bool Framework::InitD3D(HINSTANCE hInstance, int Height, int Width, bool Windowed)
{
WNDCLASSEX wc ={sizeof(WNDCLASSEX), CS_CLASSDC, this->WndProc, 0L, 0L,
GetModuleHandle(NULL),NULL,NULL,NULL,NULL,"D3D",NULL};
if( !RegisterClassEx(&wc) )
{
::MessageBox(0, "RegisterClass() - FAILED", 0, 0);
return false;
}
HWND hwnd = 0;
hwnd = ::CreateWindow("D3D","3D Cube",WS_OVERLAPPEDWINDOW,100,100,800,600,
GetDesktopWindow(),NULL,wc.hInstance,NULL);
if( !hwnd )
{
::MessageBox(0, "CreateWindow() - FAILED", 0, 0);
return false;
}
::ShowWindow(hwnd, SW_SHOW);
::UpdateWindow(hwnd);
/**///////////////////////////////////////////////////////////////////////////////////////
int vp = 0;
IDirect3D9 *_pD3d9;
D3DCAPS9 cap;
_pD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
_pD3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &cap);
if(cap.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
D3DPRESENT_PARAMETERS d3dpp;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferHeight = Height;
d3dpp.BackBufferWidth = Width;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.hDeviceWindow = hwnd;
d3dpp.MultiSampleQuality = 0;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed = Windowed;
HRESULT hr;
hr = _pD3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, vp, &d3dpp, &device);
if(FAILED(hr))
{
MessageBox(0, "CreateDevice() is faild", 0, 0);
return false;
}
_pD3d9->Release();
return true;
}
LRESULT CALLBACK Framework::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_DESTROY:
::PostQuitMessage(0);
break;
case WM_KEYDOWN:
if( wParam == VK_ESCAPE )
::DestroyWindow(hwnd);
break;
}
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}
int Framework::EnterMsgLoop()
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));
static float lastTime = (float)timeGetTime();
while(msg.message != WM_QUIT)
{
if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
float currTime = (float)timeGetTime();
float timeDelta = (currTime - lastTime)*0.001f;
this->Render(timeDelta);
lastTime = currTime;
}
}
return msg.wParam;
}
bool Framework::Render(float timeDelta)
{
return true;
}
}
/**////////////////////////////////////////////////
/////////Application.h
///////////////////////////////////////////////#ifndef APPLICATION_H
#define APPLICATION_H
#include "LTTFramework.h"
using namespace LTT;
namespace LTT
{
struct Vertex
{
Vertex(){}
Vertex(float x, float y, float z)
{
_x = x; _y = y; _z = z;
}
float _x, _y, _z;
float _nx, _y, _z;
static const DWORD FVF;
};
struct ColorVertex
{
ColorVertex(){}
ColorVertex(float x, float y, float z, D3DCOLOR color)
{
_x = x; _y = y; _z = z;
_color = color;
}
float _x, _y, _z;
D3DCOLOR _color;
static const DWORD FVF;
};
class Application: public Framework
{
public:
Application(HINSTANCE hInstance);
virtual ~Application();
virtual bool Setup() = 0;
//virtual bool Render(float timeDelta);
virtual void SetVertexBuffer(){};
virtual void SetIndexBuffer(){};
void Go();
// virtual void InitVertexBuffer() = 0;
// virtual void InitIndexBuffer() = 0;
}
#endif
/**//////////////////////////////////////////////
/////////////////////////////////////////////
////////////Application.cpp
#include "Application.h"
namespace LTT
{
const DWORD ColorVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL;
const DWORD Vertex::FVF = D3DFVF_XYZ;
Application::Application(HINSTANCE hInstance):Framework(hInstance)
{
}
Application::~Application()
{
device->Release();
}
void Application::Go()
{
this->Setup();
EnterMsgLoop();
}
}
/**////////////////////////////////////////////////
///////////ExampleApplication.h//自己写得一个sample 类,继承了application类实现用户的绘制
#ifndef EXAMPLEAPPLICATION_H
#define EXAMPLEAPPLICATION_H
#include "Application.h"
namespace LTT
{
class ExampleApplication:public Application
{
public:
ExampleApplication(HINSTANCE hInstance);
~ExampleApplication();
bool Setup();
bool Render(float timeDelta);
void CleanUp();
virtual void SetVertexBuffer();
virtual void SetIndexBuffer();
private:
IDirect3DVertexBuffer9* Cube;
IDirect3DIndexBuffer9* CubeIndex;
ID3DXMesh* teapot;
D3DXMATRIX ObjWorldMatrices[2];
};
}
#endif
/**//////////////////////////////////////////////
////////////////////////////////////////////
///////////ExampleApplication.cpp
#include "ExampleApplication.h"
using namespace LTT;
namespace LTT
{
ExampleApplication::ExampleApplication(HINSTANCE hInstance):Application(hInstance)
{
}
ExampleApplication::~ExampleApplication()
{
Cube->Release();
CubeIndex->Release();
}
bool ExampleApplication::Setup()
{
// Nothing to setup in this sample.
SetVertexBuffer();
SetIndexBuffer();
D3DXCreateTeapot(device, &teapot, 0);
D3DXMatrixTranslation(&ObjWorldMatrices[0], 3.0f, 5.0f, 3.0f);
D3DXMatrixTranslation(&ObjWorldMatrices[1], 0.0f, 0.0f, 0.0f);
D3DXVECTOR3 position(5.0f, 3.0f, 5.0f);
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMATRIX V;
D3DXMatrixLookAtLH(&V, &position, &target, &up);
device->SetTransform(D3DTS_VIEW, &V);
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI * 0.5f, (float)800 / (float)600, 1.0f, 1000.0f);
device->SetTransform(D3DTS_PROJECTION, &proj);
device->SetRenderState(D3DRS_LIGHTING, false);
return true;
}
void ExampleApplication::SetVertexBuffer()
{
device->CreateVertexBuffer(8 * sizeof(ColorVertex), D3DUSAGE_WRITEONLY, ColorVertex::FVF, D3DPOOL_MANAGED, &Cube, 0);
ColorVertex* vertices;
Cube->Lock(0, 0,(void**)&vertices, 0);
vertices[0] = ColorVertex(-1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB(255, 255, 0));
vertices[1] = ColorVertex(-1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB(255, 255, 0));
vertices[2] = ColorVertex( 1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB(255, 255, 0));
vertices[3] = ColorVertex( 1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB(255, 0, 255));
vertices[4] = ColorVertex(-1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 255));
vertices[5] = ColorVertex(-1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 255));
vertices[6] = ColorVertex( 1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 255));
vertices[7] = ColorVertex( 1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0));
Cube->Unlock();
}
void ExampleApplication::SetIndexBuffer()
{
WORD* indices;
device->CreateIndexBuffer(36 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &CubeIndex, 0);
CubeIndex->Lock(0, 0, (void**)&indices, 0);
// front side
indices[0] = 0; indices[1] = 1; indices[2] = 2;
indices[3] = 0; indices[4] = 2; indices[5] = 3;
// back side
indices[6] = 4; indices[7] = 6; indices[8] = 5;
indices[9] = 4; indices[10] = 7; indices[11] = 6;
// left side
indices[12] = 4; indices[13] = 5; indices[14] = 1;
indices[15] = 4; indices[16] = 1; indices[17] = 0;
// right side
indices[18] = 3; indices[19] = 2; indices[20] = 6;
indices[21] = 3; indices[22] = 6; indices[23] = 7;
// top
indices[24] = 1; indices[25] = 5; indices[26] = 6;
indices[27] = 1; indices[28] = 6; indices[29] = 2;
// bottom
indices[30] = 4; indices[31] = 0; indices[32] = 3;
indices[33] = 4; indices[34] = 3; indices[35] = 7;
CubeIndex->Unlock();
}
bool ExampleApplication::Render(float timeDelta)
{
if( device ) // Only use Device methods if we have a valid device.
{
D3DXMATRIX Rx, Ry;
// rotate 45 degrees on x-axis
D3DXMatrixRotationX(&Rx, 3.14f / 4.0f);
// incremement y-rotation angle each frame
static float y = 0.0f;
D3DXMatrixRotationY(&Ry, y);
y += timeDelta;
// reset angle to zero when angle reaches 2*PI
if( y >= 6.28f )
y = 0.0f;
// combine x- and y-axis rotation transformations.
D3DXMATRIX p = Rx * Ry;
device->SetTransform(D3DTS_WORLD, &p);
// Instruct the device to set each pixel on the back buffer black -
// D3DCLEAR_TARGET: 0x00000000 (black) - and to set each pixel on
// the depth buffer to a value of 1.0 - D3DCLEAR_ZBUFFER: 1.0f.
device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
device->BeginScene();
device->SetStreamSource(0, Cube, 0, sizeof(ColorVertex));
device->SetFVF(ColorVertex::FVF);
device->SetIndices(CubeIndex);
// device->SetTransform(D3DTS_WORLD, &ObjWorldMatrices[1]);
device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
// device->SetTransform(D3DTS_WORLD, &ObjWorldMatrices[0]);
// device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
// teapot->DrawSubset(0);
device->EndScene();
// Swap the back and front buffers.
device->Present(0, 0, 0, 0);
}
return true;
}
}
/**////main函数。。
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd
)
{
LTT::ExampleApplication app(hInstance);
app.Go();
return 0;
}
/**/////////////////////////////////////////////
个人感觉接口封装的还不够好。。用起来还不是那么的爽。。以后继续优化。。。^_^
posted on 2008-09-20 22:10
AstaTus 阅读(1294)
评论(0) 编辑 收藏 引用 所属分类:
DIRECTX9