Multiple viewports and camera directions

Started by
5 comments, last by Psilobe 13 years, 4 months ago
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);}
Advertisement
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.
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
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.
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.
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
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();}
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.
If I was helpful, feel free to rate me up ;)If I wasn't and you feel to rate me down, please let me know why!
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.

This topic is closed to new replies.

Advertisement