Archived

This topic is now archived and is closed to further replies.

Cybird

SwapChain problem

Recommended Posts

Well, i tried to implement SwapChains in Direct3d9. All the creation process is ok, without errors, but when i clear the device, it don´t clear the other windows. I´ll post all my code relative to this. //This is the window wrapper i use for my engine(header)
class __declspec(dllexport) CXeonWnd
{
	friend class CRenderer;
public:

	//Constructeur par defaut

	CXeonWnd(void);

	//Destructeur

	~CXeonWnd(void);

	//Gestion de la fenetre

	X3DRESULT Set ( HWND hWnd ); //Fenetre deja cree

	X3DRESULT Create ( char *strWindowTitle, RECT wndRect, bool bChild, bool bCreateSwapChain = false, CXeonWnd *pParent = NULL);
	X3DRESULT Destroy ();

	//Gestion des viewports	

	CViewport *CreateViewport ( RECT viewportRect );  //Creation	

	X3DRESULT DestroyViewport ( CViewport *pViewport ); //Destruction d''un viewport


	//Parametres de backbuffer relie a la fenetre

	X3DRESULT SetParameters ( CDocumentXML *pDoc );

	//Retourne les proprietes de la fenetre

	unsigned int GetWidth (); //Retourne le width de la fenetre

	unsigned int GetHeight (); //Retourne le height de la fenetre

	RECT GetRect(); //Retourne le rectangle de la fenetre


	//Retourne TRUE si il faut renderer le world dans cette fenetre

	bool DoRenderWorld() { return m_bRenderWorld; }

	//Clearing de la fenetre

	X3DRESULT Clear ();

	//Presentation du backbuffer de la fenetre

	X3DRESULT Present ();

	//Debut de la scene

	X3DRESULT BeginScene (  );

	//Fin de la scene

	X3DRESULT EndScene ( );

	//Retourne le handle de la fenetre

	HWND GetHandle () {return m_hWnd; }

		
protected:

	//Handle de la fenetre

	HWND m_hWnd;

	//Liste des viewports

	list<CViewport *> m_ViewportsList;

	//Flag indiquant si la fenetre est prete

	bool m_bReady;

	//Flag indiquant si le moteur doit renderer le world 

	bool m_bRenderWorld;
	
	//Swap chain

	LPDIRECT3DSWAPCHAIN9 m_pSwapChain;

	//Format des pixels

	PixelFormat m_PixelFormat;

	//Format du Depth Buffer

	DepthBufferFormat m_DepthBufferFormat;

	//Backbuffer de la fenetre

	LPDIRECT3DSURFACE9 m_pBackBuffer;

	//Stencil buffer de la fenetre

	LPDIRECT3DSURFACE9 m_pStencilBuffer;

	//Numero de la swap chain

	unsigned int m_iSwapChainID;

};
//Code for my window wrapper

//Destruction de la fenetre

X3DRESULT CXeonWnd::Destroy ()
{	
	return X3DRESULT_OK;
}

//Creation d''un viewport

CViewport *CXeonWnd::CreateViewport ( RECT viewportRect )
{
	//Assignation

	CViewport *pViewport = new CViewport ( );

	if ( ! pViewport )
		return NULL;

	m_ViewportsList.push_back ( pViewport );

	return pViewport;
}

//Destruction d''un viewport

X3DRESULT CXeonWnd::DestroyViewport ( CViewport *pViewport )
{
	std::list<CViewport *>::iterator i = m_ViewportsList.begin();

	//On doit parcourir la liste pour trouver le bon

	for( i; i != m_ViewportsList.end(); i++ )
	{
		CViewport *pVp = *i;

		//Si c le bon, on l''enleve de la liste

		if ( pVp == pViewport )
		{
			m_ViewportsList.remove( pVp );
			delete pVp;
			pVp = NULL;
		}
	}

	return X3DRESULT_OK;
}

//Parametres de backbuffer relie a la fenetre

X3DRESULT CXeonWnd::SetParameters ( CDocumentXML *pDoc )
{
	if ( ! pDoc )
		return X3DRESULT_FAILED;

	PixelFormat pf;
	DepthBufferFormat df;
			
	//Lecture des parametres de configurations a partir du fichier XML	


	std::string strPixelFormat;
	std::string strDepthBufferFormat;

	
	pDoc->GetStringTag("PixelFormat", strPixelFormat );
	pDoc->GetStringTag ("DepthBufferFormat", strDepthBufferFormat);

    //Comparaison des types pour le PixelFormat

	if ( strPixelFormat.compare( std::string ("X3D_PF_RGBA_32" ) ) == 0 )
		pf = X3D_PF_RGBA_32;
		else if ( strPixelFormat.compare( std::string ("X3D_PF_RGBA_16" ) ) == 0 )
				pf = X3D_PF_RGBA_16;
			else if ( strPixelFormat.compare( std::string ("X3D_PF_RGB_24" ) ) == 0 )
					pf = X3D_PF_RGB_24;

	//Comparaison des types pour DepthBufferFormat

	if ( strDepthBufferFormat.compare( std::string("X3D_DEPTH_15_STENCIL_1") ) == 0 )
		df = X3D_DEPTH_15_STENCIL_1;
		else if ( strDepthBufferFormat.compare( std::string("X3D_DEPTH_16_STENCIL_0") ) == 0 )
			df = X3D_DEPTH_16_STENCIL_0;
			else if ( strDepthBufferFormat.compare( std::string("X3D_DEPTH_32_STENCIL_0") ) == 0 )
				df = X3D_DEPTH_32_STENCIL_0;
				else if ( strDepthBufferFormat.compare( std::string("X3D_DEPTH_32_STENCIL_8") ) == 0 )
					df = X3D_DEPTH_32_STENCIL_8;


	m_PixelFormat = pf;
	m_DepthBufferFormat = df;

	return X3DRESULT_OK;
}

 //Retourne le width de la fenetre

unsigned int CXeonWnd::GetWidth ()
{
    RECT rect;
	GetWindowRect ( m_hWnd, &rect );

	return rect.right - rect.left;
}

 //Retourne le height de la fenetre

unsigned int CXeonWnd::GetHeight ()
{
	RECT rect;
	GetWindowRect ( m_hWnd, &rect );

	return rect.bottom - rect.top;
}

 //Retourne le rectangle de la fenetre

RECT CXeonWnd::GetRect()
{
	RECT rect;
	GetWindowRect ( m_hWnd, &rect );

	return rect;
}

//Clearing de la fenetre

X3DRESULT CXeonWnd::Clear ()
{
	CRenderer *pRenderer = CRenderer::GetInstance();

	//Si ce n''est pas une swapChain alors c la fenetre principale et il faut clearer la device

	if ( ! m_pSwapChain )
		pRenderer->Clear ();	

	return X3DRESULT_OK;
}

//Presentation du backbuffer de la fenetre

X3DRESULT CXeonWnd::Present ()
{
	CRenderer *pRenderer = CRenderer::GetInstance();

	//Si la fenetre est une swap Chain, presenter la swap chain

	HRESULT hr;
	if ( m_pSwapChain )
	{
		hr = m_pSwapChain->Present(NULL,NULL,NULL,NULL, 0);
			if ( FAILED (hr) )
			return X3DRESULT_FAILED;
	}
	else //Sinon, presenter tout le backbuffer

	{
		hr = pRenderer->Present ();
		if ( FAILED (hr) )
			return X3DRESULT_FAILED;
	}
		
	
	return X3DRESULT_OK;
}

//Debut de la scene

X3DRESULT CXeonWnd::BeginScene (  )
{
	CRenderer *pRenderer = CRenderer::GetInstance();

	//Si la fenetre est une swap chain, initialiser le bon renderTarget

	if ( m_pSwapChain )
	{
		if ( m_pBackBuffer && m_pStencilBuffer )
		{
			X3DRESULT result = pRenderer->SetRenderTarget ( m_pBackBuffer, m_pStencilBuffer );
			if ( result == X3DRESULT_FAILED )
				return result;
		}
		else return X3DRESULT_FAILED;
		}

	X3DRESULT result = pRenderer->BeginScene();
	return result;	
}

//Fin de la scene

X3DRESULT CXeonWnd::EndScene ( )
{
	CRenderer *pRenderer = CRenderer::GetInstance();
	
	//Fin de la scene

	return pRenderer->EndScene();	
}
this is the renderer header
class CRenderer
{
public:
	
	//Destructeur

	~CRenderer(void);

	//Retourne un pointeur vers l''unique instance du renderer

	static CRenderer *GetInstance ();

	//Register une XeonWnd pour qu''elle soit prete a renderer, que ce soit pour la creation de la device, ou

	//de une swap chain additionelle

	X3DRESULT RegisterWnd ( CXeonWnd *pWnd );

	//Clearing de la scene

	X3DRESULT Clear ();

	//Debut de la scene

	X3DRESULT BeginScene ();

	//Fin de la scene

	X3DRESULT EndScene ();

	//Presentation du BackBuffer

	X3DRESULT Present ();

	//Setting du RenderTarget

	X3DRESULT SetRenderTarget ( LPDIRECT3DSURFACE9 pBackBuffer, LPDIRECT3DSURFACE9 pDepthStencilBuffer );


protected:
	//Constructeur par defaut (protege dans le cas du singleton )

	CRenderer(void);

	//Pointeur vers l''instance

	static CRenderer *m_pRenderer;


	//Pointeur vers Direct3d

	LPDIRECT3D9 m_pDirect3d;

	//Pointeur vers la device

	LPDIRECT3DDEVICE9 m_pDevice;

	//Nombre de swapChains

	unsigned int m_iNbSwapChains;
};
this is the renderer source

//Instance unique du Singleton

CRenderer *CRenderer::m_pRenderer = 0;

//Constructeur par defaut

CRenderer::CRenderer(void)
{
	//Initialisation de direct3d 

	m_pDirect3d = Direct3DCreate9 ( D3D_SDK_VERSION );
	m_pDevice = NULL;
	m_iNbSwapChains = 1;
}


//Destructeur

CRenderer::~CRenderer(void)
{
}

//Retourne un pointeur vers l''unique instance du renderer

CRenderer * CRenderer::GetInstance ()
{
	if ( m_pRenderer == NULL )	
	{
		m_pRenderer = new CRenderer();
		return m_pRenderer;
	}

	else return m_pRenderer;	
}

//Registering de la / des fenetres

X3DRESULT CRenderer::RegisterWnd ( CXeonWnd *pWnd )
{
	if ( ! pWnd )
		return X3DRESULT_FAILED;

	//Remplissage des parametres de creation d3D

	D3DPRESENT_PARAMETERS d3dpp; 
	ZeroMemory( &d3dpp, sizeof(d3dpp) );
	d3dpp.Windowed = true;
	d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;	
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;	
	d3dpp.BackBufferCount = 3;
	
	//Setting du DepthBufferFormat de la fenetre

	switch ( pWnd->m_DepthBufferFormat )
	{
		case X3D_DEPTH_15_STENCIL_1:
			d3dpp.EnableAutoDepthStencil = true;
			d3dpp.AutoDepthStencilFormat = D3DFMT_D15S1;
			break;
		case X3D_DEPTH_16_STENCIL_0:
			d3dpp.EnableAutoDepthStencil = true;	
			d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
			break;

		case X3D_DEPTH_32_STENCIL_0:
			d3dpp.EnableAutoDepthStencil = true;			
			d3dpp.AutoDepthStencilFormat = D3DFMT_D32;
			break;

		case X3D_DEPTH_32_STENCIL_8:
			d3dpp.EnableAutoDepthStencil = true;			
			d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
			break;
		default:
			return X3DRESULT_FAILED;
	};

	
	//Setting du PixelFormat

	switch ( pWnd->m_PixelFormat )
	{
		case X3D_PF_RGBA_32:
			d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
			break;
		case X3D_PF_RGBA_16: 
			d3dpp.BackBufferFormat = D3DFMT_A4R4G4B4;
			break;
		case X3D_PF_RGB_24:
			d3dpp.BackBufferFormat = D3DFMT_R8G8B8;
			break;
		default:
			return X3DRESULT_FAILED;
			break;
	};	
	
	HRESULT hr;

	//Si la device est nulle, c que la fenetre est la fenetre parente de toutes les autres

	if ( m_pDevice == NULL )
	{	
		d3dpp.BackBufferWidth = pWnd->GetWidth();
		d3dpp.BackBufferHeight = pWnd->GetHeight();

		hr = m_pDirect3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, pWnd->m_hWnd,
					                        D3DCREATE_HARDWARE_VERTEXPROCESSING,
										    &d3dpp, &m_pDevice );
		if ( FAILED ( hr ) )
			return X3DRESULT_FAILED;

		pWnd->m_iSwapChainID = 0;

		//Initialisation du backbuffer

		hr = m_pDevice->GetBackBuffer( pWnd->m_iSwapChainID,
									   0,
									   D3DBACKBUFFER_TYPE_MONO, 
									   &pWnd->m_pBackBuffer);
		
		//Initialisation du Stencil Buffer		

		hr = m_pDevice->GetDepthStencilSurface( &pWnd->m_pStencilBuffer );
		if ( FAILED ( hr ) )
			return X3DRESULT_FAILED;

		


	}
	//Sinon, la device etait prealablement cree, cette fenetre est une swap-chain additionnelle

	else
	{
		hr = m_pDevice->CreateAdditionalSwapChain( &d3dpp, &pWnd->m_pSwapChain );
		if ( FAILED ( hr ) )
			return X3DRESULT_FAILED;

		m_iNbSwapChains++;
		
		//Initialisation du backbuffer

		hr = pWnd->m_pSwapChain->GetBackBuffer(0,
											   D3DBACKBUFFER_TYPE_MONO, 
											   &pWnd->m_pBackBuffer);
		if ( FAILED (hr ) )
			return X3DRESULT_FAILED;

		//Initialisation du Stencil Buffer		

		hr = m_pDevice->GetDepthStencilSurface( &pWnd->m_pStencilBuffer );
		if ( FAILED ( hr ) )
			return X3DRESULT_FAILED;

		pWnd->m_iSwapChainID = m_iNbSwapChains;
		
	}
	return X3DRESULT_OK;
}

//Clearing de la scene

X3DRESULT CRenderer::Clear ()
{
	HRESULT hr;
	hr = m_pDevice->Clear (0, NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0,255,0,0), 1.0f, 0 );

	if ( FAILED (hr) )
		return X3DRESULT_FAILED;

	return X3DRESULT_OK;
}

//Debut de la scene

X3DRESULT CRenderer::BeginScene ()
{
	HRESULT hr;

	hr = m_pDevice->BeginScene();
	
	if  (FAILED (hr) )
		return X3DRESULT_FAILED;

	return X3DRESULT_OK;
}

//Fin de la scene

X3DRESULT CRenderer::EndScene ()
{
	HRESULT hr;

	hr = m_pDevice->EndScene();

	if ( FAILED (hr) )
		return X3DRESULT_FAILED;

	return X3DRESULT_OK;
}

//Presentation du BackBuffer

X3DRESULT CRenderer::Present ()
{
	HRESULT hr;

	hr = m_pDevice->Present(NULL,NULL,NULL,NULL );

	if ( FAILED (hr) )
		return X3DRESULT_FAILED;

	return X3DRESULT_OK;
}

//Setting du RenderTarget

X3DRESULT CRenderer::SetRenderTarget ( LPDIRECT3DSURFACE9 pBackBuffer, LPDIRECT3DSURFACE9 pDepthStencilBuffer )
{
	if ( m_pDevice )
		if ( pBackBuffer)
		{
			HRESULT hr = m_pDevice->SetRenderTarget (0, pBackBuffer );
			if ( FAILED (hr) )
				return X3DRESULT_FAILED;

			if (pDepthStencilBuffer )
			{
				HRESULT hr = m_pDevice->SetDepthStencilSurface( pDepthStencilBuffer );
				if ( FAILED(hr) )
					return X3DRESULT_FAILED;
			}
		}
	return X3DRESULT_OK;
}

	

this is where all starts
//Creation d''une fenetre

CXeonWnd *CXeonEngine::CreateXeonWindow (char *strWindowTitle, RECT wndRect )
{
	CXeonWnd *pNewWindow = new CXeonWnd ();

	X3DRESULT result;

	//On ne doit pas ajouter de swapchains si c la premiere fenetre

	if ( m_WindowsList.size() == 0 )
	{
		//Creation de la fenetre

		result = pNewWindow->Create ( strWindowTitle, wndRect, false);
		if ( result == X3DRESULT_OK )
		{
			//Initialisation de ses parametre

			result = pNewWindow->SetParameters ( &m_Configurations );
			if ( result == X3DRESULT_FAILED )
			{
				delete pNewWindow;
				return NULL;
			}

			//La fenetre doit etre registree par le renderer

			result = m_pRenderer->RegisterWnd( pNewWindow );
			if ( result == X3DRESULT_FAILED )
			{
				delete pNewWindow;
				return NULL;
			}
			else			
			{
				//Ajout a la liste et retour du pointeur

				m_WindowsList.push_back ( pNewWindow );
				//bool bSuccess = ShowWindow( pNewWindow->GetHandle(), SW_SHOWDEFAULT);				

				return pNewWindow;		
			}
		}
		else 
		{
			delete pNewWindow;
			return NULL;	
		}
	}
	else
	{
		CXeonWnd *pParent = *m_WindowsList.begin();
		//Cette fenetre contient une swapChain

		result = pNewWindow->Create ( strWindowTitle, wndRect,true, true, pParent);
		if ( result == X3DRESULT_OK )
		{
			//Initialisation des parametres a partir du fichier de configurations

			result = pNewWindow->SetParameters ( &m_Configurations );
			if ( result == X3DRESULT_FAILED )
				return NULL;

			//La fenetre doit etre registree par le renderer

			result = m_pRenderer->RegisterWnd( pNewWindow );
			if ( result == X3DRESULT_FAILED )
			{
				delete pNewWindow;
				return NULL;
			}
			else			
			{
				//Ajout a la liste et retour du pointeur

				m_WindowsList.push_back ( pNewWindow );
				return pNewWindow;		
			}
		}
		else 
		{
			delete pNewWindow;
			return NULL;	
		}	
		
	}

}
I really don''t see the problem, so please check it out!

Share this post


Link to post
Share on other sites