How to set Two viewport in OpenGL?

creater16
Unregistered
 
Post: #1
Hi guys, i have got a problem in doing my project,
if i wanna make 2 viewport in OpenGL, that is to say on our computer screen view 2 image at the same time like the attached picture. (the picture may be a little bit too big.....)

[img][Image: wireframe.jpg][/img]


thanks for help!!!
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
What API are you using to create the window? It may be simpler to use two contexts.

If not, you can use glViewport and glScissor to restrict drawing to a particular section of the screen.
Quote this message in a reply
creater16
Unregistered
 
Post: #3
if i am making a game using MFC, then if i use glScissor like you mention; then when i move will both of the screen move?


thanks!
Quote this message in a reply
Oldtimer
Posts: 834
Joined: 2002.09
Post: #4
Ah, MFC. This is a Mac programming forum, so you might or might not get help with that here. :
Nevertheless, here's what you do with glViewport:
When you start your program, glViewport is set to fill the window. When you draw, it will be scaled to fill the viewport, hence, the window. Now, what you can do is to set the viewport to half of your window - let's say the left. Everything you draw will be squeezed into the left half of the window. To achieve your desired effect, you do this. Then, before swapping, you set the viewport to the right half of the window, and draw the scene again. This will squeeze everything you draw the second time around into the right half.

I guess you're trying to implement some kind of stereo effect. For this, you need to move the camera a bit before rendering the second time.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #5
glViewport alone is not enough, you must also use glScissor to clip to the viewport.

glViewport simply establishes a coordinate system rectangle, it doesn't prevent things being rendered outside that rectangle. That's what glScissor does.
Quote this message in a reply
Member
Posts: 269
Joined: 2005.04
Post: #6
OneSadCookie Wrote:glViewport alone is not enough, you must also use glScissor to clip to the viewport.

glViewport simply establishes a coordinate system rectangle, it doesn't prevent things being rendered outside that rectangle. That's what glScissor does.

Is that actually true? I've done two views in one context by switching between alternate glViewports, but I've never had to use glScissor to keep from drawing outside the viewport.
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #7
Or use AGL_BUFFER_RECT, although, it's an AGL thing... I'm sure there is similar functionality in every implementation of OpenGL. Here is some lovely code I wrote, please pardon the language, there was 0 documentation on AGL_BUFFER_RECT.

Apple's code:
Code:
short FindGDHandleFromWindow (WindowPtr pWindow, GDHandle * phgdOnThisDevice)
{
    GrafPtr pgpSave;
    Rect rectWind, rectSect;
    long greatestArea, sectArea;
    short numDevices = 0;
    GDHandle hgdNthDevice;
    
    if (!pWindow || !phgdOnThisDevice)
        return -1;
        
    *phgdOnThisDevice = NULL;
    
    GetPort (&pgpSave);
    SetPortWindowPort (pWindow);

    GetWindowPortBounds (pWindow, &rectWind);
    
    LocalToGlobal ((Point*)& rectWind.top);
    LocalToGlobal ((Point*)& rectWind.bottom);
    
    hgdNthDevice = GetDeviceList();
    greatestArea = 0;

    while (hgdNthDevice)
    {
        if (TestDeviceAttribute (hgdNthDevice, screenDevice))
            if (TestDeviceAttribute (hgdNthDevice, screenActive))
            {
                SectRect (&rectWind, &(**hgdNthDevice).gdRect, &rectSect);
                sectArea = (long) (rectSect.right - rectSect.left) * (rectSect.bottom - rectSect.top);
                if (sectArea > 0)
                    numDevices++;
                if (sectArea > greatestArea)
                {
                    greatestArea = sectArea;
                    *phgdOnThisDevice = hgdNthDevice;
                }
                hgdNthDevice = GetNextDevice(hgdNthDevice);
            }
    }
    
    SetPort (pgpSave);
    return numDevices;
}
My code:
Code:
void CreateAGLAttributesForBufferRect(GLint* aglAttributes)
{
    int i = 0;
    aglAttributes[i++] = AGL_RGBA;
    aglAttributes[i++] = AGL_DOUBLEBUFFER;
    aglAttributes[i++] = AGL_ACCELERATED;
    aglAttributes[i++] = AGL_NO_RECOVERY;
    aglAttributes[i++] = AGL_DEPTH_SIZE;
    aglAttributes[i++] = 16;
    aglAttributes[i++] = AGL_NONE;
    
}
void CreateAGLPixelFormat(WindowRef w, GLint* aglAttributes, AGLPixelFormat & fmt)
{
    GDHandle hGD = NULL;
    short numDevices;
    fmt = 0;
    
    numDevices = FindGDHandleFromWindow(w,&hGD);
    
    fmt = aglChoosePixelFormat(&hGD, 1, aglAttributes);
}
void PutGLOnWindow(WindowRef w, AGLContext* aglContext, AGLPixelFormat fmt, Rect* vPort)
{
    Rect windowRect;
    Rect sRect;
    int height;
    int fullHeight;
    GrafPtr cgrafSave = NULL;

    SetPortWindowPort(w);
    GetWindowBounds(w, kWindowStructureRgn, &sRect);
    GetWindowBounds(w, kWindowContentRgn, &windowRect);
    height = windowRect.bottom - windowRect.top;
    fullHeight = sRect.bottom - sRect.top;

    GetPort (&cgrafSave);
    
    //Now build GL on it
    if(aglGetCurrentContext() != NULL)
        *aglContext = aglCreateContext(fmt, aglGetCurrentContext());
    else
        *aglContext = aglCreateContext(fmt, 0);

    aglSetDrawable(*aglContext, GetWindowPort(w));
    aglSetCurrentContext (*aglContext);
    
    SetPort (cgrafSave);
    
    //Setup context if it was created properly.
    if (!(*aglContext))
    {
        //destroy contexts... do later
        return;        
    }
    else
    {
        aglSetCurrentContext (*aglContext);
        aglUpdateContext (*aglContext);

        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glEnable(GL_TEXTURE_2D);
        
        glClearColor(0, 0, 0, 1.0f);
        glClear (GL_COLOR_BUFFER_BIT);
        //aglSwapBuffers (*aglContext);
        //left edge == vPort->left
        //bottom edge == height - vPort->bottom
        //width = vPort->right - vPort->left
        //height = vPort->bottom - vPort->left
        //alright, so supposedly agl_buffer_rect is based on the structure region
        //therefore, that is not only #1 ***, but #2 inconvenient...
        //so we need to rework all this ******* bulshit
        //GLint aiRect[4] = { contain->left, contain->top, contain->right - contain->left, contain->bottom - contain->top};
        GLint aiRect[4];
        aiRect[0] = vPort->left;
        aiRect[1] = fullHeight - vPort->bottom;
        aiRect[2] = vPort->right - vPort->left;
        aiRect[3] = vPort->bottom - vPort->top;
        
        aglSetInteger(*aglContext, AGL_BUFFER_RECT, aiRect);
        aglEnable (*aglContext, AGL_BUFFER_RECT);
        glViewport (0, 0, vPort->right - vPort->left, vPort->bottom - vPort->top);
        aglUpdateContext (*aglContext);
    }
    aglSetCurrentContext(*aglContext);
}
Usage:
Code:
GLint aglAttributes[64];
    CreateAGLAttributesForBufferRect(aglAttributes);
    CreateAGLPixelFormat(totalWindow, aglAttributes, fmt);

    PutGLOnWindow(totalWindow, &showContext, fmt, &glContextRect);
Quote this message in a reply
creater16
Unregistered
 
Post: #8
Fenris Wrote:I guess you're trying to implement some kind of stereo effect. For this, you need to move the camera a bit before rendering the second time.

yes, i am trying to do a stereo effect.


Fenris Wrote:To achieve your desired effect, you do this. Then, before swapping, you set the viewport to the right half of the window, and draw the scene again. This will squeeze everything you draw the second time around into the right half.


my Tutor told me that i don't need to draw the scene again, instead just set 2 cameras to view an object, hence 2 view port one left and right, and shift one image a bit.
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #9
I suggest doing it a slightly different way
http://astronomy.swin.edu.au/~pbourke/opengl/stereogl/

Some people can only wall eyed view steriograms so the doing it that way will force them to spend ages trying to view it properly when they just cant, using overlayed graphics and sterio glasses is cool too!

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
creater16
Unregistered
 
Post: #10
unknown Wrote:I suggest doing it a slightly different way
http://astronomy.swin.edu.au/~pbourke/opengl/stereogl/

i know this website too.

unknown Wrote:Some people can only wall eyed view steriograms so the doing it that way will force them to spend ages trying to view it properly when they just cant, using overlayed graphics and sterio glasses is cool too!


I have to follow the way that the university is given, what I need to do is to view an image twice into lft and right and then plugin to the PC with 2 projectors(of coz the graphic card will support this), lastly wear 3D glasses for look at the stereo Images.
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #11
The Univeristy are letting you use two projectors for your own 3D project!
Your lucky!

Quote: lastly wear 3D glasses for look at the stereo Images.
Do you mean, thats the last thing your going to do, or your definitly not going to do that?

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
creater16
Unregistered
 
Post: #12
I have to use 3D glasses for the images, that is what i meant
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #13
Oh right, can I ask cos im intrested are you going to project the two images directly on top of each other then?

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
creater16
Unregistered
 
Post: #14
unknown Wrote:Oh right, can I ask cos im intrested are you going to project the two images directly on top of each other then?


exactly right you are, but the difference is one of the screen is slightly shifted.
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #15
Then you should have a look at the code paul bourke uses, it will give the same result and only use one projector.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Viewport aligned billboarding Zoldar256 1 3,000 Jul 12, 2003 04:03 PM
Last Post: Feanor