示例#1
0
// restore re-activates the display device
//
bool Display::restore() {

    bool rc = false;

    if (d3dd) {
        HRESULT hr;
		hr = d3dd->TestCooperativeLevel();
		if (hr == D3DERR_DEVICENOTRESET)
			// reset the display device
			rc = d3dd->Reset(&d3dpp) == D3D_OK;
		else if (hr == S_OK)
			rc = true;
	}
	if (rc) {
		// reacquire sprite manager references to video memory
		if (scrManager) scrManager->OnResetDevice();
    }

	// complete the restoration
	if (rc) {
        setupProjection();
        setupLighting();
		setupBlending();
	}

    return rc;
}
示例#2
0
bool PrimitiveMaterialD3D::execute()
{
	DisplayDeviceD3D * pDeviceD3D = (DisplayDeviceD3D *)m_pDevice;
	if (! pDeviceD3D )
		return false;
	LPDIRECT3DDEVICE9 pD3DD = pDeviceD3D->m_pD3DD;
	if (! pD3DD )
		return false;
	// disable culling if doubleSided flag is true, enable CCW culling if false
	if ( pD3DD->SetRenderState( D3DRS_CULLMODE, m_DoubleSided ? D3DCULL_NONE : D3DCULL_CCW ) != D3D_OK)
		return false;

	setupBlending();

	if ( m_nPass == DisplayDevice::PRIMARY )
	{
		// write enabled for primary render pass
		pD3DD->SetRenderState( D3DRS_ZWRITEENABLE, D3DZB_TRUE );			
		pD3DD->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
	}
	else
	{
		// no write for secondary and background passes
		pD3DD->SetRenderState( D3DRS_ZWRITEENABLE, D3DZB_FALSE );			
		pD3DD->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
	}

	DisplayDeviceD3D::LightMap & lights = pDeviceD3D->m_Lights;

	// we use fixed function if lighting if disabled..
	if ( DisplayDevice::sm_bUseFixedFunction 
		|| !m_LightEnable 
		|| lights.size() == 0 
		|| m_Blending == PrimitiveMaterial::ADDITIVE )
	{
		pDeviceD3D->m_bUsingFixedFunction = true;
		// enable/disable lighting
		if ( pD3DD->SetRenderState( D3DRS_LIGHTING, m_LightEnable && lights.size() > 0 ) != D3D_OK )
			return false;
		// enable/disable specular highlighting
		if ( pD3DD->SetRenderState( D3DRS_SPECULARENABLE, (m_LightEnable && m_SpecularPower > 0.0f && sm_bEnableSpecular) ? TRUE : FALSE ) != D3D_OK)
			return false;

		D3DMATERIAL9 d3dm;
		d3dm.Diffuse = makeD3DCOLORVALUE( m_Diffuse );
		d3dm.Ambient = makeD3DCOLORVALUE( m_Ambient );
		d3dm.Emissive = makeD3DCOLORVALUE( m_Emissive );
		d3dm.Specular = makeD3DCOLORVALUE( m_Specular );
		d3dm.Power = m_SpecularPower;
		
		// apply shader if one has been set manually, needed for the HDR bloom effects..
		if ( m_pShader.valid() && m_pShader != pDeviceD3D->m_pDefaultShader )
			m_pShader->apply( pDeviceD3D );
		else
			pDeviceD3D->clearShaders();

		// set the material properties
		if ( pD3DD->SetMaterial( &d3dm ) != D3D_OK )
			return false;
		if (! setupTextureStatges() )
			return false;
		if (! executeChildren() )
			return false;
	}
	else
	{
		// turn off fixed function lighting..
		if ( pD3DD->SetRenderState( D3DRS_LIGHTING, FALSE ) != D3D_OK )
			return false;

		// update our pixel/vertex shaders if needed..
		if ( m_bUpdateShaders || !m_pShader.valid() || m_pShader->released() )
		{
			m_bUpdateShaders = false;

			m_pShader = NULL;
			if ( m_sShader.length() > 0 )
				m_pShader = pDeviceD3D->getShader( m_sShader );
			if (! m_pShader.valid() )
				m_pShader = pDeviceD3D->m_pDefaultShader;
		}

		if ( !m_pShader.valid() || m_pShader->released() )
			return false;

		pDeviceD3D->m_bUsingFixedFunction = false;
		pDeviceD3D->m_pMatShader = m_pShader;

		// setup shader constants for this material..
		m_pShader->setConstant( "vMatAmbient", m_Ambient );
		m_pShader->setConstant( "vMatDiffuse", m_Diffuse );
		m_pShader->setConstant( "vMatEmissive", m_Emissive );
		m_pShader->setConstant( "vMatSpecular", m_Specular );
		m_pShader->setConstant( "fMatSpecularPower", m_SpecularPower );
		// set global ambient light for the first lighting pass..
		m_pShader->setConstant( "vGlobalAmbient", pDeviceD3D->m_cAmbientLight );
		m_pShader->setConstant( "bEnableAmbient", true );
		m_pShader->setConstant( "szShadowMap", pDeviceD3D->m_szShadowMap );

		if (! setupTextureStatges() )
			return false;

		DisplayDeviceD3D::ShadowPassList::iterator iShadowPass = pDeviceD3D->m_ShadowPassList.begin();

		// set to alpha blending for the first pass...
		pD3DD->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
		pD3DD->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
		pD3DD->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);

		// we need to make a render pass for each light in the scene
		int nLightCount = 0;
		for( DisplayDeviceD3D::LightMap::iterator iLight = lights.begin(); 
			iLight != lights.end(); ++iLight, ++nLightCount )
		{
			if ( nLightCount >= sm_nMaxLights )
				break;
			D3DLIGHT9 & light = iLight->second;

			m_pShader->setConstant( "nLightType", (int)light.Type );
			if ( light.Type != D3DLIGHT_DIRECTIONAL )
				m_pShader->setConstant( "vLightPosition", light.Position );
			if ( light.Type != D3DLIGHT_POINT )
				m_pShader->setConstant( "vLightDirection", light.Direction );
			m_pShader->setConstant( "vLightDiffuse", light.Diffuse );
			m_pShader->setConstant( "vLightSpecular", light.Specular );
			m_pShader->setConstant( "vLightAmbient", light.Ambient );
			
			if ( light.Type == D3DLIGHT_POINT )
			{
				Vector3 vAttenation( light.Attenuation0, light.Attenuation1, light.Attenuation2 );
				m_pShader->setConstant( "vAttenuation", vAttenation );
			}

			if ( iShadowPass != pDeviceD3D->m_ShadowPassList.end() )
			{
				DisplayDeviceD3D::ShadowPass & pass = *iShadowPass;

				// yes we have a shadow map..
				m_pShader->setConstant( "bEnableShadowMap", true );
				m_pShader->setConstant( "mLightView", pass.m_LightView );
				m_pShader->setConstant( "mLightProj", pass.m_LightProj );
				// put our shadow map into slot 7, reserved specially for shadow maps..
				pD3DD->SetTexture( 7, pass.m_pShadowMap );
				pD3DD->SetSamplerState( 7, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
				pD3DD->SetSamplerState( 7, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
				pD3DD->SetSamplerState( 7, D3DSAMP_MAGFILTER, D3DTEXF_POINT );			// IMPORTANT: Turn off all filtering on the shadow map, the shader does the filtering..
				pD3DD->SetSamplerState( 7, D3DSAMP_MINFILTER, D3DTEXF_POINT );
				pD3DD->SetSamplerState( 7, D3DSAMP_MIPFILTER, D3DTEXF_POINT );

				++iShadowPass;
			}
			else
				m_pShader->setConstant( "bEnableShadowMap", false );

			// apply the shader and upload all constants for rendering..
			if (! m_pShader->apply( pDeviceD3D ) )
				return false;
			// render geometry..
			if (! executeChildren() )
				return false;

			if ( nLightCount == 0 )
			{
				// after the first light, switch to additive blending mode..
				pD3DD->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA );
				pD3DD->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE );
				// disable ambient in the shader, so the colors don't accumulate per light..
				m_pShader->setConstant( "bEnableAmbient", false );
			}
		}
	}

	return true;
}
示例#3
0
// setup creates the display device according to the context
// parameters and associates the device with the application window
// (HWND)hwnd
//
bool Display::setup(void* hwnd) {

    bool rc = false;

	// store address of main application window
    this->hwnd = (HWND)hwnd;

    // set the D3D presentation parameters
    UINT adapter;
	D3DFORMAT d3dFormat;
    ZeroMemory(&d3dpp, sizeof d3dpp);
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferCount = 1;
    d3dpp.EnableAutoDepthStencil = TRUE;
    D3DDISPLAYMODE d3ddm;
    if (!runInWindow) {
		D3DFORMAT Format[] = D3D_DOC_FORMATS;
		d3dFormat = Format[pixel];
        if (FAILED(d3d->EnumAdapterModes(display, d3dFormat, mode, &d3ddm))) {
            error(L"Display::10 Failed to get selected display mode");
            error(L"Display::11 Defaulting to windowed mode");
            runInWindow = true;
        }
        else {
            adapter = display;
            d3dpp.BackBufferWidth  = d3ddm.Width;
            d3dpp.BackBufferHeight = d3ddm.Height;
            d3dpp.BackBufferFormat = d3ddm.Format;
            d3dpp.FullScreen_RefreshRateInHz = d3ddm.RefreshRate;
            width  = d3ddm.Width;
            height = d3ddm.Height;
        }
    }
    if (runInWindow) {
        adapter = D3DADAPTER_DEFAULT;
		d3d->GetAdapterDisplayMode(adapter, &d3ddm);
		d3dFormat = d3ddm.Format;
        d3dpp.Windowed = TRUE;
		d3dpp.BackBufferWidth  = WND_WIDTH;
		d3dpp.BackBufferHeight = WND_HEIGHT;
		d3dpp.BackBufferFormat = d3dFormat;
        width  = WND_WIDTH;
        height = WND_HEIGHT;
    }
	aspect = (float) width / height;
    context->set(GF_FR_ASP, aspect);

    // find the best format for depth buffering and stenciling
    //
    D3DDEVTYPE devtype;
    if (D3D_OK == d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL,
     d3dFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D32)) {
        d3dpp.AutoDepthStencilFormat = D3DFMT_D32; // depth buffer
        devtype = D3DDEVTYPE_HAL;                  // HAL device   
    }
    else if (D3D_OK == d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, 
     d3dFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16)) {
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;  // depth buffer
        devtype = D3DDEVTYPE_HAL;                   // HAL Device
    }
    // if the above attempts fail, use the REF (software emulation) device
    // with a 32-bit depth buffer rather than the HAL (hardware accelerated) 
	// device
    else if (D3D_OK == d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_REF,
     d3dFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D32)) {
        d3dpp.AutoDepthStencilFormat = D3DFMT_D32;   // depth buffer
        devtype = D3DDEVTYPE_REF;                    // REF Device
    }
    // if all else fails, use the REF (software emulation) with a 16-bit
    // depth buffer, hoping that it will work. (If it doesn't, we are out
    // of luck anyway.)
    else {
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;   // depth buffer
        devtype = D3DDEVTYPE_REF;                    // REF Device
    }

    // extract the device capabilities and configure the limits
    D3DCAPS9 caps;
    d3d->GetDeviceCaps(adapter, devtype, &caps);

	// hardware or software vertex processing?
	DWORD behaviorFlags;
	if ((caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0)
	    behaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
	else
	    behaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;

    // retrieve the Interface to the D3D display device
    if (d3dd)
        error(L"Display::11 Pointer to Direct3D interface is not NULL");
    else if (FAILED(d3d->CreateDevice(adapter, devtype, (HWND)hwnd, 
	 behaviorFlags, &d3dpp, &d3dd)))
        error(L"Display::12 Failed to create Direct3D device");
    else {
        // maximum number of lights supported by the display device
		maxLights = caps.MaxActiveLights ? caps.MaxActiveLights : MAX_ACTIVE_LIGHTS;
        // set anisotropic filtering to the maximum available on the device
        if (FAILED(d3dd->SetSamplerState(0, D3DSAMP_MAXANISOTROPY,
         caps.MaxAnisotropy - 1)))
            error(L"Display::17 Failed to set up anisotropic filtering");

		// create a sprite COM object to manage the drawing of the hud texture
		// and the drawing of the text item fonts
		if (!scrManager && FAILED(D3DXCreateSprite(d3dd, &scrManager)))
			error(L"Display::18 Failed to create the sprite manager");

		// setup successful
        APILight::connectsThrough(d3dd);
        d3dd->AddRef();
        APITexture::connectsThrough(d3dd);
        d3dd->AddRef();
        APIGraphic::connectsThrough(d3dd);
        d3dd->AddRef();
        APIText::connectsThrough(d3dd);
        d3dd->AddRef();
        APITexture::isManagedBy(scrManager);
        scrManager->AddRef();
        APIText::isManagedBy(scrManager);
        scrManager->AddRef();
        APITexture::hasClientArea(width, height);
        APIText::hasClientArea(width, height);
        rc = true;
    }

	// complete the setup
	if (rc) {
        setupProjection();
        setupLighting();
		setupBlending();
	}

    return rc;
}
示例#4
0
// setup creates the display device according to the context
// parameters and associates the device with the application window
// (HWND)hwnd
//
bool Display::setup(void* hwnd) {

    bool rc = false;

	// store address of main application window
    this->hwnd = (HWND)hwnd;

    // set the D3D presentation parameters
    UINT adapter;
	D3DFORMAT d3dFormat;
    ZeroMemory(&d3dpp, sizeof d3dpp);
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferCount = 1;
    d3dpp.EnableAutoDepthStencil = TRUE;
    D3DDISPLAYMODE d3ddm;
    if (!runInWindow) {
		D3DFORMAT Format[] = D3D_DOC_FORMATS;
		d3dFormat = Format[pixel];
        if (FAILED(d3d->EnumAdapterModes(display, d3dFormat, mode, &d3ddm))) {
            error(L"Display::10 Failed to get selected display mode");
            error(L"Display::11 Defaulting to windowed mode");
            runInWindow = true;
        }
        else {
            adapter = display;
            d3dpp.BackBufferWidth  = d3ddm.Width;
            d3dpp.BackBufferHeight = d3ddm.Height;
            d3dpp.BackBufferFormat = d3ddm.Format;
            d3dpp.FullScreen_RefreshRateInHz = d3ddm.RefreshRate;
            width_  = d3ddm.Width;
            height_ = d3ddm.Height;
        }
    }
    if (runInWindow) {
        adapter = D3DADAPTER_DEFAULT;
		d3d->GetAdapterDisplayMode(adapter, &d3ddm);
		d3dFormat = d3ddm.Format;
        d3dpp.Windowed = TRUE;
		d3dpp.BackBufferWidth  = WND_WIDTH;
		d3dpp.BackBufferHeight = WND_HEIGHT;
		d3dpp.BackBufferFormat = d3dFormat;
        width_  = WND_WIDTH;
        height_ = WND_HEIGHT;
    }
	aspect = (float) width_ / height_;

    // find the best format for depth buffering and stenciling
    //
    D3DDEVTYPE devtype;
    if (D3D_OK == d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL,
     d3dFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D32)) {
        d3dpp.AutoDepthStencilFormat = D3DFMT_D32; // depth buffer
        devtype = D3DDEVTYPE_HAL;                  // HAL device   
    }
    else if (D3D_OK == d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, 
     d3dFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16)) {
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;  // depth buffer
        devtype = D3DDEVTYPE_HAL;                   // HAL Device
    }
    // if the above attempts fail, use the REF (software emulation) device
    // with a 32-bit depth buffer rather than the HAL (hardware accelerated) 
	// device
    else if (D3D_OK == d3d->CheckDeviceFormat(adapter, D3DDEVTYPE_REF,
     d3dFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D32)) {
        d3dpp.AutoDepthStencilFormat = D3DFMT_D32;   // depth buffer
        devtype = D3DDEVTYPE_REF;                    // REF Device
    }
    // if all else fails, use the REF (software emulation) with a 16-bit
    // depth buffer, hoping that it will work. (If it doesn't, we are out
    // of luck anyway.)
    else {
        d3dpp.AutoDepthStencilFormat = D3DFMT_D16;   // depth buffer
        devtype = D3DDEVTYPE_REF;                    // REF Device
    }

    // extract the device capabilities and configure the limits
    D3DCAPS9 caps;
    d3d->GetDeviceCaps(adapter, devtype, &caps);
	DWORD behaviorFlags;
	// hardware or software vertex processing?
	if ((caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
	 caps.VertexShaderVersion < D3DVS_VERSION(1,1))
	    behaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
	else
	    behaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
    // retrieve the Interface to the D3D display device
    if (d3dd)
        error(L"Display::11 Pointer to Direct3D interface is not NULL");
    else if (FAILED(d3d->CreateDevice(adapter, devtype, (HWND)hwnd, 
	 behaviorFlags, &d3dpp, &d3dd)))
        error(L"Display::12 Failed to create Direct3D device");
    else {
        // maximum number of lights supported by the display device
		maxLights = caps.MaxActiveLights ? caps.MaxActiveLights : 8;
        // set anisotropic filtering to the maximum available on the device
        if (FAILED(d3dd->SetSamplerState(0, D3DSAMP_MAXANISOTROPY,
         caps.MaxAnisotropy - 1)))
            error(L"Display::13 Failed to set up anisotropic filtering");

		// create a sprite COM object to manage the drawing of the hud texture
		// and the drawing of the text item fonts
		if (!spriteManager_ && FAILED(D3DXCreateSprite(d3dd, &spriteManager_)))
			error(L"Display::14 Failed to create the font manager");

		// setup successful
        rc = true;
    }
	//setup fog
	if (caps.RasterCaps & D3DPRASTERCAPS_FOGRANGE)
	{
		//configure fog distances and thickness
		float fogStart = FOGSTART_DEFAULT;
		float fogEnd = FOGEND_DEFAULT;

		//enable fog
		d3dd->SetRenderState(D3DRS_FOGENABLE,TRUE);
		
		//enable ranged base fog
		d3dd->SetRenderState(D3DRS_RANGEFOGENABLE,TRUE);

		//configure fog color
		d3dd->SetRenderState(D3DRS_FOGCOLOR,FOGCOLOR_DEFAULT);
		
		//set fog to be vertex fog using linear fog formula
		d3dd->SetRenderState(D3DRS_FOGVERTEXMODE,D3DFOG_LINEAR);

		//set fog distances and thickness
		d3dd->SetRenderState(D3DRS_FOGSTART,*(DWORD*)(&fogStart));
		d3dd->SetRenderState(D3DRS_FOGEND,*(DWORD*)(&fogEnd));
	
	}
	// complete the setup
	if (rc) {
        setupProjection();
        setupLighting();
		setupBlending();
	}

    return rc;
}