Sign in to follow this  
Catwheel

Directx9 splitscreen view

Recommended Posts

Catwheel    125

I recently got my first ever freelance job (or programming job in general for that matter) and I need to rewrite an old plugin for winamp to have two splitscreens, each screen rendering with slightly altered input to create a fake stereoscopic effect. now I've been searching around for a few hours, and I have found some tutorials about directx9 but none of them cover how to create a split screen in C++ (which I learned a few days ago). I think I'm kinda locked into using this old version of directx and I have not been able to find the original documentation on the framework. I'm looking for advice or sources of good information about this subject. At the point I'm at I usually post on a relevant forum and take a break. My first employer has been razzing me about getting as much work done as possible, and I am currently feeling exhausted. I guess that's not super relevant to readers of this, but any helpful advice, or links to useful material would be greatly appreciated. Thanks! If you need any more information please let me know!

Share this post


Link to post
Share on other sites
unbird    8335
Official documentation for the Direct 3D 9 pipeline is here.

Also browse the Getting Started links of this subforum for additional information.

Splitscreen is done using the same render target (usually your current backbuffer) and rendering your scene twice to different viewports.

Viewport documentation. IDirect3DDevice9::SetViewport (Associated API function)
This (further down: "View Ports") looks like a tutorial for both C++ and C#. Checked, worked.

PS: Welcome to the forum wink.png

Share this post


Link to post
Share on other sites
Catwheel    125

so I edited the viewport for the system, and then all the 3d objects went away, but the 2D objects written from drawprimitiveup were still there. After that I messed with it some more and now everything is displaying back to normal, but what's weird is I have the system set up to display 2 viewports? Why is there no change? here's the code. any theories?

void DXContext::SetViewport()
{
	D3DVIEWPORT9 v;
	v.X = 0;
	v.Y = 0;
	v.Width = m_client_width;
	v.Height = m_client_height/2;
	v.MinZ = 0.0f;
	v.MaxZ = 1.0f;
	m_lpDevice->SetViewport(&v);

    D3DVIEWPORT9 v2;
	v2.X = 0;
	v2.Y = m_client_height/2;
	v2.Width = m_client_width;
	v2.Height = m_client_height/2;
	v2.MinZ = 0.0f;
	v2.MaxZ = 1.0f;
	m_lpDevice->SetViewport(&v2);

}

Going to get back at it tomorrow. let me know if you know anything I can use here. so sleepy

Share this post


Link to post
Share on other sites
Buckeye    10747

Splitscreen is done using the same render target (usually your current backbuffer) and rendering your scene twice to different [emphasis mine - Buckeye] viewports.

 

Your code just resets the viewport with the second SetViewport call, and all rendering is done with vp2.

 

Instead,

 

1. set viewport1 and view matrix for "top" view

2. render scene (to "top" half of buffer)

3. Present top half of buffer to top half of client area

3. set viewport2 and view matrix for "bottom" view

4. render scene "slightly altered" (to "bottom" half of buffer)

5. Present bottom half of buffer to bottom half of client area

 

The Present call has to match the current viewport:

RECT cRect;
cRect.left = 0;
cRect.right = width;
// EDIT - previously did not set cRect.bottom correctly
if( renderingTopHalf)
{
   cRect.top = 0;
   cRect.bottom = height/2;
}
else
{
   cRect.top = height/2;
   cRect.bottom = height;
}
device->Present(&cRect, &cRect, 0, 0);

FYI: The dev->Clear(...) will clear only the portion of the target/depth buffer in the current viewport. So, if desired for debugging or other purposes, you can set the clear color differently for each pass.

 

Like so: same and different

 

In the linked pix, I rendered the scenes side-by-side, rather than top/bottom. I moved the eyepoint in the left side to the right a little, and the eyepoint in the right side to the left a little to create a "cross-your-eyes" stereo effect.

Edited by Buckeye

Share this post


Link to post
Share on other sites
Catwheel    125

okay so... some new issues. I've got the screen displaying the same image twice, which is good. For some reason I can't get the viewports to work correctly. I've looked at the example linked by unbird for view ports and I just cannot figure out how they get it so that when it presents it show the split screen image. It only seems to show the single image for me. now I can't show my code because it is place around a bunch of long and expansive code but basically it's like this:

 

some other part of the frame work calls beginscene then it calls my function

 

for(2 times)

{

     function does all the drawing stuff

 

     endscene()

     setViewport(second viewport)

     beginscene()

}

setViewport(first viewport)

beginscene()

 

function ends

the frame work later calls endscene()

 

lastly, the framework presents the image. I have altered it so that it presents the same image twice one over the other.

 

any advice? I know this is very sloppy but I've been at my wits end trying to do all of this. I just learned c++ and I'm sick now. Client has stopped bothering me since I've been e-mailing him daily progress. I'm thinking that if I can make a sloppy prototype of something that works, then I can redo a clean version of it, but I need something that works first. Anyways.

 

The second issue I am having is that when i enter fullscreen mode, the screen goes back to just one screen and with no split screen. I imagine this will fix when I can get the viewports setup. Any advice is appreciated!

Share this post


Link to post
Share on other sites
Buckeye    10747

To definitively help you, we'd have to see some code as the pseudo-code you posted above doesn't really make sense. It's not clear where your beginscene, clear calls, endscene and presents occur with respect to each other.

 

EDIT: I made an error in the code I posted above with respect to setting the rectangles for the viewport and presentation. Don't know if that messed you up. Apologies.

 


lastly, the framework presents the image

 

It sounds like you're presenting the backbuffer just once. That's a bit more complicated than the simple sequence I posted above, which is intended to be straight forward.

 

Repeating what I posted above:

 

1. Set the viewport to one-half of the backbuffer.

2. Clear, BeginScene, draw, Endscene

3. Present one-half of the backbuffer to one-half of the client area of the window.

 

Repeat for the other half of the backbuffer and client area.

Edited by Buckeye

Share this post


Link to post
Share on other sites
Catwheel    125

Thanks Buckeye! I think I'm gonna have to sit down and do some direct3D tutorials. I was hoping to avoid it to save time but now it seems like I've just wasted a bunch of time. To make sure I have you correctly though, each view port has to be presented while it is set and after it has done it's scene? So you're saying you cannot render both scenes for both viewports and then draw them in one call of present? Just to make sure I have that right. Also, any idea why fullscreen is only showing the results for one present call? This program is pretty big so it's easy for something to happen with out my knowing.

Share this post


Link to post
Share on other sites
Buckeye    10747

There are some semantics to straighten out. The viewport doesn't get presented or "do" a scene. The viewport determines what portion of the backbuffer gets cleared by Clear(), and drawn to. After the drawing is done, the Present call displays the results. Present takes several parameters (take a look at the docs). The first parameter is a pointer to a RECT that determines what portion of the backbuffer will be copied to the window client area. The second parameter is a pointer to a RECT that determines TO what portion of the client area the backbuffer will be copied.

 

 

 


So you're saying you cannot render both scenes for both viewports and then draw them in one call of present?

 

No, I didn't say that. It may be possible, though I didn't do it that way when I tried it out. It seems simpler (to me) to have a single drawing routine, set parameters in preparation for drawing, call the routine, set different parameters and call the routine a second time.

 

You certainly can't have 2 viewports active at one time. Further, Present doesn't do any drawing. Present copies all or a portion of the backbuffer to all or a portion of the window client area (as described above.)

Edited by Buckeye

Share this post


Link to post
Share on other sites
Victhor    101
Hi, nice to see some development on a Winamp plugin, are you allowed to tell something else about the nature of this job? Is it official or 3rd party? Will it be used for AVS or another kind of thing? (I've read the thread but I still can't figure out that). Sorry for the non-directly related post, but this it's sort of a good news :D. Don't hesitate to jump by the official forum (forums.winamp.com) for extra help (there aren't too many plugin devs left but there is some activity, specially from the main dev!)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this