I am trying to create a game loop for an xlib window, but I cannot manage to paint the window correctly. Right now I am creating a window with XCreateSimpleWindow(...), and using a for loop to paint all pixels one at a time. (The color of these pixels is read from a large integer array, for now I've set all pixels to be blue.) The actual game loop right now is the following:
void loop() {
while (true) {
// Clear the window (the background color is set to white)
XClearWindow(dsp, win);
// Loop through all pixels of the 800*600 window
for (int j = 0; j < 600; j++) {
for (int i = 0; i < 800; i++) {
// Read the color from the pixels array (always blue for now)
long int color = pixels[i + 800*j];
// Set the foreground color for drawing
XSetForeground(dsp, gc, color);
// Draw the pixel
XDrawPoint(dsp, win, gc, i, j);
}
}
// Flush the output buffer
XFlush();
}
}
The variables dsp, win, pixels, gc are defined globally.
Now when I compile and execute the binary file, the rows with low y coordinate are mostly blue, but the rows with high y coordinate are mostly white. In between it is easy to see how it simply takes too much time to draw all pixels at once. I expect that this effect is because the top rows (low y) are drawn first, which means a short delay between XClearWindow() and XDrawPoint() for those pixels. (I also tested the fps, it takes around 7 milliseconds to run the while(true) loop once.)
I did some research, and read about how double buffering might solve this issue. I did follow a guide on double buffering with xlib (Xdbe), but it does not seem to solve the issue. Is there a faster way of drawing with xlib than just looping through all pixels? Is double buffering not supposed to solve this, or am I implementing it incorrectly?
The reason you are not seeing anything is because you are neglecting the X event loop. All you do is sending data to the X server, but there is no way for the X server to communicate back.
You must set up a loop where XEvents are read from the queue and dispatched c.q. processed. Something like:
XEvent event;
while (XPending (m_display))
{
XNextEvent (m_display, &event);
if (XFilterEvent (&event, None))
{
continue;
}
switch (event.type)
{
case KeyPress:
..
case ButtonPress:
..
case Expose:
..
case MapNotify:
..
// etc
}
}
This can be combined with your endless loop, though.
But yes, painting pixel by pixel is extremely slow. I don't even want to calculate the protocol overhead... :P
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With