How can I resize irrlicht window?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Netaro
Posts: 5
Joined: Fri Feb 09, 2007 10:27 pm

How can I resize irrlicht window?

Post by Netaro »

Ok, so here's the problem.
I have Irrlicht window (IrrlichtDevice), and I want to resize that window to given height/width, for example to the size of a picture (ITexture, getOriginalSize() ) . How?
Looked at documentation, but I was unable to find anything that would help me. Neither was I able to find anything on google?
agamemnus
Posts: 283
Joined: Sun Jan 31, 2010 6:06 pm

Post by agamemnus »

Not sure you can do that other than to restart the Irrlicht device.
random
Posts: 158
Joined: Wed Aug 11, 2010 6:01 am

Post by random »

1) you can resize the window with the mouse thatfor you need to insert this into your code

Code: Select all

device->setResizable(true);

2) you would like to call onResize() for driver and or device... obtain code here:

http://irrlicht.sourcearchive.com/docum ... cc3cd.html


or in your Irrlicht src folder :) but i dont think that onResize() would do the job alone, usualy a war is set also which is bind to a os dependend event.

Anyway both options would may change the resolution but not the Aspect ratio of your camera, you would have to that manualy else you image qould be streched.
agamemnus
Posts: 283
Joined: Sun Jan 31, 2010 6:06 pm

Post by agamemnus »

None of those options actually resize the window programatically...
CuteAlien
Admin
Posts: 9646
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

No, you can't do that from Irrlicht currently. But you can use the system API for it (I think MoveWindow on Windows for example). It might be necessary to call driver->OnResize with the new values afterward.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Rob
Posts: 15
Joined: Wed Jan 28, 2009 4:24 pm

Calling OnResize causes D3D failures, why?

Post by Rob »

If I call OnResize on m Win XP SP3 D3D9 system, it causes D3D9 to list errors, saying "too many textures", or "remove textures", and thats with just 2 textures loaded at the time! It seems calling OnResize cannot be done, anyone know why as some info here would help clarify matters for everyone.
xyzzy
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

This happened for old versions of Irrlicht, due to not released ressources. But it should work now.
Rob
Posts: 15
Joined: Wed Jan 28, 2009 4:24 pm

Post by Rob »

I´m using Irrlicht 1.7.2., latest version.
xyzzy
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Re: How can I resize irrlicht window?

Post by robmar »

I can confirm that calling driver->OnResize( newscreensize ) using D3D is still crashing Irrlicht-
This is the Output that occurs directly on calling this:

Resetting D3D9 device.
First-chance exception at 0x732710f8 in dstest.exe: 0xC0000005: Access violation reading location 0xfeeeff76.
Resetting failed due to invalid call: You need to release some more surfaces.
Unhandled exception at 0x76f415ee in medal32.exe: 0xC0000005: Access violation reading location 0xfeeeff76.

Works fine under OpenGL though. Does anyone know if there is a fix?
Last edited by robmar on Thu Feb 02, 2012 1:24 pm, edited 1 time in total.
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Re: How can I resize irrlicht window?

Post by robmar »

I´ve also tried using setViewPort() to update the irrlicht window to a new size, but the resolution is always the same, just scalled-up and more pixelated, and the only way I seem to be able to reset it is a complete delete and recreate process.

Any ideas would be really helpful...
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: How can I resize irrlicht window?

Post by hybrid »

Could you please show some minimal code to reproduce this?
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Re: How can I resize irrlicht window?

Post by robmar »

Here´s the code, from code under Windows 7:-

Code: Select all

 
void Sim::OnSize(UINT nType, int cx, int cy)    
{
        if ( m_b3Drunning )
        {
                core::rect<s32> rvp = m_p3D->m_pDriver->getViewPort();
 
                const core::dimension2d<u32> screensize = core::dimension2d<u32>( cx, cy );
                core::rect<s32> ss( 0, 0, cx, cy );
 
                if ( rvp.LowerRightCorner.X != cx || rvp.LowerRightCorner.Y != cy )
                {
                        if ( m_p3D->m_param.DriverType == video::EDT_OPENGL )
                                m_p3D->m_pDriver->OnResize( screensize );       // DO NOT USE OnResize in D3D mode!  Causes 3D engine to crash with D3D errors!!  Works under opengl
                        else
                                m_p3D->m_pDriver->setViewPort( ss );            // Doesn´t crash, but doesn´t resize to match new viewport res, causing pixelation
 
                        core::rect<s32> rect( 0, 0, screensize.Width, screensize.Height );
                        m_p3D->m_pDriver->setViewPort( rect );          // NOTE: This just sets drawing region within window, it does NOT scale the view!
                }
        }
        CScrollView::OnSize(nType, cx, cy);
}
 
Voxel
Posts: 8
Joined: Wed Feb 23, 2011 9:04 am

Re: How can I resize irrlicht window?

Post by Voxel »

Hi,

here is how I did it. I use D3D and not OpenGL, it doesn't crash and I did't have any pixelation effects. So it works for me...

In the 'OnSize' method within your view just set a mark, e.g a boolean member of your view:

Code: Select all

 
void MyView::OnSize(UINT nType, int cx, int cy)
{
    CView::OnSize(nType, cx, cy);
 
    if (m_bWndResized == false)
    {
       m_bWndResized = true;
    }
}
 
In your 'OnDraw' method check the flag and set the aspect ratio of your camera before you call 'scene manager'->'drawAll':

Code: Select all

 
void MyView::OnDraw(CDC* /*pDC*/)
{
    if (!m_driver || !m_smgr)
        return;
 
    // advance virtual time
    m_device->getTimer()->tick();
 
    if (m_driver->beginScene(true, true, irr::video::SColor(255,96,96,96), m_driver->getExposedVideoData(), 0) == false)
        return;
 
    if (bWndResized)
    {
        if (m_smgr->getActiveCamera() != 0)
        {
            CRect rWnd;
            GetClientRect(this->GetSafeHwnd(), &rWnd);
 
            int cx = rWnd.Width();
            int cy = rWnd.Height();
 
            m_smgr->getActiveCamera()->setAspectRatio((irr::f32)cx / (irr::f32)cy);
        }
        bWndResized = false;
    }
 
    m_smgr->drawAll();
 
    if (m_driver->endScene() == false)
        return;
}
 
I hope this could be helpful...

Regards,
Voxel
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Re: How can I resize irrlicht window?

Post by robmar »

Thanks, looked good, doing the call after beginscene, but for some reason it still doesn´t work.

I checked it in debug, OnSize sets the flag, the 3D loop detects it, calls the exact code you detailed, and nothing happens, it stays pixellated when the view is enlarged.

Appreciate the effort, would like to crack this, works under OpenGl, but not under D3D.

I place this code directly in the OnSize function of the CView, and in OpenGL mode, works perfectly:-
pDriver->OnResize( screensize ); // DO NOT USE with D3D!! Causes 3D engine to crash with D3D errors!! Works under opengl.

In the D3D driver, the crash occurs on the line below marked "here>" because the code "DepthBuffers" produces a NULL ptr.

Code: Select all

 
//! resets the device
bool CD3D9Driver::reset()
{
        u32 i;
        os::Printer::log("Resetting D3D9 device.", ELL_INFORMATION);
 
        for (i=0; i<Textures.size(); ++i)
        {
                if (Textures[i].Surface->isRenderTarget())
                {
                        IDirect3DBaseTexture9* tex = ((CD3D9Texture*)(Textures[i].Surface))->getDX9Texture();
                        if (tex)
                                tex->Release();
                }
        }
        for (i=0; i<DepthBuffers.size(); ++i)
        {
here>           if(DepthBuffers[i]->Surface)
                        DepthBuffers[i]->Surface->Release();
        }
 
Visual Studio 2008 is compiling under debug the following code, and from the asm code, it seems to be using the index, i, as a direct reference to memory, which, as this value starts at 0, directly address memory at 0000, would be an illegal address. Could it be a compliler bug? I´ve seen this before and just moving the code around a bit, even adding a jump label, can fix it.

Code: Select all

 
                if(DepthBuffers[i]->Surface)
013DA898  mov         edx,dword ptr [i] 
013DA89B  push        edx  
013DA89C  mov         ecx,dword ptr [this] 
013DA89F  add         ecx,704h 
013DA8A5  call        irr::core::array<irr::video::SDepthSurface *,irr::core::irrAllocator<irr::video::SDepthSurface *> >::operator[] (1217239h) 
 
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Re: How can I resize irrlicht window?

Post by robmar »

Okay, its working at last. It seems that under D3D mode, to resize the Irrlicht window it is necessary to call driver->OnResize(), which resets the device in the D3D driver.

However, if this is called after beginScene, it is necessary to perform an endscene-beginscene cycle, then reload all textures, which is also necessary as the reset deletes all the texture (under D3D).

For Windows, Voxels implementation of flaging the condition in CWnd::OnSize is used, calling the following code.

If there are any better ways of doing this, please let me know!

Code: Select all

 
// First, before updating, check if view needs resizing, as if it is, we´ll need to reload textures
        if ( m_bWndResized )
        {
                scene::ICameraSceneNode* pC = m_pSmgr->getActiveCamera();       
                if ( pC )
                {
                        CRect rectWnd;
                        GetClientRect( m_pView->GetSafeHwnd(), &rectWnd );
 
                        int cx = rectWnd.Width();
                        int cy = rectWnd.Height();
         
                        core::rect<s32> rvp = m_pDriver->getViewPort();
 
                        if ( rvp.LowerRightCorner.X != cx || rvp.LowerRightCorner.Y != cy )
                        {
                                const core::dimension2d<u32> screensize = core::dimension2d<u32>( cx, cy );
                                core::rect<s32> rect( 0, 0, cx, cy );
 
                                m_pDriver->setViewPort( rect );         // NOTE: This just sets drawing region within window, it does NOT scale the view!
 
                                m_pDriver->OnResize( screensize );              // If this crashes in the Irrlich D3D driver, modify driver to catch error conditions
                                dwFlags |= 0x01;                // Force reload of textures in UpdateObjects() below
 
                                // Set camera aspect ratio
                                irr::f32 fAspect = (float)cx/(float)cy;
                                if ( fAspect >= 0.f )
                                {
                                        pC->setAspectRatio( fAspect );
                                }
                                else
                                        ASSERT( FALSE );
 
                                // These two calls are needed in D3D mode otherwise the textures go black, even though reloaded! Under OpenGL, not needed, but cause not errors
                                m_pDriver->endScene();
                                m_pDriver->beginScene( false, false, m_sc );
                        }
                        m_bWndResized = false;
                }
        }
 
 
Post Reply