我正在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()来更新窗口图形上下文中创建的图像缓冲区。
先谢谢,我感谢所有的建议和帮助。