OpenGL 在 window 调整大小时保持对象形状
OpenGL maintain object shape on window resize
我有一个正方形,我试图在 window 调整大小时使其保持正方形,而不是使用 window 进行拉伸。我有一些我认为可行的代码,但是当我调整 window 的大小时,正方形会缩小并消失。当我 return 将 window 恢复到原始大小时,它不会恢复。有人可以告诉我我做错了什么以及如何解决吗?
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex2f(-0.5, -0.5);
glVertex2f(-0.5, 0.5);
glVertex2f(0.5, 0.5);
glVertex2f(0.5, -0.5);
glEnd();
glFlush();
return;
}
void reshape(int w, int h) {
const float aspectRatio = ((float)w) / h;
float xSpan = 1;
float ySpan = 1;
if (aspectRatio > 1) {
xSpan *= aspectRatio;
}
else {
ySpan *= aspectRatio;
}
gluOrtho2D(-1*xSpan, xSpan, -1*ySpan, ySpan);
glViewport(0, 0, w, h);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutCreateWindow("simple");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
}
函数gluOrtho2D
and glOrtho
将当前矩阵乘以新的正交投影矩阵。
这导致如果 reshape
被第二次调用,之前由 gluOrtho2D
设置的矩阵乘以新的矩阵,你会得到连续的变化。
你必须通过 glLoadIdentity
. Further you should choose the projection matrix stack by glMatrixMode
:
"reset" 矩阵堆栈上的矩阵(初始化恒等矩阵)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1*xSpan, xSpan, -1*ySpan, ySpan);
视口 glViewport
的设置是正确的,您也正确考虑了宽高比(在 gluOrtho2D
中)。但如果纵横比小于 1.0,就会出现问题。应该是ySpan /= aspectRatio;
我建议在display
函数中设置视口和投影矩阵,并在reshape
函数中设置一个通知标志。请注意,视口和投影矩阵应尽可能少地更改。
bool vp_valid = true;
int width, height;
void reshape(int w, int h) {
vp_valid = false;
width = w;
height = h;
}
void display(void)
{
if (!vp_valid)
{
const float aspectRatio = (float)width / height;
float sx = aspectRatio > 1.0f ? aspectRatio : 1.0f;
float sy = aspectRatio > 1.0f ? 1.0f : 1.0f/aspectRatio;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-sx, sx, -sy, sy);
glViewport(0, 0, width, height);
}
.....
}
我有一个正方形,我试图在 window 调整大小时使其保持正方形,而不是使用 window 进行拉伸。我有一些我认为可行的代码,但是当我调整 window 的大小时,正方形会缩小并消失。当我 return 将 window 恢复到原始大小时,它不会恢复。有人可以告诉我我做错了什么以及如何解决吗?
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glVertex2f(-0.5, -0.5);
glVertex2f(-0.5, 0.5);
glVertex2f(0.5, 0.5);
glVertex2f(0.5, -0.5);
glEnd();
glFlush();
return;
}
void reshape(int w, int h) {
const float aspectRatio = ((float)w) / h;
float xSpan = 1;
float ySpan = 1;
if (aspectRatio > 1) {
xSpan *= aspectRatio;
}
else {
ySpan *= aspectRatio;
}
gluOrtho2D(-1*xSpan, xSpan, -1*ySpan, ySpan);
glViewport(0, 0, w, h);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutCreateWindow("simple");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
}
函数gluOrtho2D
and glOrtho
将当前矩阵乘以新的正交投影矩阵。
这导致如果 reshape
被第二次调用,之前由 gluOrtho2D
设置的矩阵乘以新的矩阵,你会得到连续的变化。
你必须通过 glLoadIdentity
. Further you should choose the projection matrix stack by glMatrixMode
:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1*xSpan, xSpan, -1*ySpan, ySpan);
视口 glViewport
的设置是正确的,您也正确考虑了宽高比(在 gluOrtho2D
中)。但如果纵横比小于 1.0,就会出现问题。应该是ySpan /= aspectRatio;
我建议在display
函数中设置视口和投影矩阵,并在reshape
函数中设置一个通知标志。请注意,视口和投影矩阵应尽可能少地更改。
bool vp_valid = true;
int width, height;
void reshape(int w, int h) {
vp_valid = false;
width = w;
height = h;
}
void display(void)
{
if (!vp_valid)
{
const float aspectRatio = (float)width / height;
float sx = aspectRatio > 1.0f ? aspectRatio : 1.0f;
float sy = aspectRatio > 1.0f ? 1.0f : 1.0f/aspectRatio;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-sx, sx, -sy, sy);
glViewport(0, 0, width, height);
}
.....
}