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?
Communicating directly with Xlib is so early-90s (read: noone has done this, unless he's a framework designer, in the last 20 years!).
You're right, looping through pixels to update them on the screen is incredibly slow. That's why almost all modern GUI Frameworks use their own Xbuffers that they just draw on and instruct X to render.
As a comment on your approach: Game development on raw X doesn't make the least sense, as there are more protable, better performing, easier to use, small, well-tested libraries. Take SDL as an example.
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:
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