[Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

What it says on the tin: a place to discuss proposed new features.
fred11
Gnoblar
Posts: 4
Joined: Wed Jun 03, 2009 11:43 pm

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by fred11 »

Thanks for all of your hard work on this Nir.

I'm having an issue with the third version of the patch applied to 1.6.2.
Vertex movements don't seem to update properly when they're not in the camera's view. (I have bots manipulating the world which may not always be in view)
An animation will fire behind the camera, but if I turn around to look at it, the verts are still in their original state.

I'm moving verts by writing directly to the HardwareVertexBuffer.
Using D3D9 RenderSystem.
This is a problem on both a single window/single screen and multiple windows/screens.

Any ideas on how to fix this?
User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
x 2
Contact:

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by Nir Hasson »

Hi fred11 -

I can suggest that you take a look at the D3D9HardwareVertexBuffer class implementation.
If you work directly with HardwareVertexBuffer inteface and use the lock and unlock methods, then the intenal method that actually
updates the vertex buffer called updateBufferResources.
This method is called from the unlock implementation in case this buffer was used in the last frames, in your case when out of frustum it will skip this call from performanc issues.

Code: Select all

void D3D9HardwareVertexBuffer::unlockImpl(void)
    {
		OGRE_LOCK_MUTEX(mDeviceAccessMutex)

		DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin();
		uint nextFrameNumber = Root::getSingleton().getNextFrameNumber();

		while (it != mMapDeviceToBufferResources.end())
		{
			BufferResources* bufferResources = it->second;

			if (bufferResources->mOutOfDate && 
				bufferResources->mBuffer != NULL&&
				nextFrameNumber - bufferResources->mLastUsedFrame <= 1)
				updateBufferResources(mSystemMemoryBuffer, bufferResources);

			++it;
		}			
    }
However the data is stored in the system memory member called mSystemMemoryBuffer and in the next time that the vertex buffer is about to be used (when D3D9HardwareVertexBuffer::getD3D9VertexBuffer called), the following code will make it update -

Code: Select all

if (it->second->mOutOfDate)
          updateBufferResources(mSystemMemoryBuffer, it->second);

Put some breakpoints in these places and figure out why the updateBufferResources is not called.
Please update me with the results...
fred11
Gnoblar
Posts: 4
Joined: Wed Jun 03, 2009 11:43 pm

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by fred11 »

Thanks for pointing me in the right direction!

I commented out the (nextFrameNumber - bufferResources->mLastUsedFrame <= 1) requirement for calling updateBufferResources and it seems to have fixed the problem.

Code: Select all

void D3D9HardwareVertexBuffer::unlockImpl(void)
    {
		DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin();
		uint nextFrameNumber = Root::getSingleton().getNextFrameNumber();

		while (it != mMapDeviceToBufferResources.end())
		{
			BufferResources* bufferResources = it->second;

			if (bufferResources->mOutOfDate && 
				bufferResources->mBuffer != NULL /*&&
				nextFrameNumber - bufferResources->mLastUsedFrame <= 1 */)     // This fixed it
					updateBufferResources(mSystemMemoryBuffer, bufferResources);

			++it;
		}		
    }
Thank you!
User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
x 2
Contact:

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by Nir Hasson »

I see - but this fix cause to the buffers to be updated all the time, even if they are not used for rendering by there owner device -
I made it espacialy to prevent un-necesary updates of buffers that lay out of frustum.
I suggest you check why the buffer was not updated in the D3D9HardwareVertexBuffer::getD3D9VertexBuffer

Code: Select all

if (it->second->mOutOfDate)
          updateBufferResources(mSystemMemoryBuffer, it->second);
It seems like when the render system calls this method the mOutOfDate member is false -
OR
the system memory buffer holds another data...

Let me know what was the reason...
fred11
Gnoblar
Posts: 4
Joined: Wed Jun 03, 2009 11:43 pm

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by fred11 »

I'm sorry for taking so long to get back to you Nir, I think I've figured out my problem.

I am making multiple non-continuous writes to the same vert buffer per frame and it looks like the offset and length of the memcpy aren't getting saved properly to include all of the write calls I'm making. For example, I would writeData to the buffer from 0 to 12 and then from 24 to 36, and only 0 to 12 would get written.

I restored unlockImpl to its original glory and modified lockImpl as follows:

Code: Select all

    void* D3D9HardwareVertexBuffer::lockImpl(size_t offset, 
        size_t length, LockOptions options)
    {
		if (options != HBL_READ_ONLY)
		{
			DeviceToBufferResourcesIterator it = mMapDeviceToBufferResources.begin();

			while (it != mMapDeviceToBufferResources.end())
			{
				BufferResources* bufferResources = it->second;

				bufferResources->mOutOfDate = true;

				// ----- start new code ----- 
				if(bufferResources->mLockLength > 0)
				{
					size_t highPoint = std::max( offset + length, 
											bufferResources->mLockOffset + bufferResources->mLockLength );
					bufferResources->mLockOffset = std::min( bufferResources->mLockOffset, offset );
					bufferResources->mLockLength = highPoint - bufferResources->mLockOffset;
				}
				else // ----- end new code ----- 
				{
					if (offset < bufferResources->mLockOffset)
						bufferResources->mLockOffset = offset;
					if (length > bufferResources->mLockLength)
						bufferResources->mLockLength = length;
				}


				if (bufferResources->mLockOptions != HBL_DISCARD)
					bufferResources->mLockOptions = options;					

				++it;
			}
		}

		return mSystemMemoryBuffer + offset;		
    }
On the first write call, mLockLength would be 0, so the original code is called, after a smaller region has been established with the first write call, it resizes the range with each additional write.
User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
x 2
Contact:

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by Nir Hasson »

Hi - That seems like greate fix...

Thanks again - I'll add it and apply with the next patch release or trunk merge..
I'll add it also to the Index buffer implementation as well
lygyue
Greenskin
Posts: 122
Joined: Wed Nov 29, 2006 4:07 pm

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by lygyue »

Hi, I had downloaded "MultipleRenderWindows_1.6_Patch_004.rar", and i had downloaded ogre1.62, but i can't patched the patch file. Hope you can help, Thanks.
User avatar
Thieum
Gnome
Posts: 342
Joined: Wed Apr 26, 2006 5:13 pm
Location: Bordeaux, France
x 2
Contact:

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by Thieum »

Hi nir,

lygyue had some trouble applying the patch in order to use my stereo manager.
I converted you patch in order to apply it to the source release of ogre 1.6.3 (instead of the revision 8567 of the svn). When I updated the svn to the revision corresponding to ogre 1.6.3 (r8862), I had to resolve some conflicts and I am not sure if I handled them correctly.

I also changed the definitions of OGRE_LOCK_RECURSIVE_MUTEX :

Code: Select all

		#define OGRE_LOCK_RECURSIVE_MUTEX(name) boost::detail::thread::lock_ops<boost::recursive_mutex>::lock(name);
		#define OGRE_UNLOCK_RECURSIVE_MUTEX(name) boost::detail::thread::lock_ops<boost::recursive_mutex>::unlock(name);
to

Code: Select all

		#define OGRE_LOCK_RECURSIVE_MUTEX(name) name.lock();
		#define OGRE_UNLOCK_RECURSIVE_MUTEX(name) name.unlock();
because it did not compile with boost 1.39

Can you tell me if the changes I made to the patch seems correct ?
Thank you.

here is the patch : http://www.ogre3d.org/forums/download/file.php?id=763
User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
x 2
Contact:

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by Nir Hasson »

Hi -

Regarding the boost conversion - it is O.K - I had to do the same thing when I switch to different version of boost - It is simply interface changes.
I can not check the rest of the patch but I'm sure that if you followed the main changes and apply them it will work - I mean all the conversion to static lock objects instead of per instance.
Just pay attention that you have the latest version of the prerequisite header of the D3D9 render system since I fixed a copy paste bug there :)
lygyue
Greenskin
Posts: 122
Joined: Wed Nov 29, 2006 4:07 pm

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by lygyue »

Hi nir,

Thanks for your great job, I had patched successful with Thieum's help. But how to write a fullscreen dual output demo? and why not provide one?
User avatar
Thieum
Gnome
Posts: 342
Joined: Wed Apr 26, 2006 5:13 pm
Location: Bordeaux, France
x 2
Contact:

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by Thieum »

Nir Hasson wrote:Hi -

Regarding the boost conversion - it is O.K - I had to do the same thing when I switch to different version of boost - It is simply interface changes.
I can not check the rest of the patch but I'm sure that if you followed the main changes and apply them it will work - I mean all the conversion to static lock objects instead of per instance.
I was mainly unsure about D3D9HardwarePixelBuffer::createRenderTextures because you removed it and it was slightly updated in 1.6.3 but everything seems to work
Just pay attention that you have the latest version of the prerequisite header of the D3D9 render system since I fixed a copy paste bug there :)
Are you talking of the version of the header in the trunk on in the 1-6 branch ?

Are you OK if i distribute this patch directly in the StereoManager zip ?
User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
x 2
Contact:

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by Nir Hasson »

I was mainly unsure about D3D9HardwarePixelBuffer::createRenderTextures because you removed it and it was slightly updated in 1.6.3 but everything seems to work
That seems fine..
Are you talking of the version of the header in the trunk on in the 1-6 branch ?
I'm talking about the trunk - all the locking definitions are in that D3D9Prerequisite header.
Are you OK if i distribute this patch directly in the StereoManager zip ?
Sure - go ahead.
User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
x 2
Contact:

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by Nir Hasson »

Hi nir,

Thanks for your great job, I had patched successful with Thieum's help. But how to write a fullscreen dual output demo? and why not provide one?
If I didn't mention before one of the patches included a sample code in the playpen project. Go to PlayPen.cpp source file and uncomment the following define -_MULTIPLE_MONITOR_RENDER_MODE_.
It will cause to all tests to run on all the monitors you've got there by basically creating N render windows and attaching the same camera to all of them.

Good luck :D
Jzone
Gnoblar
Posts: 7
Joined: Fri May 29, 2009 8:28 pm

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by Jzone »

Hi, I'm using python-ogre on version 1.6.1 (with the r940 update), and I'm wondering what I would have to do to get this patch applied & working.

I'm guessing I would start by downloading ogre 1.6.1 source, applying this patch, and then moving over the dll files. But I'm also thinking there is more to it than that? (Would this question be better asked on the python-ogre board?)

Thanks
User avatar
Nir Hasson
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 363
Joined: Wed Nov 05, 2008 4:40 pm
Location: TLV - Israel
x 2
Contact:

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by Nir Hasson »

I'm guessing I would start by downloading ogre 1.6.1 source, applying this patch
That would be just fine - download the source and apply the patch - nothing else you should do - beside compiling the project of course:) .
Jzone
Gnoblar
Posts: 7
Joined: Fri May 29, 2009 8:28 pm

Re: [Solved] multihead/multiscreen in mainstream 1.6 (DirectX)

Post by Jzone »

I'm pretty sure python-ogre pulls from a compiled dll version of the ogre source, so at the very least I should have to compile ogre and move these files to the location python-ogre is looking for them right?

Hmm, I guess this question is more suited for the python-ogre board, now that I think about it...
Post Reply