예제 #1
0
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();
}
예제 #2
0
//-----------------------------------------------------------------------------
// 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();
}