PDA

View Full Version : resizing the window not the figure



pigman
10-02-2002, 03:59 AM
i have a triangle moving diagonally across the screen and changing color randomly. And i want the triangle to keep the same size even when the window is resized?
heres my code
#include <GL/glut.h>
#include <stdlib.h>


static void init(void){

/* select clearing color as white */
glClearColor (1.0, 1.0, 1.0, 0.0);

/* initialize viewing values */
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);

}
void triangle()
{

glBegin (GL_TRIANGLES);
glColor3ub( (char) random()%256, (char) random()%256, (char) random()%256);
glVertex3f(0.0, 0.85, 0.0);
glVertex3f(0.15, 0.95, 0.0);
glVertex3f(0.30, 0.85, 0.0);
glEnd();

}

void display(void)
{
float x = 0.0;

glClear(GL_COLOR_BUFFER_BIT);
glTranslatef(0.0025,-0.0025,0.0);
triangle();
glutPostRedisplay();
glFlush();
glutSwapBuffers();
}

/* reshape does nothing so that when the window is
* resized nothing happens to the shape or size of the
* triangle on the screen
*/
void reshape(int w, int h)
{

glViewport(0, 0, (GLint)w, (GLint)h);


}

void mouse(int btn, int state, int x, int y)
{

if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN){
init();
}
if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
exit(0);
}

/* Main Loop
* Open window with initial window size, title bar,
* RGBA display mode, and handle input events.
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutCreateWindow (argv[0]);
init();
glutMouseFunc(mouse);
glutDisplayFunc (display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}

Bob
10-02-2002, 04:07 AM
When your window is resized, you keep the size of the view volume at a fixed size (that is, you don't change it in the reshape function), and the objects will of course be scaled as the window is scaled. To prevent the objects from being scaled also, you must also scale the view volume accordingly. So when the screen is scaled by a factor 2, the viewvolume must also be scaled by a factor 2.

If we assume that 500x500 is the "default" window size in your program, and you want the object to keep their size as they appear in that window, you can add this to the reshape function. This will rescale the view volume as the window is resized.



double hScale = static_cast<double>(h) / static_cast<double>(500);
double wScale = static_cast<double>(w) / static_cast<double>(500);
glOrtho(0, wScale, 0, hScale, -1, 1);

Or if you use C, just replace static_cast with proper C-style typecasts.

[This message has been edited by Bob (edited 10-02-2002).]

nexusone
10-02-2002, 04:16 AM
First I see a problem in your code:


glutPostRedisplay(); // you should not call this here, I think you are not getting the correct results doing this.
glFlush();
glutSwapBuffers();
}
change to:
glFlush();
glutSwapBuffers();
glutPostRedisplay(); which make the program display keep recalling itself....

A better way would be to use:
glutIdleFunc(My_idle) and remove glutPostRedisplay() from your display routine.

void My_idle(void)
{
glutPostRedisplay();
}


Also add to your display routine:
display()
{
glClear(.......);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity ();


See if that helps:


Originally posted by pigman:
i have a triangle moving diagonally across the screen and changing color randomly. And i want the triangle to keep the same size even when the window is resized?
heres my code
#include <GL/glut.h>
#include <stdlib.h>


static void init(void){

/* select clearing color as white */
glClearColor (1.0, 1.0, 1.0, 0.0);

/* initialize viewing values */
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);

}
void triangle()
{

glBegin (GL_TRIANGLES);
glColor3ub( (char) random()%256, (char) random()%256, (char) random()%256);
glVertex3f(0.0, 0.85, 0.0);
glVertex3f(0.15, 0.95, 0.0);
glVertex3f(0.30, 0.85, 0.0);
glEnd();

}

void display(void)
{
float x = 0.0;

glClear(GL_COLOR_BUFFER_BIT);
glTranslatef(0.0025,-0.0025,0.0);
triangle();
glutPostRedisplay();
glFlush();
glutSwapBuffers();
}

/* reshape does nothing so that when the window is
* resized nothing happens to the shape or size of the
* triangle on the screen
*/
void reshape(int w, int h)
{

glViewport(0, 0, (GLint)w, (GLint)h);


}

void mouse(int btn, int state, int x, int y)
{

if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN){
init();
}
if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
exit(0);
}

/* Main Loop
* Open window with initial window size, title bar,
* RGBA display mode, and handle input events.
*/
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutCreateWindow (argv[0]);
init();
glutMouseFunc(mouse);
glutDisplayFunc (display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}

Bob
10-02-2002, 06:22 AM
Just saw I forgot an important thing in my post. Not only should you add the code I posted, but you should add this too to the reshape function. It's important to get it into the right matrix stack, and also make sure it's clean.



glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// The code I posted goes here
glMatrixMode(GL_MODELVIEW);

pigman
10-03-2002, 03:16 AM
Originally posted by Bob:
When your window is resized, you keep the size of the view volume at a fixed size (that is, you don't change it in the reshape function), and the objects will of course be scaled as the window is scaled. To prevent the objects from being scaled also, you must also scale the view volume accordingly. So when the screen is scaled by a factor 2, the viewvolume must also be scaled by a factor 2.

If we assume that 500x500 is the "default" window size in your program, and you want the object to keep their size as they appear in that window, you can add this to the reshape function. This will rescale the view volume as the window is resized.



double hScale = static_cast<double>(h) / static_cast<double>(500);
double wScale = static_cast<double>(w) / static_cast<double>(500);
glOrtho(0, wScale, 0, hScale, -1, 1);

Or if you use C, just replace static_cast with proper C-style typecasts.

[This message has been edited by Bob (edited 10-02-2002).]

I entered in both pieces of code and with the glViewport() function they get cancelled out...if i take the function out they work buti need the triangle to stay the same size,and contiue to move from corner to corner of the window. Without the glViewport function the triangle moves back and forth between the two original window corners.
Any ideas?

nexusone
10-03-2002, 04:11 AM
Did you look at my suggested code changes?

So you want the triangle to stay the same size, which means at some point durring the re-sizeing of a window to a smaller size, the triangle would take up the whole window.
Am I correct with that statment of what you want?
Which also means the area in which the triangle will have to move will also get smaller.


First understand what each view setting does:

glViewPort tell openGL the current window size in pixels in which to render to.

glOrtho tells openGL the scene area to render from.

you could have a openGL space of 1000 x 1000 set by glOrtho, but it will be rendered into a pixel space set by Viewport.

Example:
glViewPort(0, 0, 640, 480); the screen size is 640 x 480.

glOrtho( -5, 5, 5, -5, -1, 1); Out openGL space is 10 units wide by 10 units high, the 10 x 10 space will be rendered into the 640x480 pixel space.

To keep your triangle the same size we would reduce the ortho size by the same percentage as the reduction of our view port.


Originally posted by pigman:



double hScale = static_cast<double>(h) / static_cast<double>(500);
double wScale = static_cast<double>(w) / static_cast<double>(500);
glOrtho(0, wScale, 0, hScale, -1, 1);

Or if you use C, just replace static_cast with proper C-style typecasts.

[This message has been edited by Bob (edited 10-02-2002).]<HR></BLOCKQUOTE>

I entered in both pieces of code and with the glViewport() function they get cancelled out...if i take the function out they work buti need the triangle to stay the same size,and contiue to move from corner to corner of the window. Without the glViewport function the triangle moves back and forth between the two original window corners.
Any ideas?[/B]