Jump to content

  • Log In with Google      Sign In   
  • Create Account

RobMaddison

Member Since 28 Oct 2007
Offline Last Active Today, 07:46 PM

Posts I've Made

In Topic: Swap chain rendering to multiple views

Today, 07:46 PM

It's still not clear exactly what you're doing.


Sorry, I'm not sure how else to describe it. You're right though, I am trying to render two scenes to the same back buffer and that is happening but I have to Present after each render _because_ I am rendering to two separate windows, not rendering two views side by side within the same window.

I'm pretty sure my solution is to use another swapchain with its own backbuffer meaning I can do the following:

Render to swapchain 1
Present swapchain 1
Render to swapchain 2
Present swapchain 2

Rather than:

Render to a portion of the backbuffer
Present that portion of it to an hwnd
Render another portion to the same backbuffer
Present that portion of it to the other hwnd

...which clearly isn't working

In Topic: Swap chain rendering to multiple views

Today, 10:59 AM


Just to reiterate, the importance of using technical terms to describe a technical problem cannot be overemphasized

 

I've worked in the IT industry for 23 years and one of the things that has always bothered me is issues or bugs that are not described properly so I'm disappointed I didn't get my point across well enough.  Sorry for that, I'm not intending anyone to 'guess' parts of my issue, I thought I'd covered everything.

 

I've moved on from the additional swapchains after your comments and I'm now trying to render using viewports.  In simplistic terms and removing C# from the equation, I'm rendering to two viewports (DirectX9 viewports).  One on the left and one on the right.  When I call Present, I call it twice (once after the render to each viewport), not at the end.  The reason I do this is because in my Present call, I'm using an HWND as the hDestWindowOverride parameter.  I am supplying source and dest RECTs.  The source for the left render is the left half of the back buffer and the source for the right is the right side.  The destination RECT is effectively the local client area of the render 'frame', so 0, 0, width, height.  Width being half the size of the back buffer.

 

Both viewports do render the correct views but the artefact is a shimmering/tearing band across the screen horizontally where, on the left, the band shows the contents of the right-hand render and, on the right, it shows the left side.  It's difficult to explain but it looks like when I render each view, the previous view hasn't quite finished rendering so I'm getting a form of tearing.  It looks like when I've rendered the left side, I start on the right side and the CPU has already called Present on the next view before the previous view has been rendered.  If I put a sleep call of 50ms or so before each call to render each frame, just to ensure the GPU would have fully rendered everything, it works perfectly (albeit at 20fps of course).

 

I had a look at the CodeSampler example for rendering to viewports and I'm doing exactly the same as they are other than the fact that I have to call Present after each BeginScene/EndScene rather than at the end (in their example, they call Present with all NULL parameters).

 

Edit:  I think this is the problem.  Calling Present() after rendering one view is swapping the back buffer and the front buffer when I should be calling present after rendering both views.  This would work if I wasn't using HWNDs supplied from C#.  This is why I went down the additional swap chain route as each one will have its own backbuffer and it won't matter the order in which I call Present...


In Topic: Swap chain rendering to multiple views

Today, 03:18 AM

Thanks guys, it would appear my understanding of how this works is limited.

 


#1: Stop misunderstanding that and implement things correctly instead of using work-around hacks. This will solve all of your problems immediately.

 

Using a work-around hack is not what I was trying to do and, in fact, that's kind of a contradiction - if I've misunderstood something, it's not really a work-around hack.  My c# application is a multi 'view' (by view I mean a panel/control in c# that can display a rendered image from within my c++ engine) app with at least 3 rendered panels, but the option of more.  The reason I initially thought to use swap chains is purely by research.  Once I'd got my image rendering in a view in my c# client, I resized it and the pixels stretched which I obviously don't want.  When I did some further research, I found that you needed to reset the device when changing the size of the rendering area in order that it didn't have to stretch the image across a wider area.  Resetting the device, in my mind, meant losing, or decoupling then, my resources.  As I have a fair amount loaded into the card and I'd seen other applications manage to resize windows dynamically, I assumed they couldn't be resetting the device and reloading resources constantly whilst the window was resizing, which led me to swap chains.

 

I read that in order to use swap chains (which at this point felt like the right thing to) I need to render to a back buffer retrieved using the swap chain (which I thought was its own back buffer) created for the view/rendering panel/viewport and then once rendering is done, call Present on that swap chain.  What I wasn't aware of is that any additional swap chain created uses the same back buffer.  L Spiro, you mentioned that swap chains have their own back buffers - is that by default because it appears that any additional swap chain I create, uses the same back buffer as the device - which does make sense if the idea is that you are rendering to a specified portion of the back buffer - and that would explain the artifacts I am seeing where one rendered view shows flickering bits of the other and vice versa.

 

So, seeing as I have clearly been mislead by my research or have misunderstood it, let me see if I now understand...:

 

In my c++ engine, I have the ability to render in full screen mode, windowed mode or to render to a passed-in HWND.  I need to create a C# front end which has multiple 'views' in the form of a couple of split containers (front, side, top - style) which will all be rendering the same scene but from different angles.  I also need to cater for a floating tool-like window which could very well be floating over the other rendered views.

 

So from Buckeye's point, I can achieve this by just using the default SwapChain that gets created when creating the device and Presenting to different areas of it (passing in the correct RECT structures to Present()).  If I need to have windows floating over the top, I guess I just render them after the ones underneath?

 


#2: Stop running away from lost devices. The full list of things that can cause the device to be lost is intentionally left unspecified so that people don’t make assumptions as to what can cause it and thus will implement proper handling of such a scenario. It is also trivial to restore resources after a lost device, so there is really no reason not to handle it properly.

 

I'm not running away from anything.  My assumption on this was one of speed after a bit of misled research.  Other apps that do this resizing of multiple views can't possibly be resetting and reloading resources dynamically anytime the mouse is moving whilst resizing - I just took the wrong route to working out how that's done.

 

Thanks


In Topic: Swap chain rendering to multiple views

Yesterday, 05:30 PM

I'm creating two swap chains on my device so I can render to two separate views. ... At the moment I have two panels, each showing a different scene.

 
Can you be a bit more precise by what you mean by "view" and "panel?" And why you're using two swapchains? Do you, perhaps, mean 2 separate viewports?

That's it yes. My c# client currently has a scene view and an animation view (and any other views I might come up with later). I pass the window handle of each panel/view to the c++ engine via a c++/cli dll. The scene view renders the whole scene, with terrain, etc and the animation view just renders my character so I can play about with the animation blends, etc.

I'm using swapchains because the view(ports) in the c# client can be resized and with swapchains, you can resize them and reset them without losing all your loaded resources.

In Topic: Memory leak in c# client

Yesterday, 04:40 AM

Talking of event systems, I cobbled mine together with a "sort the details out later" attitude and it turns out I'm calling back event subscribers with objects placed on the heap and not deleting them.

Now this is obviously not right, but it got me thinking about better ways to do it. It's a fairly standard setup so far, systems subscribe to the message pump for message types passing a callback (function pointer) and when an event occurs, the message pump goes through the subscription list calling the function pointers passing a message object (created on the heap) containing the data pertinent to that message type, eg mouse coordinates, etc. the message implements a simple IEvent interface that had void* GetData() so all subscribers can do what they want with the event data.

So my first thought was to obviously remove the heap allocation for messages with it being difficult to keep track of them and make sure they're deleted. Repkace it with what though? A shared ptr (I currently use boost shared pointers everywhere, apart from here!)? That might cost some performance. Creating objects on the stack? That might cost some performance as there'd be a lot of copy constructors being called. I can't think of another other way in this style but I was wondering whether some kind of messaging queue might be a better option.

If the message pump maintained a queue per message type (a map actually, with a unique id as the key), then I would only need to create one message object and subscribers could come and get the object rather than being sent it. Lifetime of objects poses a problem but if each object in the queue had a reference count starting at the number of active subscribers and each subscriber reduced the ref count once they'd seen the message (after being signalled that a message has been added), the message could be destroyed. Once a subscriber has seen a message, it would be given a "next message" id so you wouldn't have subscription issues when messages get removed.

Over-engineered?

PARTNERS