PDA

View Full Version : Centre the scene on the screen



anime.igala.net
07-22-2008, 02:36 AM
Hi all,

I have a scene that has a bound: maxX, maxY, minx, minY, maxZ (may be = 0), minZ (may be = 0), the size of screen is: screenWidth, screenHeight. The point (0,0) is in the centre of the screen


- I would like to centre this scene on the screen.
- Zoom in and zoom out this scene but the scene is always in the centre of the screen. If the size of the scene is too large, it will be clipped.

How can I do this?
Thanks all,

dletozeun
07-22-2008, 03:20 AM
look at this:
FAQ 8.070 How can I automatically calculate a view that displays my entire model? (I know the bounding sphere and up vector.) (http://www.opengl.org/resources/faq/technical/viewing.htm#view0070)

anime.igala.net
07-22-2008, 03:24 AM
This approach should center your objects in the middle of the window and stretch them to fit

I don't want to stretch my scene. And this code does not work for me. See this thread: http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=241885#Post241885

Do you have the complate code that work?

Thanks so much,

dletozeun
07-22-2008, 03:34 AM
Ah yes, I read it too fast.

If you want to see the scene at the center of the screen, just draw a the world center and set the view (with glLookAt) to look at the center.
What is the problem with glLookAt? It is really simple to use in your case:
You need 3 camera parameters:
- camera position
- camera view axis
- camera vertical axis which is in most cases (0, 1, 0)

view axis in the vector between scene center (i.e (0,0,0)) and the camera position.

Then for zooming, you just need to recompute cmera position moving it along the view vector (this one should be normalized for a constant speed).

satan
07-22-2008, 04:18 AM
view vector (this one should be normalized for a constant speed).
I don't think so. IMHO it should be scaled by the camera distance so that you move slower near the model and move faster if the camera is farther away. Moving the camera at a constant speed is a very unsatisfying solution for zooming.

anime.igala.net
07-22-2008, 06:08 AM
Now, my code that run well is :


void Viewer::initGLES(){
glViewport( 0, 0, iScreenWidth, iScreenHeight );
glClearColor(0.f,0.f,0.1f,1.f);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);

//glFrustumf (-100.f,1000.f,-1000.f,500.f,3.f,300.f);
glFrustumf(-1500.f, 1500.f, -1500.f, 1500.f, 3.f, 1500.f);
//glFrustumf(Loader->minX, Loader->maxX, Loader->minY, Loader->maxY, 3.f, 2500.f);
//glFrustumf(657, 1155, -781, -442, 1.2f, 1500.f);
glMatrixMode(GL_MODELVIEW);
glShadeModel(GL_SMOOTH);
}

//--------------------------------------------
void Viewer::draw(){
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
float centerX = (Loader->minX + Loader->maxX)/2;
float centerY = (Loader->minY + Loader->maxY)/2;
float centerZ = 0;
//glScalef(m_scale, m_scale, m_scale);
//glTranslatef(centerX, centerY, centerZ);
glTranslatef(-1400.f, 1000.f, -3.f);
//glTranslatef(906.0f, -611.5f, -7.f);
//glScalef(2.0, 2.0, 2.0);

//glScalef(5.0, 5.0, 5.0);
glColor4f(0, 1, 0, 1);

drawScene();
}


But as you can see, the parameters of the function glFrustumf(-1500.f, 1500.f, -1500.f, 1500.f, 3.f, 1500.f); are fixed. It is not good, because I don't know the real data, it must be read from the data file.

And in the function glTranslatef(-1400.f, 1000.f, -3.f);, the parameters are also fixed. I would like to center my scene.

//glFrustumf(657, 1155, -781, -442, 1.2f, 1500.f); --> The real value in the data file.

How should I change thes parameters?

Thanks,

dletozeun
07-22-2008, 06:47 AM
satan> Yes this a good idea in this case. But one thing I don't like in this mode is when you look at little objects, you have to make a huge mouse scroll to move from 1 millimeter...

anime.igala.net> You have to compute this values according to the scene file.



glFrustumf(657, 1155, -781, -442, 1.2f, 1500.f);


if these values are the limits of the scene bounding box, you can find the scene center very easily:

xcenter = (right+left)/2
ycenter = (top+bottom)/2
zcenter = (far+near)/2

then you translate all scene vertices from the vector (-xcenter, -ycenter, -zcenter) and your scene is centered.

anime.igala.net
07-22-2008, 07:02 AM
yeah, I think that the problem now is in two functions: glFrustumf and glTranslatef.

If I use this, it works (these values are groped/fumbled):




void Viewer::initGLES(){
glViewport( 0, 0, iScreenWidth, iScreenHeight );
glClearColor(0.f,0.f,0.1f,1.f);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);

glFrustumf(-1500.f, 1500.f, -1500.f, 1500.f, 3.f, 1500.f);

glMatrixMode(GL_MODELVIEW);
glShadeModel(GL_SMOOTH);
}

//-----------------------------------
void Viewer::draw(){
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-1400.f, 1000.f, -3.f);
glColor4f(0, 1, 0, 1);

drawScene();
}






But it does not work with this one, I don’t know why:






void Viewer::initGLES(){
glViewport( 0, 0, iScreenWidth, iScreenHeight );
glClearColor(0.f,0.f,0.1f,1.f);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);

glFrustumf(Loader->minX, Loader->maxX, Loader->minY, Loader->maxY, 3.f, 1500.f);
//glFrustumf(657, 1155, -781, -442, 1.2f, 1500.f);
glMatrixMode(GL_MODELVIEW);
glShadeModel(GL_SMOOTH);
}
//------------------------
void Viewer::draw(){
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
float far = 1500;
float near = 1;
float centerX = (Loader->minX + Loader->maxX)/2;
float centerY = (Loader->minY + Loader->maxY)/2;
float centerZ = (far-near)/2;
glTranslatef(centerX, centerY, centerZ);

glColor4f(0, 1, 0, 1);

drawScene();
}

dletozeun
07-22-2008, 08:48 AM
float centerX = (Loader->minX + Loader->maxX)/2;
float centerY = (Loader->minY + Loader->maxY)/2;
float centerZ = (far-near)/2;
glTranslatef(centerX, centerY, centerZ);


What the hell is that? :D

I did not write this but:



xcenter = (right+left)/2
ycenter = (top+bottom)/2
zcenter = (far+near)/2


and then



translate all scene vertices from the vector (-xcenter, -ycenter, -zcenter)


AND

Since you have moved your scene center, this won't work:



glFrustumf(Loader->minX, Loader->maxX, Loader->minY, Loader->maxY, 3.f, 1500.f);


because as you translate all the scene from the vector (-xcenter, -ycenter, -zcenter), your scene boundaries move too. :)

you also have to translate each min/max value.

anime.igala.net
07-22-2008, 09:10 AM
So what's the code should be now? :p

Please help me! :)

dletozeun
07-22-2008, 09:42 AM
Are you kidding? Je t'ai maché le travail la! :)

It is very simple, you should draw your scene and the view frustrum on a paper and you will easily see the solution...

Because I am nice, this time I will help you, but please understand that people on a forum are not here to write your entire code.

So, for glFrustrum you should do this:



glFrustumf(Loader->minX-centerX, Loader->maxX-centerX, Loader->minY-centerY, Loader->maxY-centerY, 3.f-centerZ, 1500.f-centerZ);