problem in resizing the swapchain buffers

Started by
12 comments, last by Mohammed Abdulmonem 9 years, 7 months ago

this is in 640 x 480 window picture

http://prntscr.com/4emyyi

this is when switching to full screen mode

http://prntscr.com/4emzab

this is the resizing code


void Game::onResize(){
	RECT rc;
	GetClientRect(_hwnd,&rc);
	width=rc.right - rc.left;
	height=rc.bottom - rc.top;
	Directx11 :: onResize();  //swapchain new setting
	XMMATRIX Pro=XMMatrixPerspectiveFovLH((float)3.14 / 4,AspectRatio(),1.0f,1000.0f);
	XMStoreFloat4x4(&Proj,Pro);
}

Directx11::onresize()


void Directx11::onResize(){
	RECT rc;
	GetClientRect(_hwnd,&rc);
	width = rc.right - rc.left;
	height = rc.bottom - rc.top;
	swapchain -> ResizeBuffers(1,width,height,DXGI_FORMAT_R8G8B8A8_UNORM,0);
	ReleaseCOM(RenderTarget);
	ReleaseCOM(depth);
	ReleaseCOM(depthview);
	ID3D11Texture2D *back;
	HR(swapchain ->GetBuffer(0,__uuidof(ID3D11Texture2D),reinterpret_cast <void**> (&back)));
	HR(d3dDevice -> CreateRenderTargetView(back,0,&RenderTarget));
	D3D11_TEXTURE2D_DESC desc;
	ZeroMemory(&desc,sizeof(D3D11_TEXTURE2D_DESC));
	desc.ArraySize=1;
	desc.BindFlags=D3D11_BIND_DEPTH_STENCIL;
	desc.Format=DXGI_FORMAT_D24_UNORM_S8_UINT;
	desc.MipLevels=1;
	desc.Width= width;
	desc.Height=height;
	if (m4xMsaaEnable)
	{
		desc.SampleDesc.Count = 4;
		desc.SampleDesc.Quality=m4xMsaaQuality-1;
	}
	else
	{
		desc.SampleDesc.Count = 1;
		desc.SampleDesc.Quality=0;
	}
	HR(d3dDevice->CreateTexture2D(&desc,0,&depthview));
	HR(d3dDevice-> CreateDepthStencilView(depthview,0,&depth));
	d3dDeviceContext->OMSetRenderTargets(1,&RenderTarget,depth);
	D3D11_VIEWPORT vp;
	vp.TopLeftX=0.0f;
	vp.TopLeftY=0.0f;
	vp.Width = static_cast <float> (width);
	vp.Height= static_cast <float> (height);
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	d3dDeviceContext -> RSSetViewports(1,&vp);
}
Advertisement

First problem I can see is that you should release your stuff before calling ResizeBuffers, not after. See http://msdn.microsoft.com/en-us/library/windows/desktop/bb174577%28v=vs.85%29.aspx

You can't resize a swap chain unless you release all outstanding references to its back buffers. You must release all of its direct and indirect references on the back buffers in order for ResizeBuffers to succeed.

Calling ID3D11DeviceContext::ClearState is also advisable to ensure that everything that needs to be cleared out is cleared out.

Get those right first and see if your problem continues, then post an update please.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

i tried it ....no changes

still the same problem


i tried it ....no changes

What does "it" mean? Did you release resources before resizing, call ClearState, or both? Post the revised code.

How do you set the window to fullscreen?

Also, from your posted pix, it appears that the eye-point (view matrix) has changed between the two screen shots. Where/how do you change the view matrix?

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

It looks good aside from releasing your stuff after the resize instead of before. Maybe the value returned by AspectRatio() is off?

Try replacing it with ( float )width / ( float )height.

yes i release the stuff and called d3ddevicecontext->ClearState() before resizing ....do you have to change the view matrix?....i thought Directx updates coordantes scaling when you call swapchain->rsizebuffers()....if so i suppose i dont need to change the view matrix.....

It looks good aside from releasing your stuff after the resize instead of before. Maybe the value returned by AspectRatio() is off?

Try replacing it with ( float )width / ( float )height.

AspectRatio() is


float AspectRatio()const{
		return static_cast <float> (width) / height;
	} 

here is the code for resizing......


void Directx11::onResize(){
	RECT rc;
	GetClientRect(_hwnd,&rc);
	width = rc.right - rc.left;
	height = rc.bottom - rc.top;
	ReleaseCOM(RenderTarget);
	ReleaseCOM(depth);
	ReleaseCOM(depthview);
	d3dDeviceContext->ClearState();
	swapchain -> ResizeBuffers(1,width,height,DXGI_FORMAT_R8G8B8A8_UNORM,0);
	ID3D11Texture2D *back;
	HR(swapchain ->GetBuffer(0,__uuidof(ID3D11Texture2D),reinterpret_cast <void**> (&back)));
	HR(d3dDevice -> CreateRenderTargetView(back,0,&RenderTarget));
	D3D11_TEXTURE2D_DESC desc;
	ZeroMemory(&desc,sizeof(D3D11_TEXTURE2D_DESC));
	desc.ArraySize=1;
	desc.BindFlags=D3D11_BIND_DEPTH_STENCIL;
	desc.Format=DXGI_FORMAT_D24_UNORM_S8_UINT;
	desc.MipLevels=1;
	desc.Width= width;
	desc.Height=height;
	if (m4xMsaaEnable)
	{
		desc.SampleDesc.Count = 4;
		desc.SampleDesc.Quality=m4xMsaaQuality-1;
	}
	else
	{
		desc.SampleDesc.Count = 1;
		desc.SampleDesc.Quality=0;
	}
	HR(d3dDevice->CreateTexture2D(&desc,0,&depthview));
	HR(d3dDevice-> CreateDepthStencilView(depthview,0,&depth));
	d3dDeviceContext->OMSetRenderTargets(1,&RenderTarget,depth);
	D3D11_VIEWPORT vp;
	vp.TopLeftX=0.0f;
	vp.TopLeftY=0.0f;
	vp.Width = static_cast <float> (width);
	vp.Height= static_cast <float> (height);
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	d3dDeviceContext -> RSSetViewports(1,&vp);
}

i thought Directx updates coordantes scaling when you call swapchain->rsizebuffers()....if so i suppose i dont need to change the view matrix....

1. With regard to "update" of coordinate scaling: No. ResizeBuffers doesn't change the the viewport, or world, projection and view matrices.

2. I didn't say you NEED to change the view matrix. As you suspect, you shouldn't need to. I said, from the pictures, it appears you DID change it. The small green cube appears in a different relationship to the wireframe cube in that view. If you change nothing but the backbuffer and window client sizes, do your drawing using 3D world coordinates, and use the same world/view/projection matrices, the scene should look the same (ignoring aspect ratio). So the second picture appears to have been rendered with a different world or view or projection matrix.

If your posted code works correctly (and it seems to be correct now), then the problem lies elsewhere. We can't help you unless you provide more information. If you post code as requested, at worst, it will indicate other areas that are not the problem and help narrow the search.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

ok ..this the initialization routine


bool Directx11::init(HINSTANCE hinst,HWND hw){
	_hinst=hinst;_hwnd=hw;
	RECT rc;
	GetClientRect(_hwnd,&rc);
	height= rc.bottom - rc.top;
	width = rc.right - rc.left;
	UINT flags=0;
#ifdef _DEBUG
	flags |=D3D11_CREATE_DEVICE_DEBUG;
#endif
	HR(D3D11CreateDevice(0,_driverType,0,flags,0,0,D3D11_SDK_VERSION,&d3dDevice,&_featureLevel,&d3dDeviceContext));
	if (d3dDevice == 0 || d3dDeviceContext == 0)
		return 0;
	DXGI_SWAP_CHAIN_DESC sdesc;
	HR(d3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM,4,&m4xMsaaQuality));
	m4xMsaaEnable=true;
	ZeroMemory(&sdesc,sizeof(DXGI_SWAP_CHAIN_DESC));
	sdesc.Windowed=true;
	sdesc.BufferCount=1;
	sdesc.BufferDesc.Format=DXGI_FORMAT_R8G8B8A8_UNORM;
	sdesc.BufferDesc.Height=height;
	sdesc.BufferDesc.Width=width;
	sdesc.BufferDesc.Scaling=DXGI_MODE_SCALING_UNSPECIFIED;
	sdesc.BufferDesc.ScanlineOrdering=DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	sdesc.OutputWindow=_hwnd;
	sdesc.BufferDesc.RefreshRate.Denominator=1;
	sdesc.BufferDesc.RefreshRate.Numerator=60;
	sdesc.Flags=0;
	sdesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	if (m4xMsaaEnable)
	{
		sdesc.SampleDesc.Count=4;
		sdesc.SampleDesc.Quality=m4xMsaaQuality-1;
	}
	else
	{
		sdesc.SampleDesc.Count=1;
		sdesc.SampleDesc.Quality=0;
	}
	IDXGIDevice *Device=0;
	HR(d3dDevice->QueryInterface(__uuidof(IDXGIDevice),reinterpret_cast <void**> (&Device)));
	IDXGIAdapter*Ad=0;
	HR(Device->GetParent(__uuidof(IDXGIAdapter),reinterpret_cast <void**> (&Ad)));
	IDXGIFactory* fac=0;
	HR(Ad->GetParent(__uuidof(IDXGIFactory),reinterpret_cast <void**> (&fac)));
	fac->CreateSwapChain(d3dDevice,&sdesc,&swapchain);
	ReleaseCOM(Device);
	ReleaseCOM(Ad);
	ReleaseCOM(fac);
	ID3D11Texture2D *back = 0;
	HR(swapchain->GetBuffer(0,__uuidof(ID3D11Texture2D),reinterpret_cast <void**> (&back)));
	HR(d3dDevice->CreateRenderTargetView(back,0,&RenderTarget));
	D3D11_TEXTURE2D_DESC Tdesc;
	ZeroMemory(&Tdesc,sizeof(D3D11_TEXTURE2D_DESC));
	Tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	Tdesc.ArraySize = 1;
	Tdesc.Format= DXGI_FORMAT_D24_UNORM_S8_UINT;
	Tdesc.Height= height;
	Tdesc.Width = width;
	Tdesc.Usage = D3D11_USAGE_DEFAULT;
	Tdesc.MipLevels=1;
	if (m4xMsaaEnable)
	{
		Tdesc.SampleDesc.Count=4;
		Tdesc.SampleDesc.Quality=m4xMsaaQuality-1;
	}
	else
	{
		Tdesc.SampleDesc.Count=1;
		Tdesc.SampleDesc.Quality=0;
	}
	HR(d3dDevice->CreateTexture2D(&Tdesc,0,&depthview));
	HR(d3dDevice->CreateDepthStencilView(depthview,0,&depth));
	d3dDeviceContext->OMSetRenderTargets(1,&RenderTarget,depth);
	D3D11_VIEWPORT vp;
	vp.TopLeftX=0.0f;
	vp.TopLeftY=0.0f;
	vp.Width = static_cast <float> (width);
	vp.Height= static_cast <float> (height);
	vp.MinDepth = 0.0f;
	vp.MaxDepth = 1.0f;
	d3dDeviceContext -> RSSetViewports(1,&vp);
	return true;
}

and this is the function that updates the view matrix and the app scenes

this need some explanation so you dont waste your time trying to understand ....

this function job is update the world matrices every one second (3D Tetris app) droping a box from above every 10 secs ..... so it will need about 10 secs to reach the bottom until it drops another box.......the B variable contains every possible step (small cubes world matrices) ....currentitem variable is to store the currently dropping box to move if the user clicked arrows buttons ........also updating the view matrix every frame....the view matrix updating is at the bottom of the function


void Game::Update(float dt){
	static float T = 0.0f,T2=0.0;
	T = T + dt;T2 += dt;
	UINT ge;
	if ((T * 1000.0f)>= 1000.0f)
	{
		UINT mon = B.GetSize();
		for (UINT i = 1; i < mon ; i++)
		{
			UINT si=B.Memory[i].filledindeces.size(),si2 = B.Memory[i-1].filledindeces.size();
			for (UINT r = 0; r < si; r++)
			{
				ge =B.Memory[i].filledindeces.back();
				for (UINT kll = 0; kll < si2; kll++)
				{
					if (ge == B.Memory[i-1].filledindeces[kll])
					{
						ge = 10000;
					}
				}
				if (ge == 10000) {
					if(i == 9)
					{
						MessageBoxA(_hwnd,"you lost\nTerminating...","Game Over",MB_ICONINFORMATION);
						exit(1);
					}
					continue;
				}
				B.Memory[i].filledindeces.pop_back();
				B.Memory[i - 1].filledindeces.push_back(ge);
				currentItem.Height=i-1;
			}
		}
		T=0.0f;
		int ra = rand();
		if(ra<0) ra = -1* ra;
	if ((T2 * 1000.0f) >= 10000.0f)
	{
		T2 = 0.0f;
		while(!(ra >=0 && ra <36)){
			ra = rand();
		}
		B.Memory[9].filledindeces.push_back(ra);
		currentItem.Floor_Index=ra;
		currentItem.Height=9;
	}
	}
	
	float x=radius * sinf(phi) * cosf(theta);
	float z=radius * sinf(phi) * sinf(theta);
	float y=radius * cosf(phi);
	XMMATRIX V;
	XMVECTOR Foc = XMVectorSet(B.Memory[8].Pieces[18]._11,B.Memory[8].Pieces[18]._22,B.Memory[8].Pieces[18]._33,1.0f),
		Up = XMVectorSet(0.0f,1.0f,0.0f,0.0f),
		Pos= XMVectorSet(x , y ,z,1.0f);
	V=XMMatrixLookAtLH(Pos,Foc,Up);
	XMStoreFloat4x4(&View,V);
}

this the rendering function


void Game::Render(){
	d3dDeviceContext->ClearRenderTargetView(RenderTarget,reinterpret_cast <const float*> (&Colors::LightSteelBlue));
	d3dDeviceContext->ClearDepthStencilView(depth,D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL,1.0f,0);

	d3dDeviceContext-> IASetInputLayout(_layout);
	d3dDeviceContext-> IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
	d3dDeviceContext->IASetIndexBuffer(indices,DXGI_FORMAT_R32_UINT,0);
	UINT strides=sizeof(Vertex),off=0;
	d3dDeviceContext->IASetVertexBuffers(0,1,&vertices,&strides,&off);
	
	D3DX11_TECHNIQUE_DESC des;
	Tech->GetDesc(&des);
	Floor * Lookup;
	std::vector<XMFLOAT4X4> filled;
	XMMATRIX V=XMLoadFloat4x4(&View),P = XMLoadFloat4x4(&Proj);
	XMMATRIX vp = V * P;
	XMMATRIX wvp;
	for (UINT i = 0; i < des.Passes; i++)
	{
		wvp = XMLoadFloat4x4(&(B.Memory[0].Pieces[35])) * vp;
		HR(ShadeMat->SetMatrix(reinterpret_cast<float*> ( &wvp)));
		HR(Tech->GetPassByIndex(i)->Apply(0,d3dDeviceContext));
		
		d3dDeviceContext->RSSetState(BuildRast);
		d3dDeviceContext-> DrawIndexed(build_ind_count,build_ind_index,build_vers_index);
		d3dDeviceContext->RSSetState(0);
		UINT r1=10;
		for (UINT j = 0; j < r1; j++)
		{
			Lookup = &B.Memory[j];
			for (UINT r = 0; r < Lookup->filledindeces.size(); r++)
			{
				filled.push_back(Lookup->Pieces[Lookup->filledindeces[r]]);
			}
		}
		UINT r2=filled.size();
		for (UINT j = 0; j < r2; j++)
		{
			wvp = XMLoadFloat4x4(&filled[j])*vp;
			ShadeMat->SetMatrix( reinterpret_cast<float*> (&wvp));
			Tech->GetPassByIndex(i)->Apply(0,d3dDeviceContext);
			d3dDeviceContext->DrawIndexed(piese_ind_count,piese_ind_index,piese_vers_index);
			
		}
		
		filled.clear();
	}
	HR(swapchain->Present(0,0));
}

thanks for you time

This is embarrassing. I assumed from your pictures you had a problem with the scene view when switching resolutions. My fault. You haven't really described your problem.

So.. please describe what you believe your problem is.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

the funny thing is i didn't even notice something weird ....i posted the resizing function and you didn't see something wrong in it so you asked for the complete code you were making sense ....anyway my problem is when i switch to full screen ....the drawing and the box all gets messed up....the first picture where the program works correctly(windowed)....the second switched to full screen the box gets drawn a bit away from the camera .........

This topic is closed to new replies.

Advertisement