Jump to content
  • Advertisement
Sign in to follow this  
v0dKA

Multiple Viewports - screen flashes green and black

This topic is 4840 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

I'm trying to create a simple test program to try out using multiple viewports. Everything seems to work - I got everything I wanted on the screen, the additional viewport seems to be where it needs to be. However, the screen flashes green and black, so clearly, there's an error. I remember from somewhere if the screen flashes, DirectX is trying to tell you something, and the colors it flashes denote what went wrong. In this case, the colors are green and black. The debug spew from the program didn't say anything unusual, even with D3D_DEBUG_INFO defined. Here's the relevant code from my program: Defined at a global level: D3DVIEWPORT9 main; // entire window D3DVIEWPORT9 child; // small 100x100 box in bottom-right corner Setting up the viewports: // Main window, covers entire render surface main.X = 0; main.Y = 0; main.Width = 1280; main.Height = 1024; main.MinZ = 0; main.MaxZ = 1; // Small 100x100 box, bottom right corner child.X = 1180; child.Y = 924; child.Width = 100; child.Height = 100; child.MinZ = 0; child.MaxZ = 1; The Render() function:
void Render( float timeDelta )
{
	if( device )
	{
		device->SetViewport( &main );
///// Render a rotating box - no errors here, snipped from a working program
		D3DXMATRIX Ry, World;
		static float rot = 0.0f;

		D3DXMatrixRotationY( &Ry, rot );
		World = Ry;

		device->SetTransform( D3DTS_WORLD, &World );
		device->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0 );
		device->BeginScene();

		device->SetTexture( 0, Textures[ 2 ] );
		
		for( unsigned int i = 0; i < 3; i++ )
		{
			mesh->DrawSubset( i );
		}

		device->EndScene();
		device->Present( 0, 0, 0, 0 );

		rot += 0.5f * timeDelta;

		if( rot > 2.0f * D3DX_PI )
			rot = 0.0f;

//////////////// Draw a 100x100 box on bottom right, simply clear to white
		device->SetViewport( &child );
		device->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0 );
		device->Present( 0, 0, 0, 0 );
	}
	return;
}

Most of the code is snipped from a working program (a rotating, textured cube), and the second viewport I added overlaps the main viewport. There are no compilation errors, nothing suspicious in the debug spew, but the screen flashes green and black. Where's the error?

Share this post


Link to post
Share on other sites
Advertisement
That flashing normally indicates you are not clearing the back buffer. I think your problem is that you have two presents - you should only have one beginScene, endScene and present. Multiple clears are ok.

Share this post


Link to post
Share on other sites
Viewports limit drawing to a subset of the backbuffer. Present() presents the entire backbuffer, not just the active viewport.

Change to
BeginScene()
SetViewport()
Clear()
Draw()
SetViewport()
Clear()
Draw()
EndScene()
Present()

and you should be good. I think nVidia and possibly ATI recommend Clearing once, and for the full backbuffer, not on a per-viewport basis. The hardware is optimized to just wipe memory completely, and it can't use that optimization if you clear only a portion of the display.

Share this post


Link to post
Share on other sites
Thanks for the help. A couple more questions sprang up from this:

1. How exactly do you specify whether you want to clear a viewport or the entire back buffer? Is it all in the placement of the Clear() call (as in, calling Clear() before any SetViewport() will clear the entire back buffer, and calling Clear() after SetViewport() will only clear the current viewport), or is it controlled by the flags you supply to the Clear() function?

2. Approximately where should I place BeginScene() and EndScene()? Is it okay if I do non-drawing operations between those functions?

Share this post


Link to post
Share on other sites
IYou can either SetRenderTarget(), which clears any viewport settings, or just set a viewport to the full surface, then Clear(), then set the viewport you really want before drawing.

You can do anything inside beginscene/endscene, even non-drawing stuff. Technically, I think you're supposed to keep as much stuff out of beginscene/endscene as you can, as some kind of system wide lock occurs during this time, but it's not mandatory.

Some older drivers don't like multiple beginscene/endscene pairs without a present, so using multiple blocks to try to limit any system locks isn't a good way to go. Wrap all drawing in one begin/endscene pair.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!