Skip to main content
GameDev.net gamedev.net
🔒 Locked

Window resizing

Started by pas059 Jan 26, 2012 at 3:42 PM 12 replies 4.7k views
Original Post
pas059
pas059
Hi,

I'm porting an MDX application to SlimDX (targetting Direct9). Everything seems to goes fine, except when i resize the window (a Windows.Form) and so the Control it contains. Every parts are just stretched.
In the overrided OnResize() method of the Control, i tried to redefine the Viewport of my Device, but without success; i also tried to call the Reset() method of the device but this gives an D3DERR_INVALIDCALL exception.

Someone can tell what must be done to correct this problem?

thanks in advance,
Pascal
pas059
pas059
Hi,

Really, no one know what must be done on Windows Form resize?

Pascal
Syranide
Syranide
You need to reset the device for Direct3D 9, however, in order to reset it you must also provide proper arguments and clean up existing resources.

However, there is a better way if you intend to resize it a lot, I don't have the code right now, but what you do is make the primary backbuffer 1x1 and instead create your own backbuffer to replace the default one, your own backbuffer can now be recreated without resetting the device.


pas059
pas059
Hi Syranide,

I tried to Reset the device and the parameters are correct, but i always get en exception D3DERR_INVALIDCALL.

Someone can gives a code sample?

thanks in advance,
Pascal,
Postie
Postie
In general, any resources you've allocated that required passing in the Direct3D9Device need to be be freed before calling Reset(). In reality it depends on the resource pool used, but more than likely you've used the default pool, which requires explicit freeing of the resource.

My screen resize code does the following:

1) Free all resources
2) Update the backbuffer size
3) Reset the device
4) Load all resources (if required).
[size="2"]Currently working on an open world survival RPG - For info check out my Development blog:[size="2"] ByteWrangler
pas059
pas059
Hi Postie,

Do you mean that objects like VertexBuffer, Mesh have to be freed? and then recreated after updating? this can take many time in some cases.

As it was not necessary to do this in MDX, i'm suprising.

Do you have a link?

thanks again,

Pascal
Syranide
Syranide

Hi Postie,

Do you mean that objects like VertexBuffer, Mesh have to be freed? and then recreated after updating? this can take many time in some cases.

As it was not necessary to do this in MDX, i'm suprising.

Do you have a link?

thanks again,

Pascal


Sadly that is the case, with Direct3D 9, Direct3D 9Ex does not require it I believe.
Anyway, as above, you can create your own backbuffer to replace the default one, that backbuffer can then be recreated at will without resetting the device. I don't know what MDX is really, but I would assume it's using one of the above.


pas059
pas059
Hi again,

Indeed, after disposing ressources resetting the device no longer generates an exception (of course), but as recreating all can takes times (in some cases) the solution consisting on recreating the backbuffer seems more elegant to me.
But, i haven't seen how to create a backbuffer with SlimDX/D3D9.
Do you have an example, a link,...?

thanks in advance
Pascal
pas059
pas059
Hi,

i tried this by Disposing the BackBuffer, then to recreate one with the new Size, but this gives the same result. Concerning the SwapChain, it can not be created directly. On the link you give, Syranide, this is also what they observed, and then they concluded that the "Elements" have to be recreated. I saw in the SlimDX sample that this is also the method they used.
If you could show us your code, this would nice.

Thanks again,
Pascal
Syranide
Syranide

LPDIRECT3DSURFACE9 rendersurf_old;
LPDIRECT3DSURFACE9 depthsurf_old;
m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &rendersurf_old);
m_device->GetDepthStencilSurface(&depthsurf_old);
rendersurf_old->Release();
depthsurf_old->Release();

RECT rect;
GetClientRect(m_hwnd, ▭);
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
m_d3dpp.BackBufferWidth = m_width = width;
m_d3dpp.BackBufferHeight = m_height = height;
DXASSERT(m_device->CreateAdditionalSwapChain(&m_d3dpp, &m_swapchain));
DXASSERT(m_swapchain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &m_rendersurface));
DXASSERT(m_device->CreateDepthStencilSurface(m_width, m_height, m_d3dpp.AutoDepthStencilFormat, m_d3dpp.MultiSampleType, m_d3dpp.MultiSampleQuality, TRUE, &m_depthsurface, 0));


Is the basic code I'm using and I'm pretty sure it's based on the code from that post.


pas059
pas059
Hi Syranide,

Thanks your code, which is in native C++. With SlimDX (and also SharpDX and MDX) which are managed frameworks desgned to used with .Net languages (C#, C++ managed, VB,...), not all the methods of Direct3D9 are exposed, and notably [color="#660066"]CreateAdditionalSwapChain().

So, i started to use the "traditional" way: disposing ressources that must be disposed, reseting device, recreate resources. The first results seems sufficient, but this takes more time to code and the execution is probably slower. Anyway, i think that i have no other choice.

Thanks again,
Pascal
Syranide
Syranide

Hi Syranide,

Thanks your code, which is in native C++. With SlimDX (and also SharpDX and MDX) which are managed frameworks desgned to used with .Net languages (C#, C++ managed, VB,...), not all the methods of Direct3D9 are exposed, and notably [color=#660066]CreateAdditionalSwapChain().

So, i started to use the "traditional" way: disposing ressources that must be disposed, reseting device, recreate resources. The first results seems sufficient, but this takes more time to code and the execution is probably slower. Anyway, i think that i have no other choice.

Thanks again,
Pascal


Yeah, if it isn't exposed then that would be hard to say the least, unless you can just patch it in there yourself.

Also, as I believe I mentioned above Direct3D9Ex pretty much prevents lost devices from occuring entirely (on Vista and up), but I would assume that your library doesn't support that either then, as I feel like it should've just done that internally for you if it supports it.

Your last option would be to use the D3DPOOL_MANAGED for textures if exposed, however, it's not without issues and doesn't actually solve the problem, it just makes a bit faster as a copy of the texture is kept in system memory at all times.


pas059
pas059
Hi,
sorry for late reply, i was out of office

I tried with Direct3D9Ex (on vista), this gives the same (bad) results. So the "traditional" way seems to be the only one method. This is what i done, and this works (fortunately).

thanks again
Pascal

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.