📄 zfxd3d_init.cpp
字号:
// File: ZFXD3D_init.cpp
//#include <windows.h> // type definitions
#include "ZFX.h" // return values and stuff
#include "ZFXD3D.h" // class definition
#include "ZFXD3D_skinman.h" // material manager
#include "ZFXD3D_vcache.h" // vertex cache manager
#include <vfw.h> // show bmp's
#include "resource.h" // control id's
bool g_bLF=false;
// we need this for dialog callback only
ZFXD3D *g_ZFXD3D=NULL;
// store result when dialog is closed
ZFXDEVICEINFO g_xDevice;
D3DDISPLAYMODE g_Dspmd;
D3DFORMAT g_fmtA;
D3DFORMAT g_fmtB;
HBITMAP g_hBMP;
/*-----------------------------------------------------------*/
/* DLL stuff implementation *
/*-----------------------------------------------------------*/
/**
* DLL Entry Point similar to WinMain()/main()
*/
BOOL WINAPI DllEntryPoint(HINSTANCE hDll,
DWORD fdwReason,
LPVOID lpvReserved) {
switch(fdwReason) {
// called when we attach to the DLL
case DLL_PROCESS_ATTACH:
/* dll init/setup stuff */
break;
case DLL_PROCESS_DETACH:
/* dll shutdown/release stuff */
break;
default:
break;
};
return TRUE;
} // DllEntryPoint
/*----------------------------------------------------------------*/
/**
* Exported create function: Creates a new ZFXRenderDevice object.
*/
HRESULT CreateRenderDevice(HINSTANCE hDLL, ZFXRenderDevice **pDevice) {
if(!*pDevice) {
*pDevice = new ZFXD3D(hDLL);
return ZFX_OK;
}
return ZFX_FAIL;
}
/*----------------------------------------------------------------*/
/**
* Exported release function: Realeses the given ZFXRenderDevice object.
*/
HRESULT ReleaseRenderDevice(ZFXRenderDevice **pDevice) {
if(!*pDevice) {
return ZFX_FAIL;
}
delete *pDevice;
*pDevice = NULL;
return ZFX_OK;
}
/*----------------------------------------------------------------*/
// give helping hand to class implementation of callback function
BOOL CALLBACK DlgProcWrap(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)
{ return g_ZFXD3D->DlgProc(hDlg, message, wParam, lParam); }
/*----------------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* ZFXD3D class implementation *
/*-----------------------------------------------------------*/
/**
* Constructor
*/
ZFXD3D::ZFXD3D(HINSTANCE hDLL) {
m_hDLL = hDLL;
m_pEnum = NULL;
m_pD3D = NULL;
m_pDevice = NULL;
m_pLog = NULL;
m_ClearColor = D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f);
m_bRunning = false;
m_bIsSceneRunning = false;
m_bUseShaders = false;
m_bCanDoShaders = false;
m_bAdditive = false;
m_bColorBuffer = true;
m_bTextures = true;
m_pSkinMan = NULL;
m_pVertexMan = NULL;
m_pDeclVertex = NULL;
m_pDeclPVertex = NULL;
m_pDeclLVertex = NULL;
m_pDeclCVertex = NULL;
m_pDecl3TVertex = NULL;
m_pDeclTVertex = NULL;
m_pFont = NULL;
// dont use swapchain at first
m_nActivehWnd = 0;
m_nNumVShaders = 0;
m_nNumPShaders = 0;
m_nNumFonts = 0;
g_ZFXD3D = this;
m_pLog = fopen("Log_ZFXRenderDevice.txt", "w");
Log("online (waiting for initialization call)");
}
/*----------------------------------------------------------------*/
/**
* Destructor
*/
ZFXD3D::~ZFXD3D() {
Release();
}
/*----------------------------------------------------------------*/
/**
* Release all of our own and the Direct3D COM stuff.
*/
void ZFXD3D::Release() {
// our own stuff
if (m_pEnum) {
delete m_pEnum;
m_pEnum = NULL;
}
if (m_pSkinMan) {
delete m_pSkinMan;
m_pSkinMan = NULL;
}
if (m_pVertexMan) {
delete m_pVertexMan;
m_pVertexMan = NULL;
}
// shader stuff
if (m_pDeclVertex) {
m_pDeclVertex->Release();
m_pDeclVertex = NULL;
}
if (m_pDeclPVertex) {
m_pDeclPVertex->Release();
m_pDeclPVertex = NULL;
}
if (m_pDeclLVertex) {
m_pDeclLVertex->Release();
m_pDeclLVertex = NULL;
}
if (m_pDeclCVertex) {
m_pDeclCVertex->Release();
m_pDeclCVertex = NULL;
}
if (m_pDecl3TVertex) {
m_pDecl3TVertex->Release();
m_pDecl3TVertex = NULL;
}
if (m_pDeclTVertex) {
m_pDeclTVertex->Release();
m_pDeclTVertex = NULL;
}
for (UINT i=0; i<m_nNumVShaders; i++) {
if (m_pVShader[i]) {
m_pVShader[i]->Release();
m_pVShader[i] = NULL;
}
}
for (UINT j=0; j<m_nNumPShaders; j++) {
if (m_pPShader[j]) {
m_pPShader[j]->Release();
m_pPShader[j] = NULL;
}
}
for (UINT k=0; k<m_nNumFonts; k++) {
if (m_pFont[k]) {
m_pFont[k]->Release();
m_pFont[k] = NULL;
}
}
if (m_pFont) {
free(m_pFont);
m_pFont = NULL;
}
// main objects
if(m_pDevice) {
m_pDevice->Release();
m_pDevice = NULL;
}
if(m_pD3D) {
m_pD3D->Release();
m_pD3D = NULL;
}
Log("offline (ok)");
fclose(m_pLog);
}
/*----------------------------------------------------------------*/
/**
* Initialize dialogbox to select device and format. Dialog must
* have ID using -"- signs and must have combobox "IDC_ADAPTER",
* listbox "IDC_MODES", radiobuttons "IDC_FULL" and "IDC_WND",
* and Buttons "IDOK" and "IDCANCEL".
* -> IN: HWND - handle of application window
* HWND - array to render child-window HWNDs or NULL
* int - number of child HWNDs in array
* int - minimum number of depth bits
* int - minimum number of stencil bits
* bool - create a save but slow log?
*/
HRESULT ZFXD3D::Init(HWND hWnd, const HWND *hWnd3D,
int nNumhWnd, int nMinDepth,
int nMinStencil, bool bSaveLog) {
int nResult;
g_bLF = bSaveLog;
// are there any child windows to use?
if (nNumhWnd > 0) {
if (nNumhWnd > MAX_3DHWND) nNumhWnd = MAX_3DHWND;
memcpy(&m_hWnd[0], hWnd3D, sizeof(HWND)*nNumhWnd);
m_nNumhWnd = nNumhWnd;
}
// else store handle to main window at least
else {
m_hWnd[0] = hWnd;
m_nNumhWnd = 0;
}
m_hWndMain = hWnd;
if (nMinStencil > 0)
m_bStencil = true;
// create enum object
m_pEnum = new ZFXD3DEnum(nMinDepth, nMinStencil);
Log("calling dialog");
// load bmp logo
g_hBMP = (HBITMAP)LoadImage(NULL, "zfx.bmp",
IMAGE_BITMAP,0,0,
LR_LOADFROMFILE |
LR_CREATEDIBSECTION);
// call device selection dialog
nResult = DialogBox(m_hDLL, "dlgChangeDevice", hWnd, DlgProcWrap);
// delete bmp if any
if (g_hBMP) DeleteObject(g_hBMP);
Log("dialog finished");
// dialog failed somehow
if (nResult == -1) {
Log("error: selection dialog error");
return ZFX_FAIL;
}
// dialog was canceled by user
else if (nResult == 0) {
Log("warning: selection dialog canceled by user");
return ZFX_CANCELED;
}
else if (nResult == -2) {
Log("error: no compatible graphics adapter");
return ZFX_NOTCOMPATIBLE;
}
// dialog ended with ok button
else {
Log("firing up MS Direct3D");
return Go();
}
}
/*----------------------------------------------------------------*/
/**
* -> IN: HWND - handle of application window
* HWND - array to render child-window HWNDs or NULL
* int - number of child HWNDs in array
* bool - create a save but slow log?
*/
HRESULT ZFXD3D::InitWindowed(HWND hWnd, const HWND *hWnd3D,
int nNumhWnd, bool bSaveLog) {
HRESULT hr;
D3DCAPS9 caps;
RECT rc;
g_bLF = bSaveLog;
// are there any child windows to use?
if (nNumhWnd > 0) {
if (nNumhWnd > MAX_3DHWND) nNumhWnd = MAX_3DHWND;
memcpy(&m_hWnd[0], hWnd3D, sizeof(HWND)*nNumhWnd);
m_nNumhWnd = nNumhWnd;
}
// else store handle to main window at least
else {
m_hWnd[0] = hWnd;
m_nNumhWnd = 0;
}
m_hWndMain = hWnd;
m_bWindowed = true;
// build main direct3d object
if (m_pD3D) {
m_pD3D->Release();
m_pD3D = NULL;
}
m_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
if(!m_pD3D) {
Log("error: Direct3DCreate8()");
return ZFX_CREATEAPI;
}
m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
&caps);
if ( (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0) {
Log("error: no hardware vertexprocessing");
m_pD3D->Release();
m_pD3D = NULL;
return ZFX_NOTCOMPATIBLE;
}
// prepare present parameters structure
ZeroMemory(&m_d3dpp, sizeof(m_d3dpp));
m_d3dpp.Windowed = m_bWindowed;
m_d3dpp.BackBufferCount = 1;
m_d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
m_d3dpp.EnableAutoDepthStencil = TRUE;
m_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
m_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
m_bStencil = false;
// windowed mode
GetClientRect(m_hWnd[0], &rc);
m_d3dpp.hDeviceWindow = m_hWnd[0];
m_d3dpp.BackBufferWidth = rc.right;
m_d3dpp.BackBufferHeight = rc.bottom;
// create direct3d device
hr = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
m_hWnd[0],
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&m_d3dpp,
&m_pDevice);
if(FAILED(hr)) {
Log("error: IDirect3D::CreateDevice()");
if (hr == D3DERR_NOTAVAILABLE)
Log("D3DERR_NOTAVAILABLE");
else if (hr == D3DERR_INVALIDCALL)
Log("D3DERR_INVALIDCALL");
else if (hr == D3DERR_OUTOFVIDEOMEMORY)
Log("D3DERR_OUTOFVIDEOMEMORY");
else
Log("unknown error");
return ZFX_CREATEDEVICE;
}
// create additional swap chains if wished and possible
if ( (m_nNumhWnd > 0) && m_bWindowed) {
for (UINT i=0; i<m_nNumhWnd; i++) {
GetClientRect(m_hWnd[i], &rc);
m_d3dpp.hDeviceWindow = m_hWnd[i];
m_d3dpp.BackBufferWidth = rc.right;
m_d3dpp.BackBufferHeight = rc.bottom;
hr = m_pDevice->CreateAdditionalSwapChain(&m_d3dpp, &m_pChain[i]);
if (FAILED(hr)) break;
}
}
Log("initialized (online and ready)");
m_pDevice->GetDeviceCaps(&g_xDevice.d3dCaps);
LogDeviceCaps(&g_xDevice.d3dCaps);
m_bRunning = true;
m_bIsSceneRunning = false;
m_dwWidth = m_d3dpp.BackBufferWidth;
m_dwHeight = m_d3dpp.BackBufferHeight;
return OneTimeInit();
} // InitWnd
/*----------------------------------------------------------------*/
/**
* Start the API with values from dialogbox.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -