调用HTML5画布例程的函数不会按预期退出

时间:2014-03-14 21:23:56

标签: javascript html5-canvas webgl

我在Javascript编码中遇到了一个不为人知的异常:我完全不知道为什么,但有一些编译器不会返回的函数,它只是“坐”那里,即使在'}'括号有下一行代码。

请看下面的示例 - 我有一个main函数,它包含一个接一个地调用initShaders(),initBuffers()或drawScene()等函数。麻烦的initShaders()内部看起来像这样:

<!DOCTYPE html>
<html>
    <canvas id = 'c' width = '500' height = '500'></canvas>
    <script src ='js/webgl-utils.js'></script>
    <script src ='js/webgl-debug.js'></script>

<!-- MAIN WEBGL SCRIPT -->
    <script>
        var gl;
        var offset;
        function initWebGL() {
            // Create space and try to create context for WebGL
            var c = document.getElementById('c');
            gl = null;
            gl = c.getContext('experimental-webgl');

            // Check if browser supports WebGL
            if (!gl) {
                alert("Unable to initialize WebGL. Your browser may not support it.");
            }
            // Continue only if WebGL is available and working
            else {
                // Javascript console debug tool
                gl = WebGLDebugUtils.makeDebugContext(gl, throwOnGLError, logAndValidate);

                offset = [1, 1];
                // Choose background color
                gl.clearColor(0, 0, 0, 1);

                initShaders();

                initBuffers();

                drawScene();
            }
        }

        var program;
        function initShaders() {
            program = gl.createProgram();

            // Call this function when loadProgram function will load shaders
            function initProgram(loadedProgram) {
                program = loadedProgram;
                gl.useProgram(program);

                /*-- Specify ATTRIBUTES locations --*/
                // Specify locations of variables passed to shader program
                program.vertexPosAttrib = gl.getAttribLocation(program, 'aVertexPosition');
                // Enable this attribute as an array
                gl.enableVertexAttribArray(program.vertexPosAttrib);
                program.offsetUniform = gl.getUniformLocation(program, 'uOffset');

                // Set the format of an in-data
                gl.vertexAttribPointer(program.vertexPosAttrib, vertexPosBuffer.itemSize, gl.FLOAT, false, 0 ,0);

                /*-- Specify UNIFORMS locations --*/

                // TODO exit this function...
            };

            // Load the shaders from the file
            loadProgram('shaders/vshader-00.txt', 'shaders/fshader-00.txt', program, initProgram);  
        }

        var vertexPosBuffer;
        function initBuffers() {
            vertexPosBuffer = generateQuad();
        }

        function drawScene() {
            // Clear the scene before rendering
            gl.clear(gl.COLOR_BUFFER_BIT);

            /*-- Pass UNIFORMS to shader program --*/
            gl.uniform2f(program.offsetUniform, offset[0], offset[1]);

            // Draw some triangles with predefined amount of vertices
            gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertexPosBuffer.numItems);  
        }

        initWebGL();

    </script>
</html>

事情是在命令'gl.vertexAttribPointer(...)之后它什么都不做,而它应该退出这个函数,继续执行loadProgram函数并继续运行。如果我在loadProgram()的末尾放置initBuffers()然后在innitBuffers()中调用drawScene(),它工作正常。但这只是不切实际的。这个问题的原因是什么?

编辑:PS程序变量已在全球范围内声明。

EDIT2:粘贴主文件中的整个代码,以便更清晰。

1 个答案:

答案 0 :(得分:0)

在JavaScript中,大多数内容都是非阻塞的。 loadProgram电话会立即返回。但到那时程序尚未加载。加载后,将调用回调initProgram

JavaScript是事件驱动的,因此控制流程可能更难以遵循。

如果这是在浏览器中运行,你可能想在initProgram结束时启动一个计时器,然后再调用你的主程序&#39;触发时的功能。这个机制有点类似于loadProgram在加载程序时调用initShaders所发生的情况。