Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is really part of brainjam's answer, but just in case that jsfiddle were to go away, I wanted to make sure the code was archived. Here is the primary bit:</p> <pre><code> function handleMouseUp(event) { var world1 = [0,0,0,0] ; var world2 = [0,0,0,0] ; var dir = [0,0,0] ; var w = event.srcElement.clientWidth ; var h = event.srcElement.clientHeight ; // calculate x,y clip space coordinates var x = (event.offsetX-w/2)/(w/2) ; var y = -(event.offsetY-h/2)/(h/2) ; mat4.inverse(pvMatrix, pvMatrixInverse) ; // convert clip space coordinates into world space mat4.multiplyVec4(pvMatrixInverse, [x,y,-1,1], world1) ; vec3.scale(world1,1/world1[3]) ; mat4.multiplyVec4(pvMatrixInverse, [x,y,0,1], world2) ; vec3.scale(world2,1/world2[3]) ; // calculate world space view vector vec3.subtract(world2,world1,dir) ; vec3.normalize(dir) ; vec3.scale(dir,0.3) ; // move eye in direction of world space view vector vec3.subtract(eye,dir) ; drawScene(); console.log(event) } </code></pre> <p>And the entirety of the JS...</p> <pre><code> var gl; function initGL(canvas) { try { gl = canvas.getContext("experimental-webgl"); gl.viewportWidth = canvas.width; gl.viewportHeight = canvas.height; } catch (e) { } if (!gl) { alert("Could not initialise WebGL, sorry :-("); } } function getShader(gl, id) { var shaderScript = document.getElementById(id); if (!shaderScript) { return null; } var str = ""; var k = shaderScript.firstChild; while (k) { if (k.nodeType == 3) { str += k.textContent; } k = k.nextSibling; } var shader; if (shaderScript.type == "x-shader/x-fragment") { shader = gl.createShader(gl.FRAGMENT_SHADER); } else if (shaderScript.type == "x-shader/x-vertex") { shader = gl.createShader(gl.VERTEX_SHADER); } else { return null; } gl.shaderSource(shader, str); gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { alert(gl.getShaderInfoLog(shader)); return null; } return shader; } var shaderProgram; function initShaders() { var fragmentShader = getShader(gl, "shader-fs"); var vertexShader = getShader(gl, "shader-vs"); shaderProgram = gl.createProgram(); gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, fragmentShader); gl.linkProgram(shaderProgram); if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Could not initialise shaders"); } gl.useProgram(shaderProgram); shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute); shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); } var mvMatrix = mat4.create(); var pMatrix = mat4.create(); function setMatrixUniforms() { gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix); gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix); } var triangleVertexPositionBuffer; var squareVertexPositionBuffer; function initBuffers() { triangleVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer); var vertices = [ 0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0 ]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); triangleVertexPositionBuffer.itemSize = 3; triangleVertexPositionBuffer.numItems = 3; squareVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); vertices = [ 1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0 ]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); squareVertexPositionBuffer.itemSize = 3; squareVertexPositionBuffer.numItems = 4; } var eye = vec3.create([0,0,0]) ; // negation of actual eye position var pvMatrix = mat4.create(); var pvMatrixInverse = mat4.create(); function drawScene() { gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix); mat4.identity(mvMatrix); // calculate the view transform mvMatrix, and the projection-view matrix pvMatrix mat4.translate(mvMatrix, eye); mat4.multiply(pMatrix,mvMatrix,pvMatrix) ; mat4.translate(mvMatrix, [-1.5, 0.0, -7.0]); gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer); gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); setMatrixUniforms(); gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems); mat4.translate(mvMatrix, [3.0, 0.0, 0.0]); gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer); gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); setMatrixUniforms(); gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems); } function handleMouseUp(event) { var world1 = [0,0,0,0] ; var world2 = [0,0,0,0] ; var dir = [0,0,0] ; var w = event.srcElement.clientWidth ; var h = event.srcElement.clientHeight ; // calculate x,y clip space coordinates var x = (event.offsetX-w/2)/(w/2) ; var y = -(event.offsetY-h/2)/(h/2) ; mat4.inverse(pvMatrix, pvMatrixInverse) ; // convert clip space coordinates into world space mat4.multiplyVec4(pvMatrixInverse, [x,y,-1,1], world1) ; vec3.scale(world1,1/world1[3]) ; mat4.multiplyVec4(pvMatrixInverse, [x,y,0,1], world2) ; vec3.scale(world2,1/world2[3]) ; // calculate world space view vector vec3.subtract(world2,world1,dir) ; vec3.normalize(dir) ; vec3.scale(dir,0.3) ; // move eye in direction of world space view vector vec3.subtract(eye,dir) ; drawScene(); console.log(event) } function webGLStart() { var canvas = document.getElementById("lesson01-canvas"); initGL(canvas); initShaders(); initBuffers(); gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.enable(gl.DEPTH_TEST); canvas.onmouseup = handleMouseUp; drawScene(); } webGLStart(); </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload