I am drawing several shapes (such as circles) that are keyed off of the window height & width. Since the window always starts at a given size, they are drawn correctly, but when the window is resized, it messes the aspect ratio up.
How can I draw the shapes properly, regardless o开发者_Go百科f window size?
You definitely don't want to make the size of your objects explicitly dependent on the window size.
As already suggested by genpfault, adjust your projection matrix whenever the window size changes.
Things to do on window resize:
Adjust viewport
glViewport(0, 0, width, height)
Adjust scissor rectangle (only if you have
GL_SCISSOR_TEST
enabled)glScissor(0, 0, width, height)
Adjust projection matrix
In case of legacy (fixed function pipeline) OpenGL, you can do it the following ways:
glFrustum(left * ratio, right * ratio, bottom, top, nearClip,farClip)
or
glOrtho(left * ratio, right * ratio, bottom, top, nearClip,farClip)
or
gluOrtho2D(left * ratio, right * ratio, bottom, top)
(assuming that
left, right, bottom
andtop
are all equal andratio=width/height
)
If you're using something like gluPerspective() just use the window width/height ratio:
gluPerspective(60, (double)width/(double)height, 1, 256);
You should setup some sort of window handler function that is called whenever your OpenGL window is resized. You need to take care of the case when aspectRatio > 1, and when aspectRatio <= 1 separately. Not doing so may result in geometry falling offscreen after a screen resize.
void windowResizeHandler(int windowWidth, int windowHeight){
const float aspectRatio = ((float)windowWidth) / windowHeight;
float xSpan = 1; // Feel free to change this to any xSpan you need.
float ySpan = 1; // Feel free to change this to any ySpan you need.
if (aspectRatio > 1){
// Width > Height, so scale xSpan accordinly.
xSpan *= aspectRatio;
}
else{
// Height >= Width, so scale ySpan accordingly.
ySpan = xSpan / aspectRatio;
}
glOrhto2D(-1*xSpan, xSpan, -1*ySpan, ySpan, -1, 1);
// Use the entire window for rendering.
glViewport(0, 0, windowWidth, windowHeight);
}
I am learning opengl too. I faced this problem yesterday and I have not found the correct answer. Today, I have solve the problem. In my little program, the object changes size when resizing the window changing width or heigt. This is my code (please, forgive my errors):
#include <GL/freeglut.h>
void fnReshape(int ww, int hh)
{
GLdouble r;
if(hh == 0)
hh = 1.0;
if(hh > ww)
r = (double) hh / (double) ww;
else
r = (double) ww / (double) hh;
glViewport(0, 0, ww, hh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(hh > ww)
glFrustum(-1.0, 1.0, -1.0 * r, 1.0 * r, 2.0, 200.0);
else
glFrustum(-1.0 * r, 1.0 * r, -1.0, 1.0, 2.0, 200.0);
}
//////////////////////////////////////////////////////////////////
void fnDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0., 0., -5.);
glBegin(GL_QUAD_STRIP);
glColor3f(0., 0., 1.0);
glVertex3f(-1., -1., 0.);
glVertex3f(-1., 1., 0.);
glVertex3f(1., -1., 0.);
glVertex3f(1., 1., 0.);
glEnd();
glutSwapBuffers();
}
////////////////////////////////////////////////////////////
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA |GLUT_DOUBLE);
glutInitWindowSize(500, 500);
glutCreateWindow("Sample window");
glClearColor(1.0, 0, 0, 1.0);
glutDisplayFunc(fnDisplay);
glutReshapeFunc(fnReshape);
glutMainLoop();
return 0;
}
There are many methods to do that. Following example shows you how I'm doing it in my projects and its working. The example shows you simply a rectangle box which do not changes it size when window is resizing. You can directly copy and paste it in your project(consider that i'm a openGl beginner)
#include<windows.h>
#include<glut.h>
GLfloat x1=100.0f;
GLfloat y1=150.0f;
GLsizei rsize = 50;
GLfloat xstep=1.0f;
GLfloat ystep=1.0f;
GLfloat windowWidth;
GLfloat windowHeight;
void scene(void){
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f,0.0f,0.0f);
glRectf(x1,y1,x1+rsize,y1-rsize);
glutSwapBuffers();
}
void setupRc(void){
glClearColor(0.0f,0.0f,1.0f,0.0f);
}
void changeSize(GLsizei w,GLsizei h){
if(h==0)
h=1;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w>=h){
windowWidth=250.0f*w/h;
windowHeight=250.f;
}
else{
windowWidth=250.0f;
windowHeight=250.f*h/w;
}
glOrtho(0.0f,windowWidth,0.0f,windowHeight,1.0f,-1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void main(void){
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutCreateWindow("Rectangle");
glutReshapeFunc(changeSize);
glutDisplayFunc(scene);
setupRc();
glutMainLoop();
}
精彩评论