javascriptcanvaswebglpixel

Draw each pixel separately WebGL


First of all, let me talk about my target. I'm creating another one pixel art online editor and decide to make it with WebGL only (no Canvas2D at all). Pretty stupid of me because I have no knowledge in this technology, but I'm trying! So... the question: how to change the color of the only one pixel? I has struggled with another of my "misunderstand" and found this answer with particle system:

https://stackoverflow.com/a/16465343/4458277

and I rewrote it to make it appear close to my case:

https://jsfiddle.net/kurz/rt2n7hmb/1/

As you can see, there are 10 pixels with equal colour when you draw on canvas. Here the main draw method:

function mouseMoveEvent(e) {
    /*... detect x and y...*/
    gl.bindBuffer(gl.ARRAY_BUFFER, particleBuffer);
    var data = new Float32Array(2);
    data[0] = x;
    data[1] = y;
    gl.uniform4f(
        gl.getUniformLocation(shaderProgram, "color"),
        Math.random(),
        Math.random(),
        Math.random(),
        1.0
    );
    gl.bufferSubData(gl.ARRAY_BUFFER, particleId * particleSize * sizeOfFloat, data);
    particleId = (particleId + 1) % vertexBufferSize;
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.POINTS, 0, vertexBufferSize);
}

So how to change this example to the pixels drawn each with a unique color?

Some of you probably say: "use canvas2d!". - No! I think that the future is not canvas2d. "So use library!". - No, again! For that "simple" thing like draw squares I don't want include large library.

Thank you!


Solution

  • What you need to understand about that code which you posted is that it is passing a variable to the fragment shader, it is not doing any drawing. The fragment shader is doing the drawing.

    OpenGL is a tool to manipulate different stages of the rendering process on modern graphics cards. It does not try to cover the use case of blitting pixels to the screen buffer. (glDrawPixels was deprecated and is not available in ES 2.0 or WebGL)

    However there are ways that you could use it in your application.

    I recommend these two articles to understand the prerequisites, although you should be aware it is intended for openGL 3.2 and C++, not WebGL and Javascript. So you can ignore things such as context creation, the way in which textures are loaded and you don't have to create VertexArrays.

    WebGL solution 1:

    WebGL solution 2:

    See modified source

    This solution is not modifying 1 exact pixel, I think Solution 1 is a better way to do it

    Why you should use Canvas2D:

    It is a mistake to consider to Canvas2D is inferior to WebGL, One is a screwdriver and the other is hammer. One is great for attaching things with screws the other is great for attaching things with Nails.

    Use WebGL when you want to manipulate a 3d render pipeline, use Canvas2D when you want to manipulate raster images.

    TL;DR:

    If you use Canvas2D you can start making the application you want to today with good performance. If you want to use WebGL, you should make an effort to understand the stages of the render pipeline.