无法正确改变窗口中多边形的形状

Can't correctly reshape polygons in the window

本文关键字:多边形 窗口 改变      更新时间:2023-10-16

我正在尝试开发一个程序,其中每次在窗口上执行单击时,窗口上都会出现一个随机大小的圆圈,以单击发生的位置为中心。 之后,我需要使用 glOrtho(( 或 gluOrtho2D((,以便以这样一种方式设置查看音量:当调整窗口大小时,圆圈不会改变其大小或在屏幕上失真。

我尝试以不同的方式编写 reshape 函数,但我无法得到正确的结果。

int winWidth = 800;             
int winHeight = 600; 
int main( int argc, char** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE );  
glutInitWindowSize( winWidth, winHeight );
glutCreateWindow( "main" );
MyInit();
glutDisplayFunc( MyDisplay );
glutReshapeFunc( MyReshape );
glutMouseFunc( MyMouse );
glutMainLoop();
return 0;
}
void MyReshape( int w, int h )
{
winWidth = w;
winHeight = h;
glViewport( 0, 0, w, h );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
if (w <= h)
glOrtho(-2.0, 2.0, -2.0 * (GLfloat) h / (GLfloat) w,
2.0 * (GLfloat) h / (GLfloat) w, -20.0, 20.0);
else
glOrtho(-2.0 * (GLfloat) w / (GLfloat) h,
2.0 * (GLfloat) w / (GLfloat) h, -2.0, 2.0, -20.0, 20.0);
glMatrixMode( GL_MODELVIEW );
}
void MyMouse( int btn, int state, int x, int y )
{
if ( btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN )
{
disc[numDiscs].pos[0] = x;
disc[numDiscs].pos[1] = y;
disc[numDiscs].speed[0] = ((rand() % 2) * 2 - 1) * (MIN_X_SPEED + rand() / (RAND_MAX / (MAX_X_SPEED - MIN_X_SPEED)));
disc[numDiscs].speed[1] = ((rand() % 2) * 2 - 1) * (MIN_Y_SPEED + rand() / (RAND_MAX / (MAX_Y_SPEED - MIN_Y_SPEED)));
disc[numDiscs].radius = (MIN_RADIUS + rand() / (RAND_MAX / (MAX_RADIUS - MIN_RADIUS)))/10;
disc[numDiscs].color[0] = (char)rand() % 256;
disc[numDiscs].color[1] = (char)rand() % 256;
disc[numDiscs].color[2] = (char)rand() % 256;
numDiscs++;
glutPostRedisplay();
}
}
void MyDisplay( void )
{
glClear( GL_COLOR_BUFFER_BIT );
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
for ( int i = 0; i < numDiscs; i++ ) DrawDisc( &disc[i] );
glFlush();  
}
void MyInit( void )
{
glClearColor( 0.0, 0.0, 0.0, 1.0 ); 
glShadeModel( GL_FLAT );
}
[...] 以

这样的方式,当调整窗口大小时,圆圈不会改变其大小或扭曲 [...]

如果圆应该以像素为单位保持大小,则必须定义正交投影,该投影基于窗口的当前大小与窗口的初始大小之间的关系。
由于窗口的大小为 (800, 600(,因此您必须根据窗口的高度将投影分别缩放w/600.0h/600.0,因为高度小于宽度,并且坡向应用于较长的一侧:

void MyReshape( int w, int h )
{
winWidth = w;
winHeight = h;
glViewport( 0, 0, w, h );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
if (w <= h)
{
GLdouble  aspect = (GLdouble)h / w;
GLdouble  scale  = w / 600.0;
scale *= 2.0;
project = glm::ortho(-scale, scale, -scale * aspect, scale * aspect, -20.0, 20.0);
}
else
{
GLdouble  aspect = (GLdouble)w / h;
GLdouble  scale  = h / 600.0;
scale *= 2.0;
project = glm::ortho(-scale * aspect, scale * aspect, -scale, scale, -20.0, 20.0);
}
glMatrixMode( GL_MODELVIEW );
}