3D編程-Texture

#include <d3d9.h>
#include <d3dx9.h>
#include <stdio.h>
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"winmm.lib")

#define KeyDown(vk_code) 	((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define Msg(info) 			MessageBox(NULL,info,"message",MB_OK)
#define ErrorMsg(info) 		MessageBox(NULL,info,"error",MB_ICONSTOP)
#define	SAFE_RELEASE_OBJ(pObject)	if(pObject){pObject->Release();}

#define WND_CLASS "wndclass"
#define WND_TITLE "D3DApp Demo"
#define WND_WIDTH    400
#define WND_HEIGHT   300

HWND g_hwnd;
HINSTANCE g_hinst;

LPDIRECT3D9 g_d3d;
LPDIRECT3DDEVICE9 g_device;
LPDIRECT3DVERTEXBUFFER9 g_vb;
LPDIRECT3DTEXTURE9 g_texture;

#define D3DFVF_CUSTOM (D3DFVF_XYZ|D3DFVF_TEX1)
struct CustomVertex
{
	float x,y,z;
	float u,v;
};

class CTexture
{
public:
	CTexture()
	{
		memset(this, 0, sizeof(*this));
	}
	
	~CTexture()
	{
		if(m_pTexture)
			m_pTexture->Release();
	}
	
	bool Load(LPDIRECT3DDEVICE9 device, const char * imgpath)
	{ 
		if(FAILED(D3DXCreateTextureFromFile(device, imgpath, &m_pTexture)))
		{
			return false;
		}
		return true;
	}
	
	LPDIRECT3DTEXTURE9 GetTexture()const
	{
		return m_pTexture;
	}
	
private:
	LPDIRECT3DTEXTURE9 m_pTexture;
};

CTexture g_tex1;
CTexture g_tex2;
LPDIRECT3DTEXTURE9 g_pShowTexture;

bool InitGeometry()
{
	CustomVertex square[]=
	{
		-1, -1, 0,  0,1,
		 1, -1, 0,  1,1,
	    -1,  1, 0,  0,0,
	     1,  1, 0,  1,0,
	};
 
	if(FAILED(g_device->CreateVertexBuffer(sizeof(square), 0, D3DFVF_CUSTOM, D3DPOOL_DEFAULT, &g_vb, NULL)))
   		return false;

	void * paddr;
 
	if(FAILED(g_vb->Lock(0, 0, (void**)&paddr, 0)))
   		return false;
	
	memcpy(paddr, square, sizeof(square));
	
	g_vb->Unlock();
	
	
	if(!g_tex1.Load(g_device, "tex.bmp") || 
		!g_tex2.Load(g_device, "tex2.bmp"))
	{
		ErrorMsg("Unable to load texture file!");
		return false;
	}
	
	g_pShowTexture = g_tex1.GetTexture();
	
	g_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
	g_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	g_device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
	
	
	return true;
}

bool InitD3D()
{
	if(NULL==(g_d3d = Direct3DCreate9(D3D_SDK_VERSION)))
		return false;
		
	D3DDISPLAYMODE d3dpm;
	if(FAILED(g_d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3dpm)))
		return false;
	
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.Windowed = TRUE;
	d3dpp.hDeviceWindow = g_hwnd;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = d3dpm.Format;
	
	if(FAILED(g_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hwnd,
		D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_device)))
		return false;
	
	g_device->SetRenderState(D3DRS_LIGHTING, FALSE);
	g_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	
	return true;
}

void SetupMatices()
{
	D3DXMATRIX world,view,proj;
	D3DXVECTOR3 eye(1,1,3),lookat(0,0,0),updir(0,1,0);
	
	D3DXMatrixRotationY(&world, timeGetTime()/500.0f);
	g_device->SetTransform(D3DTS_WORLD, &world);
	
	D3DXMatrixLookAtLH(&view, &eye, &lookat, &updir);
	g_device->SetTransform(D3DTS_VIEW, &view);
	
	D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI / 4, WND_WIDTH/WND_HEIGHT, 1.0, 1000.0f);
	g_device->SetTransform(D3DTS_PROJECTION, &proj);
	
}
 
void Render()
{
	g_device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
	g_device->BeginScene();
 
 	SetupMatices();
 	
 	// change current texture by key input
 	if(KeyDown('G'))
 		g_pShowTexture = g_tex1.GetTexture();
	else if(KeyDown('H'))
		g_pShowTexture = g_tex2.GetTexture();
 	
 	g_device->SetTexture(0, g_pShowTexture);
 	
	g_device->SetStreamSource(0, g_vb, 0, sizeof(CustomVertex));
	g_device->SetFVF(D3DFVF_CUSTOM);
	g_device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
	
	g_device->EndScene();
	g_device->Present(NULL, NULL, NULL, NULL);
}

void ShutdownApp()
{
	SAFE_RELEASE_OBJ(g_texture);
	SAFE_RELEASE_OBJ(g_vb);
	SAFE_RELEASE_OBJ(g_device);
	SAFE_RELEASE_OBJ(g_d3d);
}

LRESULT CALLBACK MsgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	switch(msg)
	{
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
			
		default:
			break;
	}
	
	return DefWindowProc(hwnd, msg, wparam, lparam);
}

int WINAPI WinMain(HINSTANCE hinst,HINSTANCE hprevinst, LPSTR cmdlint, INT show)
{
	g_hinst = hinst;
	
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_CLASSDC;
	wcex.lpfnWndProc = MsgProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = GetModuleHandle(NULL);
	wcex.hIcon = LoadIcon(NULL, IDC_APPSTARTING);
	wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
	wcex.lpszClassName = WND_CLASS;
	wcex.lpszMenuName = NULL;
	wcex.hIconSm = LoadIcon(NULL, IDC_APPSTARTING);
 
	if(!RegisterClassEx(&wcex))
	{
		ErrorMsg("RegisterClassEx failed!");
		return 0;
	}
	
	g_hwnd = CreateWindow(WND_CLASS, WND_TITLE, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, CW_USEDEFAULT, WND_WIDTH, WND_HEIGHT,
		NULL, NULL, hinst, NULL);
		
	if(!g_hwnd)
		return 0;
		
	ShowWindow(g_hwnd, SW_SHOWNORMAL);
	UpdateWindow(g_hwnd);

	MSG msg={0};
	
	if(!InitD3D())
	{
		ErrorMsg("Init D3D failed!");
		msg.message = WM_QUIT;
	}
	else if(!InitGeometry())
	{
		ErrorMsg("InitGeometry failed!");
		msg.message = WM_QUIT;
	}
		
	while(msg.message != WM_QUIT)
	{
		if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		
		Render();
	}
	
	ShutdownApp();
	UnregisterClass(WND_CLASS, wcex.hInstance);
	
	return 0;
}
 

發佈了22 篇原創文章 · 獲贊 7 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章