在 Linux 中使用 glut 调整窗口大小时显示错误

Posted

技术标签:

【中文标题】在 Linux 中使用 glut 调整窗口大小时显示错误【英文标题】:Display error when resizing window using glut in Linux 【发布时间】:2017-03-06 07:06:52 【问题描述】:

我尝试编写一个简单的 glut 程序,但在调整窗口大小时发现显示错误(如图所示)。我使用带有 kde 的 Arch Linux。 我该如何解决?

调整大小之前:

调整大小后:

#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
void myinit(void)

  glClearColor(1.0, 1.0, 1.0, 1.0);
  glColor3f(1.0, 0.0, 0.0);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0.0, 500.0, 0.0, 500.0);
  glMatrixMode(GL_MODELVIEW);

void display( void )

  typedef GLfloat point2[2];
  point2 vertices[3]=0.0,0.0,250.0,500.0,500.0,0.0;
  int i, j, k;
  int rand();
  point2 p =75.0,50.0;
  glClear(GL_COLOR_BUFFER_BIT);
  for( k=0; k<5000; k++)
  
    j=rand()%3;
    p[0] = (p[0]+vertices[j][0])/2.0; 
    p[1] = (p[1]+vertices[j][1])/2.0;
    glBegin(GL_POINTS);
           glVertex2fv(p); 
    glEnd();
  
  glFlush();
  printf ("display invokved....\n");
 
void main(int argc, char** argv)

  glutInit(&argc,argv);
  glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
  glutInitWindowSize(500,500); 
  glutInitWindowPosition(0,0); 
  glutCreateWindow("Sierpinski Gasket"); 
  glutDisplayFunc(display); 
  myinit();
  glutMainLoop();

【问题讨论】:

在绘制每一帧之前尝试以当前窗口宽度和高度作为参数调用glViewport() 【参考方案1】:

切换到双缓冲 (GLUT_DOUBLE & glutSwapBuffers()) 在我的系统上修复它:

#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
void display( void )

  typedef GLfloat point2[2];
  point2 vertices[3]=0.0,0.0,250.0,500.0,500.0,0.0;
  int i, j, k;
  int rand();
  point2 p =75.0,50.0;

  glClearColor(1.0, 1.0, 1.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0.0, 500.0, 0.0, 500.0);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glBegin(GL_POINTS);
  glColor3f(1.0, 0.0, 0.0);
  for( k=0; k<5000; k++)
  
    j=rand()%3;
    p[0] = (p[0]+vertices[j][0])/2.0; 
    p[1] = (p[1]+vertices[j][1])/2.0;
    glVertex2fv(p); 
  
  glEnd();
  glutSwapBuffers();
 
int main(int argc, char** argv)

  glutInit(&argc,argv);
  glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
  glutInitWindowSize(500,500); 
  glutInitWindowPosition(0,0); 
  glutCreateWindow("Sierpinski Gasket"); 
  glutDisplayFunc(display); 
  glutMainLoop();
  return 0;

【讨论】:

谢谢,它有效!我可以问一下为什么使用 GLUT_SINGLE 会有问题吗? @haokunli:遗憾的是我没有很好的解释为什么GLUT_SINGLE 不能正常工作:( 我能够重现时髦的不调整大小的行为在我运行 MATE 的 Linux 机器上,无论是否启用桌面组合。 我明白了。非常感谢!【参考方案2】:

您需要捕获调整大小事件。在 glut 中,您必须使用函数glutReshapeFunc 注册回调。在此函数中,您可以更改投影参数和视口。

下面是您的程序中的一个小改动,展示了如何做到这一点:

(...)
void reshape(int width, int height)

   glViewport(0, 0, width, height);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluOrtho2D(0.0, width, 0.0, height);
   glMatrixMode(GL_MODELVIEW);

(...)
int main(int argc, char** argv)

(...)
   glutDisplayFunc(display); 
   glutReshapeFunc(reshape);  /* <--- */
   myinit();
(...)

【讨论】:

对不起,它不起作用。无法正确显示的区域仍然无法显示。但是由于您展开屏幕坐标,调整窗口大小时点不会改变位置。还是谢谢。

以上是关于在 Linux 中使用 glut 调整窗口大小时显示错误的主要内容,如果未能解决你的问题,请参考以下文章

opengl:调整大小时如何将对象保留在窗口中

OpenGL窗口大小渲染问题

当鼠标悬停在边框上时,如何完全禁用调整窗口大小,包括调整大小图标?

如何使用某个组合键+鼠标移动来调整窗口大小? (如 Linux 中的 Alt+F8)不单击并拖动

在 Linux 上与 GLUT 共享上下文

Linux(Deepin)的eclipse窗口字体大小怎样调整