Sign in to follow this  
rene_g

Is there a better way than a scissor rect?

Recommended Posts

Basic details: VS2005 / std. c++ / DirectX 9 SDK (Feb 2007) Hi experts! I'm working on my own GUI (I know! There's lots of them. But I'm making my own for the experience of it) but I've run into a problem with windows inside windows. I'm rendering windows as textured quads in an orthogonal projection. Now, when a window is inside another window, it should be clipped if it moves outside of its parent. My first thought was that scissor testing could do the trick, but after some testing I thought stenciling was the right choice. After testing that, I rejected the idea and went back to scissor testing. So that's where I am now. When a window should draw itself, it fetches its parents scissor rect and compares it with its own. If some part of its own scissor rect is outside the parent scissor rect, the rect will be cut to fit inside the parent's rect. This works as expected. However, I'm experiencing a tiny visual artifact. As you can see on the screenshots above, the greenish rect is 1 pixel above the redish, and when the green rect is at the bottom of the red, it's again 1 pixel above the expected pixel. The green rect is a child of the big red one. So it should not be outside the red rects border. Your first thought might be that I calculate the rect incorrectly, however, this is not a consistent error. It's sometimes there, sometimes it's not. I thought it was a rounding error when I converted from my internal gui coordinate system, to the screen coordinate system, so I tried this:
	int GuiManager::GetScreenY(float guiY) const
	{
		float result = (float)m_screenHeight / m_surfaceHeight * guiY;
		if (result - floor(result) > 0.5f)
			result = ceil(result);
		return m_screenHeight - (int)result; // This might look weird, but it's because y=0 in ortho is at the bottom, and y=0 on the screen is at the top
	}


This should correctly round up or down, but this doesn't solve the problem. It still happens sometimes. So, my question is really, do any of you guys have any suggestions on how to correctly calculate the pixel coordinates, when I have the absolute position in Direct3D? If my quad is positioned at 20.0, 20.0. I want to know the coordinates of each of the corners of the quad on the screen. Is there a way to do that? (Preferably an easy one [grin]) The way I'm doing it now is pasted above. I know the size of my render surface and the orthogonal projection size. So I calculate the relationship between them and multiply with my known direct3d coordinate. Or, does anyone have any suggestion on another way to properly constrain window drawing, so that windows inside windows will be clipped correctly? Any help is really appreciated! And sorry for such a long post! René

Share this post


Link to post
Share on other sites
Keep in mind that by convention, the region you specify using the RECT structure does NOT include the pixel at location (right,bottom). For example, when RECT is passed to the FillRect function in Win32, the rectangle is filled up to, but not including, the right column and bottom row of pixels. See the RECT page on MSDN for more info (http://msdn2.microsoft.com/en-us/library/ms536136.aspx).

This convention is also applied in D3D. So your rounding of screen coordinates may be off, which would account for why you see the problem intermitantly.

neneboricua

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this