Sign in to follow this  

Multiple viewports and camera directions

This topic is 2548 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm setting up an environment where I can look at my scene through either 1 or 4 veiwports and even thou I almost got it working traversing hurdles like flickering and clipping I still got two problems left.

First my perspectives are messed up when in 4 viewport mode, they look "squashed" and wrong and I tried to fix it with :

gluPerspective(45.0f, (w/2) / (h/2), 0.1f, 100.0f);

but it's still not working.


Secondly when in 4 viewport mode I want 3 views to be fixed, like top-down, left and front but I'm having some trouble.

I thought this would give me top-down view gluLookAt(0,30,0,0,0,0,0,1,0); but it aint.


Here is my code:

void display(int what)
{
if(what==5){glViewport(0, 0, w, h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
ca.lookAt();}

if(what==1){glViewport(0, 0, w/2, h/2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(55,15,-5,0,5,-5,0,1,0);}

if(what==2){glViewport(w/2, h/2, w, h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,30,0,0,0,0,0,1,0);}

if(what==3){glViewport(w/2, 0, w, h/2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
ca.lookAt();}

if(what==4){glViewport(0, h/2, w/2, h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(15,15,15,0,0,0,0,1,0);}


//glMatrixMode(GL_MODELVIEW);
//glLoadIdentity();
////gluLookAt(cos(shared.time) * shared.distance, 10, sin(shared.time) * shared.distance, 0, 0, 0, 0, 1, 0); // Roterar kameran kring origo genom att skapa en ny vymatris varje bildruta
////ca.orbitYaw(0.05);
//ca.lookAt();

glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
drawScene();
glutSwapBuffers();
}

void viewport(){
glEnable(GL_SCISSOR_TEST);

if(!divided_view_port)
{
glViewport(0, 0, w, h);
glScissor(0,0,640,480);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, w / h, 0.1f, 100.0f);
display(5);
}

else
{
////////////////////// bottom left - working
glViewport(0, 0, w/2, h/2);
glScissor(0,0,w/2,h/2);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (w/2) / (h/2), 0.1f, 100.0f);
display(1);
//////////////////////


////////////////////// top right - working
glViewport(w/2, h/2, w, h);
glScissor(w/2,h/2,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (w/2) / (h/2), 0.1f, 100.0f);
display(2);
//////////////////////

////////////////////// bottom right -working
glViewport(w/2, 0, w, h/2);
glScissor(w/2,0,w,h/2);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (w/2) / (h/2), 0.1f, 100.0f);
display(3);
////////////////////////

////////////////////////// top left
glViewport(0, h/2, w/2, h);
glScissor(0,h/2,w/2,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (w/2) / (h/2), 0.1f, 100.0f);
display(4);
///////////////////////////
}

glDisable(GL_SCISSOR_TEST);
glMatrixMode(GL_MODELVIEW);
}

Share this post


Link to post
Share on other sites
Note that glViewport parameters are position and size, so glViewport(w/2, h/2, w, h); will result in a fullsize viewport starting at the center.

For the view portion of the modelview matrix: gluLookAt(0,30,0,0,0,0,0,1,0); won't work, since the camera should look down from 0,30,0 to 0,0,0 but the up vector points in the opposite direction. However, the up vector needs to be non-parallel (ideally orthogonal) to the view direction, so try gluLookAt(0,30,0,0,0,0,0,,1); instead.

From what you describe you seem to be making an editor. AFAIK most editors have ortho projection for their top-down, front-back, left-right etc. views. This would require you to use glOrtho instead of gluPerspective, though.

Share this post


Link to post
Share on other sites
I actually managed to get everything to work after some fiddling, realised that the second pair of parameters for glViewport() was width and height not endpoints.

What I'm creating is similar to and editor but basically just training so at the moment Ortho isnt needed for what I'm doing.

Got one second question thou.

In 3 of the viewports I want to show camera position and target position and I've done so by rendering spheres at each location but I dont want these to be shown in the "perspective" viewport and I'm wondering if there is any way to do this viewport specific object culling.

One way I guess would be to render the view from the three viewports to texture, then render perspective viewport to texture, mix and render to screen but that seems like an awful lot of work for something so relatively easy.

Share this post


Link to post
Share on other sites
Since you need to issue a draw call for every viewport anyways you could do that in your display function. Just query the type of view you're rendering and skip those spheres for the perspective view.

Share this post


Link to post
Share on other sites
Not sure I'm following what you mean.



At the end I got this piece which draws everything.
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
drawScene();
drawCamera();
glutSwapBuffers();


If you suggest I should do it like this instead It only produces a black screen:
if(what==5){
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawScene();
drawCamera();
camControll();}


If i use swapbuffers duplicate times it will start to flicker.

Or should It be like this and jsut put drawScene/drawCamera in under correct viewport?

if(what==5){
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawScene();
drawCamera();
camControll();}


Or am I going in the entierly wrong direction?

Here is the code for display(int what).
void display(int what)
{
if(what==5){
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
camControll();}

if(what==1){
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(75,15,-5,0,5,-5,0,1,0);}

if(what==2){
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,110,0,0,0,0,1,0,0);}

if(what==3){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, float(320) / float(240), 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
camControll();}

if(what==4){
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(185,75,25,0,28,0,0,1,0);}


glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
drawScene();
drawCamera();
glutSwapBuffers();
}

Share this post


Link to post
Share on other sites
I'm not sure what drawScene() and drawCamera() do, but you seem to draw the spheres in one of those functions. So pass the int to those and decide whether to skip the spheres or not.

If drawCamera() is the function drawing just those spheres just add something like

if(what==ortho_view_id) //or if(what in a list of ortho view id)
{
drawCamera();
}


And please use the [source] tags for longer portions of code.

Share this post


Link to post
Share on other sites
Ok, I'll start using those tags instead.

I'll try out what you are suggesting but I'm using perspective instead of ortho but it shouldn't be to hard to switch.

Big thanks for all the help so far.

Share this post


Link to post
Share on other sites

This topic is 2548 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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