Jump to content
  • Advertisement
Sign in to follow this  
markypooch

Rendering to a Child Window w/ D3D & Win32

This topic is 579 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey Guys,

Hoping there are some Win32 guys out there since I have a bit of an issue. So I'm rendering to a child window of my Win32 application with D3D11. For the most part, everything is well, and good. However when I go to actually render some geometry to the screen my backbuffer flashes. At first I thought it was Z-Fighting, however having ruled that out, it almost looks as if there are two presents going on.

The one that I know about, the call to the swapChains method to present the backbuffer, and another one buried in Win32 callback code somewhere. I'm wondering if there is a simple fix for this. I don't need the application to run at anything more than 20fps to be completely honest. So throw some suggestions at me, if ya got them.

The child window I render to:

hPanel = CreateWindowEx(NULL, L"RR", L"None", WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS, 40, 20, 500, 500, hWnd, nullptr, nullptr, nullptr);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case IDC_BUTTON1:
			//If Button pressed, retrieve text from textArea, and locate it in wide string
			text.resize(GetWindowTextLength(hEdit)+1);
			GetWindowText(hEdit, &text[0], text.size());
			SetWindowText(hEdit, L"");
			break;
		}
		break;
	case WM_PAINT:
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}

	return 0;
}

I'm a bit of a Win32 noob. One common suggestion I see is to throw the D3D rendering code into WM_PAINT case, but I was wondering if there are other ways.

Thanks,

Marcus

Share this post


Link to post
Share on other sites
Advertisement

Out of curiosity, what OS are you running on?

My understanding of how child windows work is that they share the same backing surface as the parent window, and they just get asked to render into a small portion of it with a clipping rect. So the two presents that you'd be seeing would be one from your parent window, and one from your child window.

I don't necessarily know the answer, but I have two experiments you can try if you're on Win8+:

1. What happens if you add WS_EX_LAYERED to the window style?

2. What happens if you use DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL?

Share this post


Link to post
Share on other sites

Hey guys,

thanks for the follow up. Once I'm back at my desk, i'll make these changes.

 

Out of curiosity, what OS are you running on?

This build is on a Win10 box.

 

1. What happens if you add WS_EX_LAYERED to the window style?

2. What happens if you use DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL?

I'll try those changes. I think right now I didn't specify any particular swap effect in my chain, so i'll give both a shot, and report back how it goes.

 

Take the WM_PAINT

 

I added that for placing my D3D render code into. I had the issue beforehand, however, this was admist changes so removing may now yield a different result, I'll let you know.

Thanks Guys!

Marcus

Edited by markypooch

Share this post


Link to post
Share on other sites

Hey,

So I removed the WM_PAINT case, and the issue persisted, same for the WS_EX_LAYERED. I added the additional swap effect to the structure, and now it only renders one frame to the backbuffer, and just stops. So it's very possible I just am missing something in regards to how this particular swap effect is supposed to work.

Here goes my chain creation. Interestingly enough, if I add a 1 to my present method to synch with the v-blank, I see one frame (that quickly vanishes), otherwise I see nothing at all.

	DXGI_SWAP_CHAIN_DESC swapDesc = {};
	swapDesc.BufferCount = 2;
	swapDesc.BufferDesc.Height = height;
	swapDesc.BufferDesc.Width = width;
	swapDesc.BufferDesc.RefreshRate.Numerator = RR; 
	swapDesc.BufferDesc.RefreshRate.Denominator = 1;
	swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; 
	swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	swapDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
	swapDesc.OutputWindow = hWnd; 
	swapDesc.SampleDesc.Count = 1;
	swapDesc.SampleDesc.Quality = 0;
	swapDesc.Windowed = true;

	hr = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &swapDesc, &swapChain, &device, nullptr, &deviceContext);
	if (FAILED(hr)) throw GetLastError();

	ID3D11Texture2D *swapTexture;
	hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&swapTexture);
	if (FAILED(hr)) throw GetLastError();
	hr = device->CreateRenderTargetView(swapTexture, nullptr, &rtv);
	if (FAILED(hr)) throw GetLastError();
Edited by markypooch

Share this post


Link to post
Share on other sites

The WS_EX_LAYERED style is incompatible with DirectX processing (or was a few years ago).

Share this post


Link to post
Share on other sites

Okay, but don't use WM_PAINT to render in either.  That is for updating win32 controls (custom drawn etc)

Instead in your main loop, process all the windows events then run your game update then render functions.

 

Can we see your main loop?  That might help a lot.  Are you using PeekMessage() or GetMessage()?  etc.

Edited by Mike2343

Share this post


Link to post
Share on other sites

Jesse, you rock! :^) I added the WM_EX_LAYERED, and the new swap effect to the chain (after adding the new per frame call of OMSetRenderTargets), and that did it!

A good catch on the WM_PAINT case I left in there as I'm sure that wasn't helping matters. The present seems to be synched now across the parent, and child window.

Thanks a bunch guys!

Marcus

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!