📄 zfxd3d_init.cpp
字号:
*/
HRESULT ZFXD3D::Go(void) {
ZFXCOMBOINFO xCombo;
HRESULT hr;
HWND hwnd;
// 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;
}
// find the appropriate combo
for (UINT i=0; i<g_xDevice.nNumCombo; i++) {
if ( (g_xDevice.d3dCombo[i].bWindowed == m_bWindowed)
&& (g_xDevice.d3dCombo[i].d3dDevType == g_xDevice.d3dDevType)
&& (g_xDevice.d3dCombo[i].fmtAdapter == g_fmtA)
&& (g_xDevice.d3dCombo[i].fmtBackBuffer == g_fmtB) )
{
xCombo = g_xDevice.d3dCombo[i];
break;
}
}
// prepare present parameters structure
ZeroMemory(&m_d3dpp, sizeof(m_d3dpp));
m_d3dpp.Windowed = m_bWindowed;
m_d3dpp.BackBufferCount = 1;
m_d3dpp.BackBufferFormat = g_Dspmd.Format;
m_d3dpp.EnableAutoDepthStencil = TRUE;
m_d3dpp.AutoDepthStencilFormat = xCombo.fmtDepthStencil;
m_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
// stencil buffer active?
if ( (xCombo.fmtDepthStencil == D3DFMT_D24S8)
|| (xCombo.fmtDepthStencil == D3DFMT_D24X4S4)
|| (xCombo.fmtDepthStencil == D3DFMT_D15S1) )
m_bStencil = true;
else
m_bStencil = false;
// fullscreen mode
if (!m_bWindowed) {
m_d3dpp.hDeviceWindow = hwnd = m_hWndMain;
m_d3dpp.BackBufferWidth = g_Dspmd.Width;
m_d3dpp.BackBufferHeight = g_Dspmd.Height;
m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
ShowCursor(FALSE);
}
// windowed mode
else {
m_d3dpp.hDeviceWindow = hwnd = m_hWnd[0];
m_d3dpp.BackBufferWidth = GetSystemMetrics(SM_CXSCREEN);
m_d3dpp.BackBufferHeight = GetSystemMetrics(SM_CYSCREEN);
}
// create direct3d device
hr = m_pD3D->CreateDevice(g_xDevice.nAdapter, g_xDevice.d3dDevType,
hwnd, xCombo.dwBehavior,
&m_d3dpp, &m_pDevice);
// create additional swap chains if wished and possible
if ( (m_nNumhWnd > 0) && m_bWindowed) {
for (UINT i=0; i<m_nNumhWnd; i++) {
m_d3dpp.hDeviceWindow = m_hWnd[i];
m_pDevice->CreateAdditionalSwapChain(&m_d3dpp, &m_pChain[i]);
}
}
m_pEnum->~ZFXD3DEnum();
m_pEnum = NULL;
if(FAILED(hr)) {
Log("error: IDirect3D::CreateDevice()");
return ZFX_CREATEDEVICE;
}
Log("initialized (online and ready)");
LogDeviceCaps(&g_xDevice.d3dCaps);
m_bRunning = true;
m_bIsSceneRunning = false;
m_dwWidth = m_d3dpp.BackBufferWidth;
m_dwHeight = m_d3dpp.BackBufferHeight;
return OneTimeInit();
} // Go
/*----------------------------------------------------------------*/
/**
* Called by ZFXD3D::Go to initialize renderstates and stuff.
*/
HRESULT ZFXD3D::OneTimeInit(void) {
if (!ZFX3DInitCPU()) Log("no SIMD compatible CPU detected");
else Log("SIMD compatible CPU detected => using fast math");
// solid rendering
m_ShadeMode = RS_SHADE_SOLID;
// bring material and vertex cache managers online
m_pSkinMan = new ZFXD3DSkinManager(m_pDevice, m_pLog);
m_pVertexMan = new ZFXD3DVCManager((ZFXD3DSkinManager*)m_pSkinMan,
m_pDevice, this, 8192, 8192, m_pLog);
// activate renderstates
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
// create and set standard material
memset(&m_StdMtrl, 0, sizeof(D3DMATERIAL9));
m_StdMtrl.Ambient.r = 1.0f;
m_StdMtrl.Ambient.g = 1.0f;
m_StdMtrl.Ambient.b = 1.0f;
m_StdMtrl.Ambient.a = 1.0f;
if (FAILED(m_pDevice->SetMaterial(&m_StdMtrl))) {
Log("error: set material (OneTimeInit)");
return ZFX_FAIL;
}
// set texture filtering
m_pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
m_pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
m_pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
// goto 3D mode in first stage
ZFXVIEWPORT vpView = { 0, 0, m_dwWidth, m_dwHeight };
m_Mode = EMD_PERSPECTIVE;
m_nStage = -1;
SetActiveSkinID(MAX_ID);
// identity matrix for view
IDENTITY(m_mView3D);
// set clipping plane values
SetClippingPlanes(0.1f, 1000.0f);
// check and init shaders
PrepareShaderStuff();
// create a default shader. Note: its ID is 0
if (m_bCanDoShaders) {
const char BaseShader[] =
"vs.1.1 \n"\
"dcl_position0 v0 \n"\
"dcl_normal0 v3 \n"\
"dcl_texcoord0 v6 \n"\
"m4x4 oPos, v0, c0 \n"\
"mov oD0, c4 \n"\
"mov oT0, v6 \n";
if (FAILED(CreateVShader((void*)BaseShader, sizeof(BaseShader),
false, false, NULL))) {
Log("CreateVShader() default failed");
return ZFX_FAIL;
}
/*
if (FAILED(ActivateVShader(0, VID_UU))) {
Log("ActivateVShader() default failed");
return ZFX_FAIL;
}
*/
} // default shader
// Set Ambient light level
SetAmbientLight(1.0f, 1.0f, 1.0f);
SetTextureStage(0, RS_TEX_MODULATE);
SetTextureStage(1, RS_NONE);
SetTextureStage(2, RS_NONE);
SetTextureStage(3, RS_NONE);
SetTextureStage(4, RS_NONE);
SetTextureStage(5, RS_NONE);
SetTextureStage(6, RS_NONE);
SetTextureStage(7, RS_NONE);
// set perspective projection stage 0
if (FAILED(InitStage(0.8f, &vpView, 0)))
return ZFX_FAIL;
// set perspective projection
if (FAILED(SetMode(EMD_PERSPECTIVE, 0)))
return ZFX_FAIL;
// world matrix to identity, this is needed to set
// correct values to vertex shader registers also
SetWorldTransform(NULL);
Log("one time scene init complete");
return ZFX_OK;
} // OneTimeInit
/*----------------------------------------------------------------*/
/**
* write outputstring to attribut outputstream if exists
* -> IN: char - format string to output
* ... - output values
*/
void ZFXD3D::Log(char *chString, ...) {
char ch[256];
char *pArgs;
pArgs = (char*) &chString + sizeof(chString);
vsprintf(ch, chString, pArgs);
fprintf(m_pLog, "[ZFXD3DDevice]: ");
fprintf(m_pLog, ch);
fprintf(m_pLog, "\n");
if (g_bLF)
fflush(m_pLog);
} // Log
/*----------------------------------------------------------------*/
/**
* Callback function to handle the device/mode selection dialog
*/
BOOL CALLBACK ZFXD3D::DlgProc(HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam) {
DIBSECTION dibSection;
HRESULT hr;
BOOL bWnd=FALSE;
// get handles
HWND hFULL = GetDlgItem(hDlg, IDC_FULL);
HWND hWND = GetDlgItem(hDlg, IDC_WND);
HWND hADAPTER = GetDlgItem(hDlg, IDC_ADAPTER);
HWND hMODE = GetDlgItem(hDlg, IDC_MODE);
HWND hADAPTERFMT = GetDlgItem(hDlg, IDC_ADAPTERFMT);
HWND hBACKFMT = GetDlgItem(hDlg, IDC_BACKFMT);
HWND hDEVICE = GetDlgItem(hDlg, IDC_DEVICE);
switch (message) {
// preselect windowed
case WM_INITDIALOG: {
SendMessage(hWND, BM_SETCHECK, BST_CHECKED, 0);
hr = m_pEnum->Enum(hADAPTER, hMODE, hDEVICE,
hADAPTERFMT, hBACKFMT,
hWND, hFULL, m_pLog);
if (hr == ZFX_NOTCOMPATIBLE)
EndDialog(hDlg, -2);
else if (hr == ZFX_FAIL)
EndDialog(hDlg, -1);
return TRUE;
}
// draw zfx logo
case WM_PAINT: {
if (g_hBMP) {
GetObject(g_hBMP, sizeof(DIBSECTION), &dibSection);
HDC hdc = GetDC(hDlg);
HDRAWDIB hdd = DrawDibOpen();
DrawDibDraw(hdd, hdc, 50, 10, 95, 99,
&dibSection.dsBmih,
dibSection.dsBm.bmBits, 0, 0,
dibSection.dsBmih.biWidth,
dibSection.dsBmih.biHeight, 0);
DrawDibClose(hdd);
ReleaseDC(hDlg, hdc);
}
} break;
// control changed
case WM_COMMAND: {
switch (LOWORD(wParam)) {
// okay button => read selections
case IDOK: {
m_bWindowed = !SendMessage(hFULL, BM_GETCHECK, 0, 0);
m_pEnum->GetSelections(&g_xDevice, &g_Dspmd, &g_fmtA, &g_fmtB);
GetWindowText(hADAPTER, m_chAdapter, 256);
EndDialog(hDlg, 1);
return TRUE;
} break;
// cancel button
case IDCANCEL: {
EndDialog(hDlg, 0);
return TRUE;
} break;
case IDC_ADAPTER: {
if(HIWORD(wParam)==CBN_SELCHANGE)
m_pEnum->ChangedAdapter();
} break;
case IDC_DEVICE: {
if(HIWORD(wParam)==CBN_SELCHANGE) {
m_pEnum->ChangedDevice();
}
} break;
case IDC_ADAPTERFMT: {
if(HIWORD(wParam)==CBN_SELCHANGE)
m_pEnum->ChangedAdapterFmt();
} break;
case IDC_FULL: case IDC_WND: {
m_pEnum->ChangedWindowMode();
} break;
} // switch [CMD]
} break; // case [CMD]
} // switch [MSG]
return FALSE;
}
/*----------------------------------------------------------------*/
/**
* Log all nice features of a device for eye candy
*/
void ZFXD3D::LogDeviceCaps(D3DCAPS9 *pCaps) {
Log("ADAPTERINFO: {");
if (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) {
Log(" adapter features hardware TnL");
if (pCaps->DevCaps & D3DDEVCAPS_PUREDEVICE)
Log(" (pure device possible)");
else Log(" (no pure device possible)");
}
else
Log(" adapter only features software TnL");
// TEXTURE STUFF
Log(" max. texture stages: %d" , pCaps->MaxTextureBlendStages);
Log(" max. textures for single pass: %d" , pCaps->MaxSimultaneousTextures);
Log(" max. texture width: %d" , pCaps->MaxTextureWidth);
Log(" max. texture height: %d" , pCaps->MaxTextureHeight);
// VERTEX SHADER VERSION
if (pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
Log(" Vertex Shader Version 1.0");
else if (pCaps->VertexShaderVersion < D3DVS_VERSION(2,0) )
Log(" Vertex Shader Version 1.1");
else
Log(" Vertex Shader Version 2.0 or better");
// PIXEL SHADER VERSION
if (pCaps->PixelShaderVersion < D3DPS_VERSION(1,1) )
Log(" Pixel Shader Version 1.0");
else if (pCaps->PixelShaderVersion < D3DPS_VERSION(1,2) )
Log(" Pixel Shader Version 1.1");
else if (pCaps->PixelShaderVersion < D3DPS_VERSION(1,3) )
Log(" Pixel Shader Version 1.2");
else if (pCaps->PixelShaderVersion < D3DPS_VERSION(1,4) )
Log(" Pixel Shader Version 1.3");
else if (pCaps->PixelShaderVersion < D3DPS_VERSION(2,0) )
Log(" Pixel Shader Version 1.4");
else
Log(" Pixel Shader Version 2.0 or better");
Log(" } ENDINFO");
// SCREEN RESOLUTION, FORMAT AND STUFF
Log("DISPLAYINFO {");
LPDIRECT3DSURFACE9 pDepthStencil=NULL;
D3DSURFACE_DESC desc;
D3DFORMAT Format = D3DFMT_UNKNOWN;
D3DDISPLAYMODE mode = {0,0,0,D3DFMT_UNKNOWN};
if (FAILED(m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode)))
Log("Error: IDirect3D::GetAdapterDisplayMode failed");
if (FAILED(m_pDevice->GetDepthStencilSurface(&pDepthStencil)))
Log("Error: IDirect3DDevice::GetDepthStencilSurface failed");
else {
if (FAILED(pDepthStencil->GetDesc(&desc))) {
Log("Error: IDirect3DSurface::GetDesc failed");
Format = D3DFMT_UNKNOWN;
}
}
Log(" Resolution: %dx%d", mode.Width, mode.Height);
Log(" Refreshrate: %d", mode.RefreshRate);
// backbuffer format
switch(mode.Format) {
case D3DFMT_A2R10G10B10: Log(" Pixelformat: D3DFMT_A2R10G10B10"); break;
case D3DFMT_A8R8G8B8: Log(" Pixelformat: D3DFMT_A8R8G8B8"); break;
case D3DFMT_X8R8G8B8: Log(" Pixelformat: D3DFMT_X8R8G8B8"); break;
case D3DFMT_A1R5G5B5 : Log(" Pixelformat: D3DFMT_A1R5G5B5"); break;
case D3DFMT_X1R5G5B5: Log(" Pixelformat: D3DFMT_X1R5G5B5"); break;
case D3DFMT_R5G6B5: Log(" Pixelformat: D3DFMT_R5G6B5"); break;
default: break;
} // switch
// depth buffer format
switch(desc.Format) {
case D3DFMT_D16_LOCKABLE: Log(" Depth/Stencil: D3DFMT_D16_LOCKABLE"); break;
case D3DFMT_D32F_LOCKABLE: Log(" Depth/Stencil: D3DFMT_D32F_LOCKABLE"); break;
case D3DFMT_D32: Log(" Depth/Stencil: D3DFMT_D32"); break;
case D3DFMT_D15S1: Log(" Depth/Stencil: D3DFMT_D15S1"); break;
case D3DFMT_D24S8: Log(" Depth/Stencil: D3DFMT_D24S8"); break;
case D3DFMT_D24X8: Log(" Depth/Stencil: D3DFMT_D24X8"); break;
case D3DFMT_D24X4S4: Log(" Depth/Stencil: D3DFMT_D24X4S4"); break;
case D3DFMT_D24FS8: Log(" Depth/Stencil: D3DFMT_D24FS8"); break;
case D3DFMT_D16: Log(" Depth/Stencil: D3DFMT_D16"); break;
default: break;
} // switch
pDepthStencil->Release();
Log(" } ENDINFO");
} // LogDeviceCaps
/*----------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -