dimanche 28 octobre 2018

WebGL 2.0 Questions - about rotation and transformation

I still have some things I do not understand as I study WebGL. While studying at WebGL Fundamentals site, I looked at the contents of Translation and looked at Rotation. But what do you do not know that the figure moves according to the keyboard input but does not move at the same time as it rotates diagonally? Do I have to look at the Matrix?

// Vertex shader.
var _vertexShader = `
    attribute vec2 _position;
    uniform vec2 _translation;
    uniform vec2 _rotation;
    void main() {
        // Rotate the position.
        vec2 _rotatedPosition = vec2(_position.x * _rotation.y + _position.y * _rotation.x,
            _position.y * _rotation.y - _position.x * _rotation.x);
        gl_Position = vec4(_translation + _rotatedPosition, 0, 1);
    }
`

// Fragment shader.
var _fragmentShader = `
    precision mediump float;
    uniform vec4 _color;
    void main() {
        gl_FragColor = _color;
    }
`

// Create shader
function createShader(gl, type, source) {
    var shader = gl.createShader(type)
    gl.shaderSource(shader, source)
    gl.compileShader(shader)
    var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS)
    if (success) {
        return shader
    } else {
        console.log(gl.getShaderInfoLog(shader))
        gl.deleteShader(shader)
        // return false
    }
}

// Linking shader by program
function createProgram(gl, vertexShader, fragmentShader) {
    var program = gl.createProgram()
    gl.attachShader(program, vertexShader)
    gl.attachShader(program, fragmentShader)
    gl.linkProgram(program)
    var success = gl.getProgramParameter(program, gl.LINK_STATUS)
    if (success) {
        return program
    } else {
        console.log(gl.getProgramInfoLog(program))
        gl.deleteProgram(program)
        // return false
    }
}

function main() {
    // Get a WebGL context.
    var canvas = document.getElementById('canvas')
    var gl = canvas.getContext('webgl2')
    if (!gl) {
        alert('Not support WebGL.')
        return false
    }

    // Get the strings for our GLSL shaders.
    var vertexShader = createShader(gl, gl.VERTEX_SHADER, _vertexShader)
    var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, _fragmentShader)
    // Link the two shaders into a program.
    var program = createProgram(gl, vertexShader, fragmentShader)
    // Look up where the vertex data need to go.
    var positionLoc = gl.getAttribLocation(program, '_position')
    // Look up uniform locations.
    var uniformColorPositionLoc = gl.getUniformLocation(program, '_color')
    var uniformTranslationPositionLoc = gl.getUniformLocation(program, '_translation')
    var uniformLocationPositionLoc = gl.getUniformLocation(program, '_rotation')
    var body_positions = new Float32Array([
        // Body triangle (Left)
        -0.25,  0,
        0.25,  0,
        0, 0.35,
        // Body square
        -0.1, 0,
        0.1, 0,
        0.1, -0.25,
        // Body square
        -0.1, 0,
        -0.1, -0.25,
        0.1, -0.25,
    ])

    var roter_positions = new Float32Array([
        0, 0,
        0.3, 0,
        0, -0.1,

        0, 0,
        0, 0.1,
        -0.3, 0,
    ])

    // Create a buffer and put the three 2d clip space points in it.
    var body_positionBuf = gl.createBuffer()
    // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = body_positionBuf).
    gl.bindBuffer(gl.ARRAY_BUFFER, body_positionBuf)
    gl.bufferData(gl.ARRAY_BUFFER, body_positions, gl.STATIC_DRAW)
    
    // Create a buffer and put the three 2d clip space points in it.
    var roter_positionBuf = gl.createBuffer()
    // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = roter_positionBuf).
    gl.bindBuffer(gl.ARRAY_BUFFER, roter_positionBuf)
    gl.bufferData(gl.ARRAY_BUFFER, roter_positions, gl.STATIC_DRAW)
    
    // Translation variable
    var translation = [0, 0]
    // Rotation variable
    var rotation = [0, 1]
    // Angle variable for rotation
    var angle = 0

    // Code above this line is initialization code.
    // Code below this line is rendering code.

    drawScene()

    function drawScene() {
        // webglUtils.resizeCanvasToDisplaySize(gl.canvas)
        // Tell WebGL how to convert from clip space to pixels.
        gl.viewport(0, 0, gl.canvas.width, gl.canvas.height)

        // Clear the canvas.
        gl.clearColor(0, 0, 0, 0)
        gl.clear(gl.COLOR_BUFFER_BIT)
        
        // Tell it to use our program (pair of shaders).
        gl.useProgram(program)
        // Turn on the attribute.
        gl.enableVertexAttribArray(positionLoc)
        // Set random color for body shape.
        gl.uniform4f(uniformColorPositionLoc, Math.random(), Math.random(), Math.random(), 1)
        // Bind the position buffer.
        gl.bindBuffer(gl.ARRAY_BUFFER, body_positionBuf)
        gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0)
        // Set the Translation.
        gl.uniform2fv(uniformTranslationPositionLoc, translation)
        // Set the Rotation.
        gl.uniform2fv(uniformLocationPositionLoc, rotation)
        // Draw.
        gl.drawArrays(gl.TRIANGLES, 0, body_positions.length / 2)

        roterDraw()

        function roterDraw() {
            // Set random color for roter shape.
            gl.uniform4f(uniformColorPositionLoc, Math.random(), Math.random(), Math.random(), 1)
            // Bind the position buffer.
            gl.bindBuffer(gl.ARRAY_BUFFER, roter_positionBuf)
            gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0)
            // Set the Translation.
            gl.uniform2fv(uniformTranslationPositionLoc, translation)
            // Set the Rotation.
            gl.uniform2fv(uniformLocationPositionLoc, rotation)
            // Draw.
            gl.drawArrays(gl.TRIANGLES, 0, roter_positions.length / 2)
        }
        // var size = 2
        // var type = gl.FLOAT
        // var normalize = false
        // var stride = 0
        // var offset = 0 
    }

    // Event listener
    window.addEventListener('keypress', checkKeyPressed, false)

    function checkKeyPressed(event) {
        if (event.charCode == '119') {
            translation[0] = 0
            translation[1] += 0.05
            console.log('Translation X: ' + translation[0].toFixed(2) + ' Translation Y: ' + translation[1].toFixed(2))
            document.getElementById('yAxis').innerText = translation[1].toFixed(2)
            drawScene()
        }
        if (event.charCode == '115') {
            translation[0] = 0
            translation[1] -= 0.05
            console.log('Translation X: ' + translation[0].toFixed(2) + ' Translation Y: ' + translation[1].toFixed(2))
            document.getElementById('yAxis').innerText = translation[1].toFixed(2)
            drawScene()
        }
        if (event.charCode == '97') {
            angle -= 10
            var angleInRadians = angle * Math.PI / 180.0
            rotation[0] = Math.sin(angleInRadians)
            rotation[1] = Math.cos(angleInRadians)
            drawScene()
        }
        if (event.charCode == '100') {
            angle += 10
            var angleInRadians = angle * Math.PI / 180.0
            rotation[0] = Math.sin(angleInRadians)
            rotation[1] = Math.cos(angleInRadians)
            drawScene()
        }
    }
}

I would really appreciate it if you could give me a simple sample code to help you understand. For reference, there is a propeller made of two triangles as shown in the figure below. What happens when requestAnimationFrame () does not auto-rotate normally?

Reference image

I'm sorry to ask you a question that might seem too theoretical and easy. But I really want to learn, but it is too hard to understand.




Aucun commentaire:

Enregistrer un commentaire