Skip to content

Non Flickering Canvas GUI Tutorial

Misha edited this page Nov 11, 2021 · 6 revisions

Welcome to my tutorial! Today, we are going to make a fully working GUI that doesn't flicker with a mouse. First, make sure to add the using lines for both System.Drawing and Cosmos.System.Graphics. First, we need to define the screen x and y size. Make these ints that are not in a method.

private static int screenX = 800;
private static int screenY = 640;

Second, define the pixel buffer. This will store all of the pixels you are setting until the screen is drawn. We also need one that will store the last frame's buffer to check against for the same pixel. We use (x * y) + x so that we can differentiate from pixel (3, 3) and (9, 1). If we only used x*y, those two coordinates would give the same pixel.

private static Color[] pixelBuffer = new Color[(screenX * screenY) + screenX];
private static Color[] pixelBufferOld = new Color[(screenX * screenY) + screenX];

Let's add a canvas variable.

private static Canvas canvas;

We need to make an init method as well to initialize the canvas.

public static void init() {
    canvas = FullScreenCanvas.GetFullScreenCanvas();
    canvas.Mode = new Mode(screenX, screenY, ColorDepth.ColorDepth32);
}

Now that we've gotten everything initialized, let's make the first method. This one will set a pixel inside the buffer to a specific color. We will use this instead of the canvas.setPixel() method. Here, we check if the pixel location is outside of the screen dimensions, and if not, set the buffer at that location to that color.

public static void setPixel(int x, int y, Color c) {
    if (x > screenX || y > screenY) return;
    pixelBuffer[(x * y) + x] = c;
}

After that, we need to draw the screen. So let's make that method. I randomly picked Color.Orange for the starting pen color, but it doesn't matter at all. This just loops through all pixels on the screen, checks if they are different from the last version, and then changes them if they are.

public static void drawScreen() {
    Pen pen = new Pen(Color.Orange);
    for (int y = 0, h = screenY; y < h; y++)
    {
        for (int x = 0, w = screenX; x < w; x++)
        {
            if (!(pixelBuffer[(y * x) + x] == pixelBufferOld[(y * y) + x]))
            {
                pen.Color = pixelBuffer[(y * screenX) + x];
                canvas.DrawPoint(pen, x, y);
            }
        }
    }
    for (int i = 0, len = pixelBuffer.Length; i < len; i++)
    {
        pixelBuffer[i] = pixelBufferOld[i];
    }
}

Next, let's make a method to set all of the pixels on the screen to a certain color.

public static void clearScreen(Color c) {
    for (int i = 0, len = pixelBuffer.Length; i < len; i++)
    {
        pixelBuffer[i] = c;
    }
}

Ok. Now we can set pixels, clear the screen, and draw all the pixels! The last thing we need is an update method. This is where you put all the code to set the pixels. Using the setPixel method we made, you can make all kinds of methods, like rectangles, etc etc. Here's the update method. If you put this in a separate class like "DisplayDriver.cs", just put DisplayDriver.update(); in the run method in the kernel.cs and add the DisplayDriver.init() call in the beforerun method.

public static void update() {
    clearScreen(Color.Blue);
    setPixel(1, 1, Color.Black);
    setPixel(1, 2, Color.Black);
    setPixel(2, 1, Color.Black);
    setPixel(2, 2, Color.Black);
    drawScreen();
}

Now we're done! Let me know if there are any issues or need help. In the next tutorial, I'll show how to add a mouse to the GUI.

Clone this wiki locally