slaviboy
slaviboy

Reputation: 1922

WebGL wrong drawing order for the OpenGL shapes

I wanted to test something using WebGL(OpenGL for the browser) and I wrote simple js code that is drawing LINES and POINTS. So I have the function draw() that is drawing multiple shapes, first it draws multiple Lines and after that multiple Circles(represented as squares). But it so happens that the lines are drawn above the circles, as if the drawing order is inverted. Any idea why??

drawShapes(gl.LINES, { r: 1.0, g: 0.0, b: 0.0, a: 1.0 })
drawShapes(gl.POINTS, { r: 0.0, g: 1.0, b: 0.0, a: 1.0 })

enter image description here

Below is the full source code

let canvas = document.getElementById('canvas');
        let gl = canvas.getContext('webgl');

        let vertices = [
            -0.7, -0.1, 0,
            -0.3, 0.6, 0,
            -0.3, -0.3, 0,
            0.2, 0.6, 0,
            0.3, -0.3, 0,
            0.7, 0.6, 0
        ]

        function drawShapes(shape, color) {

            // Create an empty buffer object
            let vertex_buffer = gl.createBuffer()
            gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer)
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)
            gl.bindBuffer(gl.ARRAY_BUFFER, null)

            // Vertex shader source code
            let vertCode = `
            attribute vec3 coordinates;
            void main(void) {
                gl_Position = vec4(coordinates, 1.0);
                gl_PointSize = 10.0;
            }`

            // Create a vertex shader object
            let vertShader = gl.createShader(gl.VERTEX_SHADER)
            gl.shaderSource(vertShader, vertCode)
            gl.compileShader(vertShader)
            let fragCode = `
            void main(void) { 
                gl_FragColor = vec4(${color.r}, ${color.g}, ${color.b}, ${color.a});
            }`

            let fragShader = gl.createShader(gl.FRAGMENT_SHADER)
            gl.shaderSource(fragShader, fragCode)
            gl.compileShader(fragShader)

            let shaderProgram = gl.createProgram()
            gl.attachShader(shaderProgram, vertShader)
            gl.attachShader(shaderProgram, fragShader)

            gl.linkProgram(shaderProgram)
            gl.useProgram(shaderProgram)
            gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer)

            // Get the attribute location
            let coord = gl.getAttribLocation(shaderProgram, "coordinates")
            gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0)
            gl.enableVertexAttribArray(coord)


            gl.enable(gl.DEPTH_TEST)
            gl.viewport(0, 0, canvas.width, canvas.height)
            gl.drawArrays(shape, 0, 6)
        }

        function draw(shape, color) {

            // change background color
            gl.clearColor(0, 0, 0, 0.7)
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

            drawShapes(gl.LINES, { r: 1.0, g: 0.0, b: 0.0, a: 1.0 })
            drawShapes(gl.POINTS, { r: 0.0, g: 1.0, b: 0.0, a: 1.0 })
        }
        draw()
<!doctype html>
<html>

<body>
    <canvas width="500" height="500" id="canvas"></canvas>
</body>

</html>

Upvotes: 0

Views: 398

Answers (1)

robthebloke
robthebloke

Reputation: 9668

You have the depth test enabled. since the lines are drawn first, they enter the depth buffer first. When drawing the points in the same location, the depth test is preventing the pixels from being drawn on top of the lines.

            gl.enable(gl.DEPTH_TEST)

Either a) draw the lines after the points. b) set the depth func to GL_LEQUAL

Upvotes: 1

Related Questions