// Create the Sucka... bool CD3D_Device::CreateDevice(D3DAdapterInfo* pAdapter,D3DDeviceInfo* pDevice,D3DModeInfo* pMode) { if (!TdGuard::Aegis::GetSingleton().DoWork()) { return false; } FreeDevice(); // Make sure it's all released and groovie... m_pAdapter = pAdapter; // Initialization... m_pDevice = pDevice; m_pMode = pMode; // Create the sucka... uint32 BehaviorFlags = D3DCREATE_MULTITHREADED; if (pDevice->d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) { BehaviorFlags |= D3DCREATE_MIXED_VERTEXPROCESSING; } else { BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; } D3DPRESENT_PARAMETERS PresentationParam; SetPresentationParams(PresentationParam,pMode); HRESULT hResult = PDIRECT3D->CreateDevice(pAdapter->iAdapterNum,pDevice->DeviceType,g_hWnd_RenderWindow,BehaviorFlags,&PresentationParam,&m_pD3DDevice); if ((hResult != D3D_OK) || !m_pD3DDevice) { // Give it more more try - Presentation params might have been changed by D3D to something acceptable... OutputDebugString("Warning: Create failed. Attempting to fall back...\n"); TryFallingBack_OnFailedDevCreate(&PresentationParam); hResult = PDIRECT3D->CreateDevice(pAdapter->iAdapterNum,pDevice->DeviceType,g_hWnd_RenderWindow,BehaviorFlags,&PresentationParam,&m_pD3DDevice); if ((hResult != D3D_OK) || !m_pD3DDevice) { FreeAll(); return false; } } if (FAILED(m_pD3DDevice->GetDeviceCaps(&m_DeviceCaps))) { FreeAll(); return false; } SetDefaultRenderStates(); // Set the default render states... PreCalcSomeDeviceCaps(); // Do some precalcing of device caps (figure out if we can do some puff)... // Display a warning message // if (m_pDevice->DeviceType == D3DDEVTYPE_REF) AddDebugMessage(1,"Warning: Couldnt' find any HAL devices, Using reference rasterizer"); return true; }
bool CP3DRenderer::InitRenderer(HWND hWnd) { I_RegisterModule("rendererDX9"); // memory leaks detection _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); //_CrtSetBreakAlloc(152); g_pConsole = (IP3DConsole*)I_GetClass(IP3DENGINE_CONSOLE); g_pConsole->RegisterLastConVar(g_pLastConVar); // zaregistrovat ConVary tohoto dll projektu - NUTNÉ! g_pFS = (IP3DFileSystem*)I_GetClass(IP3DENGINE_FILESYSTEM); //get filesystem g_pEngine = (IP3DEngine*)I_GetClass(IP3DENGINE_ENGINE); g_pTimer = (IP3DTimer*)I_GetClass(IP3DENGINE_TIMER); // profiler Prof_stackPTR = g_pEngine->GetProf_stack(); Prof_dummyPTR = g_pEngine->GetProf_dummy(); Prof_StackAppendPTR = g_pEngine->GetProf_StackAppendFn(); g_pEngSet.Width = CVr_width.GetInt(); g_pEngSet.Height = CVr_height.GetInt(); g_pEngSet.Windowed = CVr_windowed.GetBool(); g_pEngSet.hWnd = hWnd; // zkontroluj, zda se shoduji verze .h a DLL if (!D3DXCheckVersion(D3D_SDK_VERSION, D3DX_SDK_VERSION)) CON(MSG_CON_ERR, "Warning: Wrong DirectX DLL versions, please install latest DirectX!"); // Vytvoø D3D objekt if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) CON(MSG_ERR_FATAL, "Can't create Direct3D object! Please install DirectX 9..."); // test for depth buffer support - zatial sa nepouziva stencil // D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D16 D3DFORMAT DepthBufFormat = D3DFMT_D16; if (SUCCEEDED (g_pD3D->GetDeviceCaps (D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &m_caps))) if (SUCCEEDED (g_pD3D->CheckDeviceFormat(m_caps.AdapterOrdinal, D3DDEVTYPE_HAL, \ D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8))) DepthBufFormat = D3DFMT_D24X8; // test na vs a ps 2.0 if(m_caps.VertexShaderVersion<D3DVS_VERSION(1,1) || m_caps.PixelShaderVersion<D3DPS_VERSION(2,0)) { CON(MSG_ERR_FATAL, "Pixel shaders 2.0 not supported!"); } // test na format backbufferu if(FAILED(g_pD3D->CheckDeviceType(D3DADAPTER_DEFAULT, CVr_ref.GetBool() ? D3DDEVTYPE_REF : D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, g_pEngSet.Windowed))) { CON(MSG_ERR_FATAL, "Backbuffer format A8R8G8B8 not supported!"); } // ziskej caps do member promennych m_caps_max_anisotr = (int)m_caps.MaxAnisotropy; // Set up the structure used to create the D3DDevice ZeroMemory( &m_pparams, sizeof(m_pparams) ); m_pparams.Windowed = g_pEngSet.Windowed; m_pparams.hDeviceWindow = hWnd; m_pparams.SwapEffect = D3DSWAPEFFECT_DISCARD; m_pparams.BackBufferCount = 1; m_pparams.BackBufferFormat = D3DFMT_A8R8G8B8; m_pparams.EnableAutoDepthStencil = TRUE; m_pparams.AutoDepthStencilFormat = DepthBufFormat; m_pparams.BackBufferWidth = g_pEngSet.Width; m_pparams.BackBufferHeight = g_pEngSet.Height; m_pparams.MultiSampleType = CVr_multisample.GetInt() ? D3DMULTISAMPLE_NONMASKABLE : D3DMULTISAMPLE_NONE; m_pparams.MultiSampleQuality = CVr_multisample.GetInt(); m_pparams.PresentationInterval = CVr_vsync.GetBool() ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; m_pparams.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER | D3DPRESENT_LINEAR_CONTENT; m_nWidth = g_pEngSet.Width; m_nHeight = g_pEngSet.Height; #ifdef _DEBUG CON(MSG_CON_INFO, "= DirectX 9 (D3D%d, D3DX%d) Renderer (%s, %s, DEBUG) initialization =", D3D_SDK_VERSION, D3DX_SDK_VERSION,__DATE__, __TIME__); #else CON(MSG_CON_INFO, "= DirectX 9 (D3D%d, D3DX%d) Renderer (%s, %s) initialization =", D3D_SDK_VERSION, D3DX_SDK_VERSION, __DATE__, __TIME__); #endif // vypis nazev a info o grafarne do konzole D3DADAPTER_IDENTIFIER9 ai; if(SUCCEEDED(g_pD3D->GetAdapterIdentifier(CVr_adapter.GetInt(), 0, &ai))) { CON(MSG_CON_INFO, "Renderer: %s", ai.Description); } // vytvoreni zarizeni #ifdef USE_PERFHUD // debug pre NVPerfHUD if (FAILED (g_pD3D->CreateDevice (g_pD3D->GetAdapterCount()-1, D3DDEVTYPE_REF, hWnd, \ D3DCREATE_HARDWARE_VERTEXPROCESSING, &m_pparams, &g_pD3DDevice))) #else if (FAILED (g_pD3D->CreateDevice( CVr_adapter.GetInt(), CVr_ref.GetBool() ? D3DDEVTYPE_REF : D3DDEVTYPE_HAL, hWnd, \ D3DCREATE_HARDWARE_VERTEXPROCESSING, &m_pparams, &g_pD3DDevice))) #endif { CON(MSG_ERR_FATAL, "Renderer: Can't create rendering device!\n\rTry restart or reinstall game...\n\rTry reinstall DirectX and graphic drivers..."); return false; } g_pResMgr = new CP3DResourceManager; g_pResMgr->Initialize(); g_pFrustum = (IP3DFrustum*)I_GetClass(IP3DRENDERER_FRUSTUM); if (g_pFrustum == NULL) { CON(MSG_ERR_FATAL, "Renderer: Can't obtain Frustum class!"); return false; } g_pMeshLoader = (IP3DMeshLoader*)I_GetClass(IP3DRENDERER_MESHLOADER); if (g_pMeshLoader == NULL) { CON(MSG_ERR_FATAL, "Renderer: Can't obtain MeshLoader!"); return false; } g_pAlphaManager = (IP3DAlphaManager*)I_GetClass(IP3DRENDERER_ALPHAMANAGER); if (g_pAlphaManager == NULL) { CON(MSG_ERR_FATAL, "Renderer: Can't obtain AlphaManager!"); return false; } g_pXML = (IP3DXML*)I_GetClass(IP3DENGINE_XML); if (g_pXML == NULL) { CON(MSG_ERR_FATAL, "Renderer: Can't obtain XML class!"); return false; } g_pMaterialManager = (IP3DMaterialManager*)I_GetClass(IP3DRENDERER_MATERIALMANAGER); if (g_pMaterialManager == NULL) { CON(MSG_ERR_FATAL, "Renderer: Can't obtain MaterialManager!"); return false; } float ViewportSize[2]; ViewportSize[0] = 1.0f / float(g_pEngSet.Width); ViewportSize[1] = 1.0f / float(g_pEngSet.Height); g_pMaterialManager->OnViewportSizeChange (ViewportSize); g_pPostProcessMgr = (IP3DPostprocessManager*)I_GetClass(IP3DRENDERER_POSTPROCESSMANAGER); if (g_pPostProcessMgr == NULL) { CON(MSG_ERR_FATAL, "Renderer: Can't obtain PostProcessManager!"); return false; } g_pPhysEngine = (IP3DPhysEngine*)I_GetClass(IP3DPHYS_PHYSENGINE); if (g_pPhysEngine == NULL) { CON(MSG_ERR_FATAL, "Renderer: Can't obtain Physics Engine Class!"); return false; } g_pLightManager = (IP3DLightManager*)I_GetClass(IP3DRENDERER_LIGHTMANAGER); if (g_pLightManager == NULL) { CON(MSG_ERR_FATAL, "Renderer: Can't obtain DynlightManager!"); return false; } if ( !g_TextureLoader.Init() ) { CON(MSG_ERR_FATAL, "Renderer: Can't initialize TextureLoader!"); return false; } g_pSoundMan = (IP3DSoundManager*)I_GetClass(IP3DSOUND_SOUNDMANAGER); if (g_pSoundMan == NULL) { CON(MSG_ERR_FATAL, "Renderer: Can't obtain SoundManager!"); return false; } SetDefaultRenderStates (); // nastavenie sampler states pre potreby shader modelu 3.0 g_pD3DDevice->SetSamplerState(4, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState(4, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState(4, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState(5, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState(5, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState(5, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState(6, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState(6, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState(6, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState(7, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState(7, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); g_pD3DDevice->SetSamplerState(7, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); // --- get original parameters g_pD3DDevice->GetGammaRamp(0, &m_origGama); // get default render target if(FAILED(g_pD3DDevice->GetRenderTarget(0, &m_pBackBufferSurf))) CON(MSG_CON_INFO, "Renderer: DX9 %d x %d %s initialized!", m_pparams.BackBufferWidth, m_pparams.BackBufferHeight, m_pparams.Windowed ? "windowed" : "fullscreen"); // nastavit callbacky ConVar-ov CVr_wireframe.SetChangeCallback(CV_wireframe); CVr_gamma.SetChangeCallback(&CP3DRenderer::CV_SetGamma); #ifdef _DEBUG g_stats.Init(); // STATS #endif ///////////////// tmpVertPosClr myvert[] = { {P3DXPoint3D(-50,0,0), P3DXPoint3D(1,0,0)}, {P3DXPoint3D(-50,50,0), P3DXPoint3D(0,1,0)}, {P3DXPoint3D(50,50,0), P3DXPoint3D(0,0,1)} }; P3DVertexElement ve[3]; ve[0] = P3DVertexElement(P3DVD_FLOAT3, P3DVU_POSITION); ve[1] = P3DVertexElement(P3DVD_FLOAT3, P3DVU_COLOR); ve[2] = P3DVE_END(); vb.CreateVB(3, ve, sizeof(tmpVertPosClr)); tmpVertPosClr *pv = 0; vb.Lock((void**)&pv); pv[0] = myvert[0]; pv[1] = myvert[1]; pv[2] = myvert[2]; vb.UnLock(); effect.Create("solid.fx"); //////////////// return true; }
// obnovenie lost device // je potrebne uvolnit vsetky zdroje, ktore su D3DPOOL_DEFAULT a znova ich obnovit //--------------------------------- void CP3DRenderer::OnLostDevice() { HRESULT hr; while ((hr = g_pD3DDevice->TestCooperativeLevel ()) == D3DERR_DEVICELOST) { // spracovanie sprav, napr. pre pripad uzatvorenia okna uzivatelom, bude to fungovat ??? // KEX: S NULL hwnd asi ne ;) ael asi ani neni potreba vubec MSG msg; while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage (&msg); DispatchMessage (&msg); if (msg.message == WM_QUIT) {PostQuitMessage (0); return;} } Sleep (10); } if (hr == S_OK) return; // ziadna chyba else if (hr == D3DERR_DRIVERINTERNALERROR) { CON (MSG_ERR_FATAL, "Internal driver error! Can't recover lost device. Try restart game."); return; } else if (hr != D3DERR_DEVICENOTRESET) return; // neznama chyba //teraz je mozne obnovit device /* Nasleduje uvolnenie vsetkych D3DPOOL_DEFAULT (video-memory) zdrojov - textury, VB, IB, atd. Okrem D3DPOOL_DEFAULT zdrojov je treba uvolnit aj pripadne vytvorene swap chains, render targets, depth stencil surfaces a state blocks. Zdroje v D3DPOOL_SYSTEMMEM alebo D3DPOOL_MANAGED nie potrebne obnovovat, pretoze sa nachadzaju v system memory, alebo su aspon v nej "zalohovane". Taktiez treba obnovit vsetky predosle "device states", shadery nie je treba obnovovat. Ak neboli uvolnene vsetky D3DPOOL_DEFAULT zdroje fcia g_pD3DDevice->Reset() bude neuspesna! Before calling the IDirect3DDevice9::Reset method for a device, an application should release any explicit render targets, depth stencil surfaces, additional swap chains, state blocks, and D3DPOOL_DEFAULT resources associated with the device. */ //uvolnenie zdrojov ... TODO: pridat !!! CON(MSG_ERR_FATAL, "OnLostDevice() not yet implemented, please don't use ALT+TAB!\r\nQuitting..."); exit(-1); //resetování zaøízení if (SUCCEEDED (g_pD3DDevice->Reset (&m_pparams))) { /* nasledujuci kod by mal byt rovnaky ako pri starte programu (vytvorenie zariadenia a zdrojov) s tym rozdielom, ze nie je potrebne znovu vytvarat D3DPOOL_SYSTEMMEM a D3DPOOL_MANAGED zdroje */ //obnovenie zdrojov ... TODO: pridat !!! // pridat pripadnu notifikaciu casti programu ktore to vyzaduju, napr. AlphaManager a pod. } SetDefaultRenderStates (); }
void Graphics::InitializeDirect3d() { HRESULT d3dresult; /* Set some global flags. */ if (config.useDirect3d9Ex) { logger->info("Using Direct3D9Ex mode"); d3dresult = D3DLOG(Direct3DCreate9Ex(D3D_SDK_VERSION, &mDirect3d9)); if (d3dresult != D3D_OK) { throw TempleException("Unable to create Direct3D9 interface."); } } else { logger->info("Using standard Direct3D9 mode"); mDirect3d9 = static_cast<IDirect3D9Ex*>(Direct3DCreate9(D3D_SDK_VERSION)); if (!mDirect3d9) { throw TempleException("Unable to create Direct3D9 interface."); } } /** START OF OLD WINDOWED INIT */ // At this point we only do a GetDisplayMode to check the resolution. We could also do this elsewhere D3DDISPLAYMODE displayMode; d3dresult = D3DLOG(mDirect3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)); if (d3dresult != D3D_OK) { throw TempleException("Unable to query display mode for primary adapter."); } // We need at least 1024x768 if (displayMode.Width < 1024 || displayMode.Height < 768) { throw TempleException("You need at least a display resolution of 1024x768."); } auto presentParams = CreatePresentParams(); // presentParams.MultiSampleType = D3DMULTISAMPLE_4_SAMPLES; // presentParams.MultiSampleQuality = 0; // Nvidia drivers seriously barf on D3d9ex if we use software vertex processing here, as ToEE specifies. // I think we are safe with hardware vertex processing, since HW T&L has been standard for more than 10 years. if (config.useDirect3d9Ex) { logger->info("Creating Direct3D9Ex device."); d3dresult = D3DLOG(mDirect3d9->CreateDeviceEx( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mMainWindow.GetHwnd(), D3DCREATE_HARDWARE_VERTEXPROCESSING, &presentParams, nullptr, &mDevice)); } else { logger->info("Creating Direct3D9 device."); d3dresult = D3DLOG(mDirect3d9->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, mMainWindow.GetHwnd(), D3DCREATE_HARDWARE_VERTEXPROCESSING, &presentParams, reinterpret_cast<IDirect3DDevice9**>(&mDevice))); } if (d3dresult != D3D_OK) { throw TempleException("Unable to create Direct3D9 device!"); } // TODO: color bullshit is not yet done (tig_d3d_init_handleformat et al) // Get the device caps for real this time. ReadCaps(); SetDefaultRenderStates(); CreateResources(); }
// Create the Sucka... bool CD3D_Device::CreateDevice(D3DAdapterInfo* pAdapter,D3DDeviceInfo* pDevice,D3DModeInfo* pMode) { FreeDevice(); // Make sure it's all released and groovie... m_pAdapter = pAdapter; // Initialization... m_pDevice = pDevice; m_pMode = pMode; // Create the sucka... uint32 BehaviorFlags = D3DCREATE_MULTITHREADED; if (pDevice->d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) BehaviorFlags |= D3DCREATE_MIXED_VERTEXPROCESSING; else BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; D3DPRESENT_PARAMETERS PresentationParam; SetPresentationParams(PresentationParam,pMode); IDirect3DDevice9 *pD3DDevice; HRESULT hResult = PDIRECT3D->CreateDevice(pAdapter->iAdapterNum,pDevice->DeviceType,g_hWnd,BehaviorFlags,&PresentationParam,&pD3DDevice); if ((hResult != D3D_OK) || !pD3DDevice) { // Give it more more try - Presentation params might have been changed by D3D to something acceptable... OUTPUT_D3D_ERROR(1,hResult); // Report the error... OutputDebugString("Warning: Create failed. Attempting to fall back...\n"); TryFallingBack_OnFailedDevCreate(&PresentationParam); hResult = PDIRECT3D->CreateDevice(pAdapter->iAdapterNum,pDevice->DeviceType,g_hWnd,BehaviorFlags,&PresentationParam,&pD3DDevice); if ((hResult != D3D_OK) || !pD3DDevice) { OUTPUT_D3D_ERROR(0,hResult); FreeDevice(); return false; } } // Create our wrapper, which we're going to present to the world as an actual D3D device LT_MEM_TRACK_ALLOC(m_pD3DDevice = new CDirect3DDevice9Wrapper,LT_MEM_TYPE_RENDERER); m_pD3DDevice->SetDevice(pD3DDevice); if (FAILED(m_pD3DDevice->GetDeviceCaps(&m_DeviceCaps))) { FreeDevice(); return false; } SetDefaultRenderStates(); // Set the default render states... PreCalcSomeDeviceCaps(); // Do some precalcing of device caps (figure out if we can do some puff)... m_pD3DDevice->SetStates(); // Display a warning message if (m_pDevice->DeviceType == D3DDEVTYPE_REF) AddDebugMessage(1,"Warning: Couldn\'t find any HAL devices, Using reference rasterizer"); //make sure to clear out the back buffer so it isn't filled with left over garbage LTRGBColor ClearColor; ClearColor.dwordVal = 0; d3d_Clear(NULL, CLEARSCREEN_SCREEN | CLEARSCREEN_RENDER, ClearColor); //create the end of frame query events PD3DDEVICE->CreateQuery(D3DQUERYTYPE_EVENT, &m_pEndOfFrameQuery); // Initialize the render target manager. CRenderTargetMgr::GetSingleton().Init(); return true; }