Square不会出现使用透视矩阵

时间:2013-06-27 14:06:56

标签: javascript webgl

我开始使用 WebGL 时遇到问题。我不明白为什么,但它不起作用的原因是透视矩阵。

因此,代码不能与透视矩阵一起使用:

<script type="x-shader/x-fragment" id="shader-fs">
    void main (void) {
        gl_FragColor = vec4(1,1,1,1);
    }
</script>
<script type="x-shader/x-vertex" id="shader-vs">
    attribute vec3 aVertexPosition;

    uniform mat4 pMatrix;
    uniform mat4 mvMatrix;

    void main(void) {
        gl_Position = pMatrix * mvMatrix * vec4(aVertexPosition, 1.0);
    }
</script>
<script type="text/javascript">
    function makePerspective(fovy, aspect, znear, zfar) {
        var ymax = znear * Math.tan(fovy * Math.PI / 360.0);
        var ymin = -ymax;
        var xmin = ymin * aspect;
        var xmax = ymax * aspect;

        return makeFrustum(xmin, xmax, ymin, ymax, znear, zfar);
    }

    function makeFrustum(left, right,
                         bottom, top,
                         znear, zfar) {
        var X = 2*znear/(right-left);
        var Y = 2*znear/(top-bottom);
        var A = (right+left)/(right-left);
        var B = (top+bottom)/(top-bottom);
        var C = -(zfar+znear)/(zfar-znear);
        var D = -2*zfar*znear/(zfar-znear);

        return [X, 0, A, 0,
                0, Y, B, 0,
                0, 0, C, D,
                0, 0, -1, 0];
    }

    function identity() {
        return [
            1,0,0,0,
            0,1,0,0,
            0,0,1,0,
            0,0,0,1
        ];
    }

    var canvas, gl;
    var win = {w: 0,h: 0};
    var shaderProgram, vertexPositionAttribute;
    var horizAspect = 480/640;
    var squareVerticesBuffer;

    function getShader(gl, id) {
        var shaderScript = document.getElementById(id);

        if (!shaderScript) {
            return null;
        }

        theSource = "";
        currentChild = shaderScript.firstChild;

        while (currentChild) {
            if (currentChild.nodeType == currentChild.TEXT_NODE) {
                theSource += currentChild.textContent;
            }

            currentChild = currentChild.nextSibling;
        }

        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,theSource);
        gl.compileShader(shader);

        if (!gl.getShaderParameter(shader,gl.COMPILE_STATUS)) {
            alert("An error compiling the shader "+gl.getShaderInfoLog(shader));
            return null;
        }

        return shader;
    }
    function initShaders() {
        var fragmentShader = getShader(gl,"shader-fs");
        var vertexShader = getShader(gl,"shader-vs");

        shaderProgram = gl.createProgram();
        gl.attachShader(shaderProgram,fragmentShader);
        gl.attachShader(shaderProgram,vertexShader);
        gl.linkProgram(shaderProgram);

        if (!gl.getProgramParameter(shaderProgram,gl.LINK_STATUS)) {
            alert("Cannot init shaders!");
        }

        gl.useProgram(shaderProgram);

        vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
        gl.enableVertexAttribArray(vertexPositionAttribute);
    }
    function initBuffers() {
        squareVerticesBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);

        var vertices = [
            1,1,0,
            -1,1,0,
            1,-1,0,
            -1,-1,0,
        ];

        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices),gl.STATIC_DRAW);
    }
    function drawScene() {
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesBuffer);
        gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);

        var perspectiveMatrix = makePerspective(45,640/480,0.1,100); 
        /* if you set up the line above ^ to: [
                1,0,0,0,
                0,1,0,0,
                0,0,1,0,
                0,0,0,1
            ] it will work
        */
        var pUniform = gl.getUniformLocation(shaderProgram, "pMatrix");
        gl.uniformMatrix4fv(pUniform, false, new Float32Array(perspectiveMatrix));

        var mvMatrix = identity();

        var mvUniform = gl.getUniformLocation(shaderProgram, "mvMatrix");
        gl.uniformMatrix4fv(mvUniform, false, new Float32Array(mvMatrix));

        gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
    }

    function load() {
        canvas = document.getElementById("c");
        gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
        win.w = canvas.width; win.h = canvas.height;

        if (gl) { // Ok!
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            gl.enable(gl.DEPTH_TEST);
            gl.depthFunc(gl.LEQUAL);
            gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);

            initShaders();
            initBuffers();

            drawScene();
        }
        else { // Fallback to 2d!
            gl = canvas.getContext("2d");

            gl.font = "14px Arial";
            gl.textAlign = "center";
            gl.textBaseline = "bottom";
            gl.fillStyle = "#000";

            gl.fillText("You're browser doesn't support WebGL!",win.w/2,win.h/2);
        }
    }

    window.onload = load;
</script>

我从此example获取了代码。但我不想使用SylvesterglMatrix

1 个答案:

答案 0 :(得分:1)

我找到了解决问题的方法!我错了创建矩阵数组的想法,接下来4个元素是列而不是行。所以翻译矩阵是:

var arr = [
    1,0,0,0,
    0,1,0,0,
    0,0,1,0,
    vx,vy,vz,1,
];

不喜欢这样:

var arr = [
    1,0,0,vx,
    0,1,0,vy,
    0,0,1,vz,
    0,0,0,1,
];