X11 Window 不会自动更新/绘图

Posted

技术标签:

【中文标题】X11 Window 不会自动更新/绘图【英文标题】:X11 Window isn't updating/drawing automatically 【发布时间】:2014-06-23 08:16:22 【问题描述】:

我使用 x11(在 slackware linux 中)作为使用 OpenGL 进行绘图的窗口。

一切正常,但不知何故我的 x11 窗口没有自动更新/绘图。

如果我调整窗口大小,它只会更新/绘制。

x11 窗口代码:

int main()


    /***************  VARIABLE DEFINITION SECTION  ***************/

    Display *dpy;
    Window root;
    GLint att[] = GLX_RGBA,GLX_DEPTH_SIZE,24,GLX_DOUBLEBUFFER,None;
    XVisualInfo *vi;
    Colormap cmap;
    XSetWindowAttributes swa;
    Window win;
    GLXContext glc;
    XWindowAttributes gwa;
    XEvent xev;

    enum GAMEOBJECTS USER, ENEMY;                     //Object Enum - to identify the objects, object must be added in same enumeration you've created the objects

    Renderer *renderer = new Renderer();                //Renderer Object


    /***************  LINUX WINDOW SETTINGS  ***************/


    dpy = XOpenDisplay(NULL);
    if(dpy == NULL)
    
        cout << "\ncan't connect to x server\n" << endl;
        exit(0);
    

    root = DefaultRootWindow(dpy);    
    vi = glXChooseVisual(dpy,0,att);


    if(vi == NULL)
    
        cout << "\n no appropriate visual found \n" << endl;
        exit(0);
    
    else
    
        cout << "visual " << (void *)vi->visualid << "selected";
    


    cmap = XCreateColormap(dpy, root, vi->visual, AllocNone);
    swa.colormap = cmap;
    swa.event_mask = ExposureMask | KeyPressMask;

    win = XCreateWindow(dpy,root,0,0,800,600,0,vi->depth,InputOutput,vi->visual,CWColormap | CWEventMask, &swa);


    XMapWindow(dpy,win);

    XStoreName(dpy,win,"VERY SIMPLE APP");

    glc = glXCreateContext(dpy,vi,NULL,GL_TRUE);
    glXMakeCurrent(dpy,win,glc);

    cout << "ENUM: " << USER << endl;
    cout << "ENUM: " << ENEMY << endl;

    /***************  START RENDERER AND ADD OBJECTS ***************/

    renderer->initGL();

    renderer->addObject(100,100);   // USER
    renderer->move(USER,0,-100);    //move to startposition of USER

    renderer->addObject(100,100);   // ENEMY
    renderer->move(ENEMY,0,100);    //move to startposition of ENEMY

    glEnable(GL_DEPTH_TEST);


    /***************  GAME LOOP += GAME LOOP NEEDS A OWN GAME LOOP ***************/
    int count = 0;
    while(1)
    
        XNextEvent(dpy,&xev);
        //glViewport(0,0,gwa.width,gwa.height);
        //renderer->drawGL();

        renderer->move(ENEMY,count,100);
        if(xev.type == Expose)
        
            XGetWindowAttributes(dpy,win,&gwa);
            glViewport(0,0,gwa.width,gwa.height);
            renderer->drawGL();     // DRAW OPENGL
            glXSwapBuffers(dpy,win);
        

        else if(xev.type == KeyPress)
        
            switch(XLookupKeysym(&xev.xkey,0))
            
                case XK_Left:   cout << "LEFT KEY PRESSED" << endl;
                                renderer->move(USER,-1.0f,0.0f); //Move USER to the right
                                xev.xkey.send_event;
                                break;

                case XK_Right:  cout << "RIGHT KEY PRESSED" << endl;
                                renderer->move(USER,1.0f,0.0f); //Move USER to the right
                                break;

                case XK_Escape: glXMakeCurrent(dpy,None,NULL);
                                glXDestroyContext(dpy,glc);
                                XDestroyWindow(dpy,win);
                                XCloseDisplay(dpy);
                                exit(0);
                                break;

                case XK_P: cout << "P KEY PRESSEED" << endl;
                           break;

                case ConfigureNotify:   renderer->resizeGL(xev.xconfigure.width,xev.xconfigure.height);
                                        break;
            

        
        renderer->drawGL();   //DRAW OPENGL
        glXSwapBuffers(dpy,win);
        count++;
    

    return 0;

有人可以帮忙吗?

【问题讨论】:

【参考方案1】:
   The XNextEvent function copies the first event from the event queue into the
   specified XEvent structure and then removes it from the queue.  If the event
   queue is empty, XNextEvent flushes the output buffer and blocks until an event
   is received.

因此,您对XNextEvent 的调用会等到某个事件发生,然后才会重绘。更糟糕的是,它会在每个事件上重绘,所以如果发生多个事件,你只会在几帧之后才知道。

您应该改用XCheckWindowEvent,并重新组织您的循环(先处理所有事件,然后渲染)。

【讨论】:

以上是关于X11 Window 不会自动更新/绘图的主要内容,如果未能解决你的问题,请参考以下文章

如何关闭MyEclipse自动更新

Window Server 2019 配置篇- 在域中建立WSUS以实现自动更新

如何禁止win10系统应用商店自动更新

如何禁止win10系统应用商店自动更新

如何禁止win10系统应用商店自动更新

因Window服务器自动更新并重启导致WebSphere服务故障一例