Jump to content

  • Log In with Google      Sign In   
  • Create Account

Directx9 splitscreen view


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
13 replies to this topic

#1 Catwheel   Members   -  Reputation: 125

Like
0Likes
Like

Posted 01 August 2014 - 04:43 PM

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!



Sponsor:

#2 unbird   Crossbones+   -  Reputation: 6012

Like
3Likes
Like

Posted 01 August 2014 - 05:33 PM

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

#3 Catwheel   Members   -  Reputation: 125

Like
0Likes
Like

Posted 01 August 2014 - 05:57 PM

thank you! you are like an angle bird from on high! (no idea how to say that)



#4 Catwheel   Members   -  Reputation: 125

Like
0Likes
Like

Posted 01 August 2014 - 06:01 PM

Is directx9 and direct3D9 the same thing? if not, what is the difference?



#5 mark ds   Members   -  Reputation: 1480

Like
1Likes
Like

Posted 01 August 2014 - 06:16 PM

Directx is a series of technologies (including sound, input, 2D, 3D), whereas Direct3D is the 3D component (obviously!).



#6 Catwheel   Members   -  Reputation: 125

Like
0Likes
Like

Posted 01 August 2014 - 06:22 PM

awesome! thanks!



#7 unbird   Crossbones+   -  Reputation: 6012

Like
0Likes
Like

Posted 01 August 2014 - 07:00 PM

thank you! you are like an angle bird from on high! (no idea how to say that)


Nah, don't use angles, prefer vectors tongue.png

#8 Catwheel   Members   -  Reputation: 125

Like
0Likes
Like

Posted 02 August 2014 - 02:54 AM

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



#9 Buckeye   Crossbones+   -  Reputation: 6299

Like
0Likes
Like

Posted 02 August 2014 - 06:59 AM


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, 03 August 2014 - 07:40 AM.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.


#10 Catwheel   Members   -  Reputation: 125

Like
0Likes
Like

Posted 03 August 2014 - 12:28 AM

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!



#11 Buckeye   Crossbones+   -  Reputation: 6299

Like
0Likes
Like

Posted 03 August 2014 - 07:36 AM

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, 03 August 2014 - 07:42 AM.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.


#12 Catwheel   Members   -  Reputation: 125

Like
0Likes
Like

Posted 03 August 2014 - 11:58 AM

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.



#13 Buckeye   Crossbones+   -  Reputation: 6299

Like
1Likes
Like

Posted 03 August 2014 - 02:44 PM

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, 03 August 2014 - 02:46 PM.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.


#14 Victhor   Members   -  Reputation: 101

Like
0Likes
Like

Posted 05 August 2014 - 08:23 AM

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!)




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS