Xlib应用程序更新中的问题

时间:2016-04-08 13:31:03

标签: events x11 xlib

我正在Ubuntu上使用Xlib处理光线跟踪应用程序,应用程序正常工作但是当系统响应输入事件时图像更新存在问题。

问题是图像更新和频繁输入事件之间存在明显滞后,例如按住键和拖动鼠标。当我拖动鼠标但图像没有更新时,片刻之后,窗口上的图像会更新以响应之前的事件。我想原因是执行图像更新的不合适的地方,但我真的不知道如何解决这个错误。这是我的代码:

int main(int argc,char * argv []){

g_Display = XOpenDisplay(NULL);
if(g_Display == NULL)
{
    fprintf(stderr, "Cannot open display\n");
    exit(-1);

}

//Set up camera
g_Camera.SetUp(0.0f, 0.0f, 1.0f);
g_Camera.SetPosition(10.0f, 0.0f, 0.0f);
g_Camera.SetFocal(0.0f, 0.0f, 0.0f);
g_Camera.SetFovAngle(45.0f);
g_Camera.SetClipping(0.1f, 100.0f);

/* create a simple window, as a direct child of the screen's   */
/* root window. Use the screen's white color as the background */
/* color of the window. Place the new window's top-left corner */
/* at the given 'x,y' coordinates.                             */
g_Window = CreateSimpleWindow(g_Display, g_RendererWidth, g_RendererHeight, g_PositionX, g_PositionY);

g_TextWindow = CreateTextWindow(g_Display, g_Window, g_TextWinWidth, g_TextWinHeight, 0, 0);



/* allocate a new GC (graphics context) for drawing in the window. */
g_GraphicsContext = CreateGraphicsContext(g_Display, g_Window, 0);
XSync(g_Display, False);

MeshLoad("Model/Models/cow.obj");

HighResClock::HighResClock::time_point  lastFrame = HighResClock::HighResClock::now();
int nbFrame = 0;
float avgTime = 0.0f;

//voxlize mesh
VoxelizeOnClient();

XSelectInput(g_Display, g_Window, ExposureMask | KeyPressMask | KeyReleaseMask
        | ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
XMapWindow(g_Display, g_Window);

//create bmp image
CameraControl();

while(1)
{
    //render
    CameraControl();
    XNextEvent(g_Display, &g_Event);

    if(g_dirty)
    {
        //Set CPU time display
        //start timer
        std::chrono::microseconds l_ElapsedC = std::chrono::duration_cast<std::chrono::microseconds>(g_endC - g_start);
        std::chrono::microseconds l_Elapsed = std::chrono::duration_cast<std::chrono::microseconds>(g_end - g_start);

        avgTime += l_Elapsed.count();
        nbFrame++;

        if(std::chrono::duration_cast<std::chrono::milliseconds>(g_end - lastFrame).count() > 500)
        {
            lastFrame = g_end;
            std::stringstream stream;

            stream << "CPU time: " << l_ElapsedC.count() << " micros    ";
            stream << "FPS: "   << 1000000.0f*nbFrame / avgTime;

            DisplayText(g_Display, stream);

            nbFrame = 0;
            avgTime = 0.0f;
        }

        g_dirty = false;

    }

    //key events
    if(g_Event.type == KeyPress)
    {
        float x = 0, y = 0;
        switch (g_Event.xkey.keycode)
        {
                // key ESC
                case 0x09:
                {
                    exit(0);
                }
                    break;

                default:
                    break;

            }        

        }

    //mouse press event
    if(g_Event.type == ButtonPress)
    {              
        switch(g_Event.xbutton.button)
        {   
            //left button
            case Button1:
            {
                g_MouseLeft = true;
                g_PositionX = g_Event.xbutton.x;
                g_PositionY = g_Event.xbutton.y;
            }
                break;


            //right button
            case Button3:
            {
                g_MouseRight = true;
                g_PositionX = g_Event.xbutton.x;
                g_PositionY = g_Event.xbutton.y;
            }
                break;
        }
    }

    //mouse release event
    if(g_Event.type == ButtonRelease)
    {
        switch(g_Event.xbutton.button)
        {   
            //left button
            case Button1:
            {
                g_MouseLeft = false;
                g_PositionX = g_Event.xbutton.x;
                g_PositionY = g_Event.xbutton.y;
            }
                break;

            //right button
            case Button3:
            {
                g_MouseRight = false;
                g_PositionX = g_Event.xbutton.x;
                g_PositionY = g_Event.xbutton.y;
            }
                break;
        }
    }

    //mouse motion
    if(g_Event.type == MotionNotify)
    {            
        if(g_MouseLeft)
        {   

            if(g_Event.type == KeyPress && g_Event.xkey.keycode == 0x25)
            {
                /*Do something*/
            }
        }

        if(g_MouseRight)
        {            
            if(g_Event.type == KeyPress && g_Event.xkey.keycode == 0x25)
            {
                /* Update Camera */
            }
            else
            {
               /* Update Camera */
            }

            printf("Pressing mouse's right button and moving mouse. \n");

        }

        g_PositionX = g_Event.xbutton.x;
        g_PositionY = g_Event.xbutton.y;
    }

    XFlush(g_Display); 

    CameraControl();
}


XCloseDisplay(g_Display);

return 0;

}

在CameraControl()函数中,我使用XPutImage()和XSync()来更新窗口图形上下文中创建的图像缓冲区。

先谢谢,我感谢所有的建议和帮助。

0 个答案:

没有答案