void GFXGLDevice::init( const GFXVideoMode &mode, PlatformWindow *window ) { AssertFatal(window, "GFXGLDevice::init - no window specified, can't init device without a window!"); PlatformWindowSDL* sdlWindow = dynamic_cast<PlatformWindowSDL*>(window); AssertFatal(sdlWindow, "Window is not a valid PlatformWindowSDL object"); // Create OpenGL context mContext = PlatformGL::CreateContextGL( sdlWindow ); PlatformGL::MakeCurrentGL( sdlWindow, mContext ); loadGLCore(); loadGLExtensions(mContext); // It is very important that extensions be loaded before we call initGLState() initGLState(); mProjectionMatrix.identity(); mInitialized = true; deviceInited(); }
//----------------------------------------------------------------------------- // Initialize - create window, device, etc //----------------------------------------------------------------------------- void GFXPCD3D9Device::init( const GFXVideoMode &mode, PlatformWindow *window /* = NULL */ ) { AssertFatal(window, "GFXPCD3D9Device::init - must specify a window!"); initD3DXFnTable(); HWND winHwnd = (HWND)window->getSystemWindow( PlatformWindow::WindowSystem_Windows ); AssertISV(winHwnd, "GFXPCD3D9WindowTarget::initPresentationParams() - no HWND"); // Create D3D Presentation params D3DPRESENT_PARAMETERS d3dpp = setupPresentParams( mode, winHwnd ); mMultisampleType = d3dpp.MultiSampleType; mMultisampleLevel = d3dpp.MultiSampleQuality; #ifndef TORQUE_SHIPPING bool usePerfHud = GFXPCD3D9Device::mEnableNVPerfHUD || Con::getBoolVariable("$Video::useNVPerfHud", false); #else bool usePerfHud = false; #endif HRESULT hres = E_FAIL; if ( usePerfHud ) { hres = createDevice( mD3D->GetAdapterCount() - 1, D3DDEVTYPE_REF, winHwnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp); } else { // Vertex processing was changed from MIXED to HARDWARE because of the switch to a pure D3D device. // Set up device flags from our compile flags. U32 deviceFlags = 0; deviceFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING; // Currently, offscreen rendering is only used by WPF apps and we need to create with D3DCREATE_MULTITHREAD for it // In all other cases, you can do better by locking/creating resources in the primary thread // and passing them to worker threads. if (window->getOffscreenRender()) { deviceFlags |= D3DCREATE_MULTITHREADED; d3dpp.Windowed = TRUE; d3dpp.BackBufferHeight = 1; d3dpp.BackBufferWidth = 1; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; } // DirectX will switch the floating poing control word to single precision // and disable exceptions by default. There are a few issues with this... // // 1. It can cause rendering problems when running in WPF. // 2. Firefox embedding issues. // 3. Physics engines depend on the higher precision. // // Interestingly enough... DirectX 10 and 11 do not modifiy the floating point // settings and are always in full precision. // // The down side is we supposedly loose some performance, but so far i've not // seen a measurable impact. // deviceFlags |= D3DCREATE_FPU_PRESERVE; // Try to do pure, unless we're doing debug (and thus doing more paranoid checking). #ifndef TORQUE_DEBUG_RENDER deviceFlags |= D3DCREATE_PUREDEVICE; #endif hres = createDevice( mAdapterIndex, D3DDEVTYPE_HAL, winHwnd, deviceFlags, &d3dpp); if (FAILED(hres) && hres != D3DERR_OUTOFVIDEOMEMORY) { Con::errorf(" Failed to create hardware device, trying mixed device"); // turn off pure deviceFlags &= (~D3DCREATE_PUREDEVICE); // try mixed mode deviceFlags &= (~D3DCREATE_HARDWARE_VERTEXPROCESSING); deviceFlags |= D3DCREATE_MIXED_VERTEXPROCESSING; hres = createDevice( mAdapterIndex, D3DDEVTYPE_HAL, winHwnd, deviceFlags, &d3dpp); // try software if (FAILED(hres) && hres != D3DERR_OUTOFVIDEOMEMORY) { Con::errorf(" Failed to create mixed mode device, trying software device"); deviceFlags &= (~D3DCREATE_MIXED_VERTEXPROCESSING); deviceFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; hres = createDevice( mAdapterIndex, D3DDEVTYPE_HAL, winHwnd, deviceFlags, &d3dpp); if (FAILED(hres) && hres != D3DERR_OUTOFVIDEOMEMORY) Con::errorf(" Failed to create software device, giving up"); D3D9Assert(hres, "GFXPCD3D9Device::init - CreateDevice failed!"); } } } // Gracefully die if they can't give us a device. if(!mD3DDevice) { if (hres == D3DERR_OUTOFVIDEOMEMORY) { char errorMsg[4096]; dSprintf(errorMsg, sizeof(errorMsg), "Out of video memory. Close other windows, reboot, and/or upgrade your video card drivers. Your video card is: %s", getAdapter().getName()); Platform::AlertOK("DirectX Error", errorMsg); } else { Platform::AlertOK("DirectX Error!", "Failed to initialize Direct3D! Make sure you have DirectX 9 installed, and " "are running a graphics card that supports Pixel Shader 1.1."); } Platform::forceShutdown(1); } // Check up on things Con::printf(" Cur. D3DDevice ref count=%d", mD3DDevice->AddRef() - 1); mD3DDevice->Release(); mTextureManager = new GFXD3D9TextureManager( mD3DDevice, mAdapterIndex ); // Now reacquire all the resources we trashed earlier reacquireDefaultPoolResources(); // Setup default states initStates(); //-------- Output init info --------- D3DCAPS9 caps; mD3DDevice->GetDeviceCaps( &caps ); U8 *pxPtr = (U8*) &caps.PixelShaderVersion; mPixVersion = pxPtr[1] + pxPtr[0] * 0.1; if (mPixVersion >= 2.0f && mPixVersion < 3.0f && caps.PS20Caps.NumTemps >= 32) mPixVersion += 0.2f; else if (mPixVersion >= 2.0f && mPixVersion < 3.0f && caps.PS20Caps.NumTemps >= 22) mPixVersion += 0.1f; Con::printf( " Pix version detected: %f", mPixVersion ); if ( smForcedPixVersion >= 0.0f && smForcedPixVersion < mPixVersion ) { mPixVersion = smForcedPixVersion; Con::errorf( " Forced pix version: %f", mPixVersion ); } U8 *vertPtr = (U8*) &caps.VertexShaderVersion; F32 vertVersion = vertPtr[1] + vertPtr[0] * 0.1; Con::printf( " Vert version detected: %f", vertVersion ); // The sampler count is based on the shader model and // not found in the caps. // // MaxSimultaneousTextures is only valid for fixed // function rendering. // if ( mPixVersion >= 2.0f ) mNumSamplers = 16; else if ( mPixVersion >= 1.4f ) mNumSamplers = 6; else if ( mPixVersion > 0.0f ) mNumSamplers = 4; else mNumSamplers = caps.MaxSimultaneousTextures; // This shouldn't happen until SM5 or some other // radical change in GPU hardware occurs. AssertFatal( mNumSamplers <= TEXTURE_STAGE_COUNT, "GFXPCD3D9Device::init - Sampler count greater than TEXTURE_STAGE_COUNT!" ); Con::printf( " Maximum number of simultaneous samplers: %d", mNumSamplers ); // detect max number of simultaneous render targets mNumRenderTargets = caps.NumSimultaneousRTs; Con::printf( " Number of simultaneous render targets: %d", mNumRenderTargets ); // detect occlusion query support if (SUCCEEDED(mD3DDevice->CreateQuery( D3DQUERYTYPE_OCCLUSION, NULL ))) mOcclusionQuerySupported = true; Con::printf( " Hardware occlusion query detected: %s", mOcclusionQuerySupported ? "Yes" : "No" ); Con::printf( " Using Direct3D9Ex: %s", isD3D9Ex() ? "Yes" : "No" ); mCardProfiler = new GFXD3D9CardProfiler(mAdapterIndex); mCardProfiler->init(); gScreenShot = new ScreenShotD3D; // Set the video capture frame grabber. mVideoFrameGrabber = new VideoFrameGrabberD3D9(); VIDCAP->setFrameGrabber( mVideoFrameGrabber ); // Grab the depth-stencil... SAFE_RELEASE(mDeviceDepthStencil); D3D9Assert(mD3DDevice->GetDepthStencilSurface(&mDeviceDepthStencil), "GFXD3D9Device::init - couldn't grab reference to device's depth-stencil surface."); mInitialized = true; deviceInited(); // Uncomment to dump out code needed in initStates, you may also need to enable the reference device (get rid of code in initStates first as well) // regenStates(); }
void GFXGLDevice::init( const GFXVideoMode &mode, PlatformWindow *window ) { AssertFatal(window, "GFXGLDevice::init - no window specified, can't init device without a window!"); AssertFatal(dynamic_cast<Win32Window*>(window), "Invalid window class type!"); HWND hwnd = GETHWND(window); mWindowRT = &static_cast<Win32Window*>(window)->mTarget; RECT rect; GetClientRect(hwnd, &rect); Point2I resolution; resolution.x = rect.right - rect.left; resolution.y = rect.bottom - rect.top; // Create a device context HDC hdcGL = GetDC( hwnd ); AssertFatal( hdcGL != NULL, "Failed to create device context" ); // Create pixel format descriptor... PIXELFORMATDESCRIPTOR pfd; CreatePixelFormat( &pfd, 32, 0, 0, false ); // 32 bit color... We do not need depth or stencil, OpenGL renders into a FBO and then copy the image to window if( !SetPixelFormat( hdcGL, ChoosePixelFormat( hdcGL, &pfd ), &pfd ) ) { AssertFatal( false, "GFXGLDevice::init - cannot get the one and only pixel format we check for." ); } int OGL_MAJOR = 3; int OGL_MINOR = 2; #if TORQUE_DEBUG int debugFlag = WGL_CONTEXT_DEBUG_BIT_ARB; #else int debugFlag = 0; #endif if( gglHasWExtension(ARB_create_context) ) { int const create_attribs[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, OGL_MAJOR, WGL_CONTEXT_MINOR_VERSION_ARB, OGL_MINOR, WGL_CONTEXT_FLAGS_ARB, /*WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB |*/ debugFlag, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, //WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0 }; mContext = wglCreateContextAttribsARB(hdcGL, 0, create_attribs); if(!mContext) { AssertFatal(0,""); } } else mContext = wglCreateContext( hdcGL ); if( !wglMakeCurrent( hdcGL, (HGLRC)mContext ) ) AssertFatal( false , "GFXGLDevice::init - cannot make our context current. Or maybe we can't create it." ); loadGLCore(); loadGLExtensions(hdcGL); wglSwapIntervalEXT(0); // It is very important that extensions be loaded // before we call initGLState() initGLState(); mProjectionMatrix.identity(); mInitialized = true; deviceInited(); }