texted's picture

Two viewport in same Gamewindow

Hi, is it possible to have more than one viewport on same GameWindow?

If so, how to reference them?

// Initialize the first viewport
GL.Viewport(Rectangle)

How to initialize the second one? after initialized, how to reference each of them?
Thanks


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
c2woody's picture

There are lots of tutorials out there how to do multi-viewport layouts in OpenGL, NeHe has one in the first few lessons.

texted's picture

Thanks for your help~

the Fiddler's picture

The general idea is this:

GL.Viewport(Rectangle1);
// Draw to first viewport
GL.Viewport(Rectangle2);
// Draw to second viewport

Repeat ad nauseam.

texted's picture

If I do this, the first viewport contents will gone.

c2woody's picture

Then you did something wrong, or didn't understand how it's supposed to be used (again check the web for a lot of examples).

Richard_Kain's picture

You will need to provide more details if you want additional help. Off hand, I would say that you are clearing something at the wrong point in your render loop. Keep in mind that OpenGL is a very procedural API, everything happens in a specific order.

In this case, I think the following order would be proper for your render loop...

1. Clear the buffer
2. Define your projection.
3. Refresh your model matrix
4. Define your 1st viewport
5. Run the drawing code for your 1st viewport
6. Clear the buffer
7. Define your 2nd viewport
8. Run the drawing code for your 2nd viewport
9. Swap the buffer

Please note that swapping the buffer and clearing the buffer are not the same thing. Clearing the buffer cleans out whatever you had been drawing previously, and readies the buffer for more blank-slate drawing.

Another approach to this is to use a FrameBuffer Object to draw to textures instead. But that is another ball of wax, and probably isn't necessary for what you're trying to achieve.

nythrix's picture

Also, glScissor() is required for multiple viewports to work properly. That's why you're probably loosing all but the last viewport.

http://www.opengl.org/sdk/docs/man/xhtml/glScissor.xml

Richard_Kain's picture
nythrix wrote:

Also, glScissor() is required for multiple viewports to work properly. That's why you're probably loosing all but the last viewport.

http://www.opengl.org/sdk/docs/man/xhtml/glScissor.xml

Ooooo, I wasn't aware of that scissor function. That could be really useful for a scaled-down camera system. I'm going to have to give it a try.

Richard_Kain's picture

Okay, I played around with this feature a little last night, and I was actually quite pleased with the results. I decided to use this method for adding multiple viewports to my personal project instead of the FBO solution I had been planning. Using Viewports doesn't allow for as many features, but it is simpler, and should be better for performance. Here's some code that I cooked up...

protected override void OnRenderFrame (FrameEventArgs e)
{
	base.OnRenderFrame (e);
	GL.Clear(ClearBufferMask.ColorBufferBit);
 
	GL.Viewport(0, 0, 160, 240);
	GL.MatrixMode(MatrixMode.Modelview);
	GL.LoadIdentity();
	GL.Ortho(0.0, 160.0, 240.0, 0.0, -1.0, 1.0);
	// First Viewport Drawing Code Goes Here
 
	GL.Viewport(160, 0, 160, 240);
	GL.MatrixMode(MatrixMode.Modelview);
	GL.LoadIdentity();
	GL.Ortho(0.0, 160.0, 240.0, 0.0, -1.0, 1.0);
	GL.Translate(160.0, 0.0, 0.0);
	//Second Viewport Drawing Code Goes Here
 
	this.SwapBuffers();
}

This method seems to work for me. It creates two viewports that bisect a 320 x 240 window. I attempted to render the same object using the same position settings, and it seemed to work just fine. I didn't seem to need the Scissors function, but I may have just been missing out on what it would have been able to provide. I'll have to do some further testing to determine how to handle this viewport code.

nythrix's picture

Yeah, you don't need glScissor there because you're clearing the whole framebuffer at once. However, if you want to clear only the viewport you're about to draw to (as you suggested before) you need glScissor (I think).