?? direct3d.cpp
字號:
#include "Direct3D.h"
///////////////////////////////////////////////////////////
//
// Initialize Direct3D function
//
///////////////////////////////////////////////////////////
HRESULT InitD3D(IDirect3D9 **ppD3D,
IDirect3DDevice9 **ppD3DDevice,
HWND hWnd,
BOOL ForceWindowed,
BOOL MultiThreaded)
{
IDirect3D9 *pD3D = NULL;
IDirect3DDevice9 *pD3DDevice = NULL;
HRESULT hr;
// Error checking
if(!ppD3D || !ppD3DDevice || !hWnd)
return E_FAIL;
// Initialize Direct3D
if((pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
return E_FAIL;
*ppD3D = pD3D;
// Ask if user wants to run windowed or fullscreen
// or force windowed if flagged to do such
int Mode;
if(ForceWindowed == TRUE)
Mode = IDNO;
else
Mode = MessageBox(hWnd, "Use fullscreen mode? (640x480x16)", "Initialize D3D", MB_YESNO | MB_ICONQUESTION);
// Set the video (depending on windowed mode or fullscreen)
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
// Setup video settings based on choice of fullscreen or not
if(Mode == IDYES) {
//////////////////////////////////////////////////////////
// Setup fullscreen format (set to your own if you prefer)
//////////////////////////////////////////////////////////
DWORD Width = 640;
DWORD Height = 480;
D3DFORMAT Format = D3DFMT_R5G6B5;
// Set the presentation parameters (use fullscreen)
d3dpp.BackBufferWidth = Width;
d3dpp.BackBufferHeight = Height;
d3dpp.BackBufferFormat = Format;
d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
d3dpp.Windowed = FALSE;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
} else {
//////////////////////////////////////////////////////////
// Setup windowed format (set to your own dimensions below)
//////////////////////////////////////////////////////////
// Get the client and window dimensions
RECT ClientRect, WndRect;
GetClientRect(hWnd, &ClientRect);
GetWindowRect(hWnd, &WndRect);
// Set the width and height (set your dimensions here)
DWORD DesiredWidth = 640;
DWORD DesiredHeight = 480;
DWORD Width = (WndRect.right - WndRect.left) + (DesiredWidth - ClientRect.right);
DWORD Height = (WndRect.bottom - WndRect.top) + (DesiredHeight - ClientRect.bottom);
// Set the window's dimensions
MoveWindow(hWnd, WndRect.left, WndRect.top, Width, Height, TRUE);
// Get the desktop format
D3DDISPLAYMODE d3ddm;
pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
// Set the presentation parameters (use windowed)
d3dpp.BackBufferWidth = DesiredWidth;
d3dpp.BackBufferHeight = DesiredHeight;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed = TRUE;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
}
// Create the 3-D device
DWORD Flags= D3DCREATE_MIXED_VERTEXPROCESSING;
// DWORD Flags= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
if(MultiThreaded == TRUE)
Flags |= D3DCREATE_MULTITHREADED;
if(FAILED(hr = pD3D->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, hWnd, Flags,
&d3dpp, &pD3DDevice)))
return hr;
// Store the 3-D device object pointer
*ppD3DDevice = pD3DDevice;
// Set the perspective projection
float Aspect = (float)d3dpp.BackBufferWidth / (float)d3dpp.BackBufferHeight;
D3DXMATRIX matProjection;
D3DXMatrixPerspectiveFovLH(&matProjection, D3DX_PI/4.0f, Aspect, 1.0f, 10000.0f);
pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProjection);
// Set the default render states
pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
pD3DDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
// Set the default texture stage states
pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
// Set the default texture filters
pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
return S_OK;
}
///////////////////////////////////////////////////////////
//
// Load a vertex shader function
//
///////////////////////////////////////////////////////////
HRESULT LoadVertexShader(IDirect3DVertexShader9 **ppShader,
IDirect3DDevice9 *pDevice,
char *Filename,
D3DVERTEXELEMENT9 *pElements,
IDirect3DVertexDeclaration9 **ppDecl)
{
HRESULT hr;
// Error checking
if(!ppShader || !pDevice || !Filename)
return E_FAIL;
// Load and assemble the shader
ID3DXBuffer *pCode;
if(FAILED(hr=D3DXAssembleShaderFromFile(Filename, NULL, NULL, 0, &pCode, NULL)))
return hr;
if(FAILED(hr=pDevice->CreateVertexShader((DWORD*)pCode->GetBufferPointer(), ppShader)))
return hr;
pCode->Release();
// Create the declaration interface if needed
if(pElements && ppDecl)
pDevice->CreateVertexDeclaration(pElements, ppDecl);
// Return success
return S_OK;
}
///////////////////////////////////////////////////////////
//
// Load mesh functions
//
///////////////////////////////////////////////////////////
HRESULT LoadMesh(D3DXMESHCONTAINER_EX **ppMesh,
IDirect3DDevice9 *pDevice,
char *Filename,
char *TexturePath,
DWORD NewFVF,
DWORD LoadFlags)
{
ID3DXMesh *pLoadMesh = NULL;
HRESULT hr;
// Error checking
if(!ppMesh || !pDevice || !Filename || !TexturePath)
return E_FAIL;
// Use system memory if converting FVF
DWORD TempLoadFlags = LoadFlags;
if(NewFVF)
TempLoadFlags = D3DXMESH_SYSTEMMEM;
// Load the mesh using D3DX routines
ID3DXBuffer *MaterialBuffer = NULL, *AdjacencyBuffer = NULL;
DWORD NumMaterials;
if(FAILED(hr=D3DXLoadMeshFromX(Filename, TempLoadFlags,
pDevice, &AdjacencyBuffer,
&MaterialBuffer, NULL,
&NumMaterials, &pLoadMesh)))
return hr;
// Convert to new FVF first as needed
if(NewFVF) {
ID3DXMesh *pTempMesh;
// Use CloneMeshFVF to convert mesh
if(FAILED(hr=pLoadMesh->CloneMeshFVF(LoadFlags, NewFVF, pDevice, &pTempMesh))) {
ReleaseCOM(AdjacencyBuffer);
ReleaseCOM(MaterialBuffer);
ReleaseCOM(pLoadMesh);
return hr;
}
// Free prior mesh and store new pointer
ReleaseCOM(pLoadMesh);
pLoadMesh = pTempMesh; pTempMesh = NULL;
}
// Allocate a D3DXMESHCONTAINER_EX structure
D3DXMESHCONTAINER_EX *pMesh = new D3DXMESHCONTAINER_EX();
*ppMesh = pMesh;
// Store mesh name (filename), type, and mesh pointer
pMesh->Name = strdup(Filename);
pMesh->MeshData.Type = D3DXMESHTYPE_MESH;
pMesh->MeshData.pMesh = pLoadMesh; pLoadMesh = NULL;
// Store adjacency buffer
DWORD AdjSize = AdjacencyBuffer->GetBufferSize();
if(AdjSize) {
pMesh->pAdjacency = new DWORD[AdjSize];
memcpy(pMesh->pAdjacency, AdjacencyBuffer->GetBufferPointer(), AdjSize);
}
ReleaseCOM(AdjacencyBuffer);
// Build material list
if(!(pMesh->NumMaterials = NumMaterials)) {
// Create a default material
pMesh->NumMaterials = 1;
pMesh->pMaterials = new D3DXMATERIAL[1];
pMesh->pTextures = new IDirect3DTexture9*[1];
ZeroMemory(pMesh->pMaterials, sizeof(D3DXMATERIAL));
pMesh->pMaterials[0].MatD3D.Diffuse.r = 1.0f;
pMesh->pMaterials[0].MatD3D.Diffuse.g = 1.0f;
pMesh->pMaterials[0].MatD3D.Diffuse.b = 1.0f;
pMesh->pMaterials[0].MatD3D.Diffuse.a = 1.0f;
pMesh->pMaterials[0].MatD3D.Ambient = pMesh->pMaterials[0].MatD3D.Diffuse;
pMesh->pMaterials[0].MatD3D.Specular = pMesh->pMaterials[0].MatD3D.Diffuse;
pMesh->pMaterials[0].pTextureFilename = NULL;
pMesh->pTextures[0] = NULL;
} else {
// Load the materials
D3DXMATERIAL *Materials = (D3DXMATERIAL*)MaterialBuffer->GetBufferPointer();
pMesh->pMaterials = new D3DXMATERIAL[pMesh->NumMaterials];
pMesh->pTextures = new IDirect3DTexture9*[pMesh->NumMaterials];
for(DWORD i=0;i<pMesh->NumMaterials;i++) {
pMesh->pMaterials[i].MatD3D = Materials[i].MatD3D;
pMesh->pMaterials[i].MatD3D.Ambient = pMesh->pMaterials[i].MatD3D.Diffuse;
// Load the texture if one exists
pMesh->pTextures[i] = NULL;
if(Materials[i].pTextureFilename) {
char TextureFile[MAX_PATH];
sprintf(TextureFile, "%s%s", TexturePath,
Materials[i].pTextureFilename);
D3DXCreateTextureFromFile(pDevice,
TextureFile,
&pMesh->pTextures[i]);
}
}
}
ReleaseCOM(MaterialBuffer);
// Optimize the mesh for better attribute access
pMesh->MeshData.pMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL);
// Clear pMesh pointer just in case
pMesh = NULL;
return S_OK;
}
HRESULT LoadMesh(D3DXMESHCONTAINER_EX **ppMesh,
IDirect3DDevice9 *pDevice,
IDirectXFileData *pDataObj,
char *TexturePath,
DWORD NewFVF,
DWORD LoadFlags)
{
ID3DXMesh *pLoadMesh = NULL;
ID3DXSkinInfo *pSkin = NULL;
HRESULT hr;
// Error checking
if(!ppMesh || !pDevice || !pDataObj || !TexturePath)
return E_FAIL;
// Use system memory if converting FVF
DWORD TempLoadFlags = LoadFlags;
if(NewFVF)
TempLoadFlags = D3DXMESH_SYSTEMMEM;
// Load the mesh using the D3DX skinned mesh interface
ID3DXBuffer *MaterialBuffer = NULL, *AdjacencyBuffer = NULL;
DWORD NumMaterials;
if(FAILED(hr=D3DXLoadSkinMeshFromXof(pDataObj, TempLoadFlags,
pDevice, &AdjacencyBuffer,
&MaterialBuffer, NULL,
&NumMaterials, &pSkin,
&pLoadMesh)))
return hr;
// Free skin info if no bones
if(pSkin && !pSkin->GetNumBones())
ReleaseCOM(pSkin);
// Convert to new FVF first as needed (not w/skinned models)
if(NewFVF) {
ID3DXMesh *pTempMesh = NULL;
// Use CloneMeshFVF to convert mesh
if(FAILED(hr=pLoadMesh->CloneMeshFVF(LoadFlags, NewFVF, pDevice, &pTempMesh))) {
ReleaseCOM(pLoadMesh);
ReleaseCOM(pSkin);
ReleaseCOM(MaterialBuffer);
ReleaseCOM(AdjacencyBuffer);
return hr;
}
// Free prior mesh and store new pointer
ReleaseCOM(pLoadMesh);
pLoadMesh = pTempMesh; pTempMesh = NULL;
}
// Allocate a D3DXMESHCONTAINER_EX structure
D3DXMESHCONTAINER_EX *pMesh = new D3DXMESHCONTAINER_EX();
*ppMesh = pMesh;
// Store mesh template name, type, and mesh pointers
DWORD Size;
pDataObj->GetName(NULL, &Size);
if(Size) {
pMesh->Name = new char[Size];
pDataObj->GetName(pMesh->Name, &Size);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -