Render directx in only a portion of a window

Started by
10 comments, last by noatom 10 years, 1 month ago

So if I want to make a windowed app that has directx in a portion of it, how would I do that? Usually directx just takes the whole window.

Advertisement

In OpenGL, it is done with glViewport. Searching the net, I see that DirectX equivalent is SetViewport.

Your best results will be to render to the full buffer and set a rectangular area of the client window in the Present function.


RECT vRect;
GetClientRect(hwnd,&vRect);

... render your scene up to device->EndScene();
// present the buffer to the upper right corner of the window
RECT pRect;
pRect.left = vRect.right/2;
pRect.right = vRect.right;
pRect.top = 0;
pRect.bottom = vRect.bottom/2;
device->Present(0,&pRect, 0, 0);

Be sure to present the buffer with the same aspect ratio of the buffer, otherwise the presentation will be stretched or squashed.

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.

Just add a smaller control that is the portion of the window you want to render to and use its HWND instead of the main window's HWND.

Actually, andur's suggestion will probably work better for you. Just create a child window of the main window. You can resize and position the child wherever you'd like within the client area. Build the viewport and projection matrix using the child's client size and aspect ratio. In the render routine:


RECT cRect;
GetClientRect(hChildWindow,&cRect);

... do your rendering

device->Present( &cRect, &cRect, hChildWindow, 0 ); // assumes viewport set to child client size

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.

but isn't there any way to set the backbuffer height and width? i tried setting them but they just occupy the whole window. And without manually setting them, my aspect ratio will be hard to estimate.

EDIT: Just used a viewport.


without manually setting them, my aspect ratio will be hard to estimate

As long as the backbuffer width/height is larger than the child window's client width/height you'll be fine. Just don't render to the entire backbuffer.

They are a couple approaches but the simplest would be:

Get the child's client rect.

RECT cRect;

GetClientRect(hChildWnd,&cRect);

Set the viewport to the child's rect size. // sets the portion of the backbuffer to render to.

Set the view to whatever you want.

Set the projection with the aspect ratio of the child. aspect = (float)cRect.width/(float)cRect.height.

Draw the scene

device->Present( &cRect, &cRect, hChildWnd, 0 ); // present the cRect area of the backbuffer to the cRect area of the child window

EDIT: Yes, setting the viewport properly is the key.

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.

Reading the other comments here, I will retract my answer, assuming you won't be rendering in the other parts of the screen as well - then it stands. In retrospect, it seem the solution you are seeking is the answer given by andur.

D3DVIEWPORT9 Viewport;
Viewport.X = 0;
Viewport.Y = 0;
Viewport.Width = 200;
Viewport.Height = 200;
Viewport.MinZ = 0.0f;
Viewport.MaxZ = 1.0f;
d3ddev->SetViewport(&Viewport);

Yea apparently using a viewport won't work since the backbuffer will still be created by default to fill the entire window. You simply cannot specify a custom buffer size. So,by using a viewport you will have all the space that is nonrendered black, and if you decide to put buttons or other controls in that space, there will be problems with rendering.

The only solution is to actually render in a control like a tab.

This topic is closed to new replies.

Advertisement