webgl добавление проекции не отображает объект - PullRequest
0 голосов
/ 24 марта 2012

Я смотрю на web gl и пытаюсь отобразить куб, но у меня возникает проблема, когда я пытаюсь добавить проекцию в вершинный шейдер.Я добавил атрибут, но когда я использую его для многократного просмотра модели и положения, он перестает отображать куб.Я не уверен, почему и было интересно, если кто-нибудь может помочь?Я попытался просмотреть несколько примеров, но просто не могу заставить это работать

vertex shader
    attribute vec3 aVertexPosition;

    uniform mat4 uMVMatrix;
    uniform mat4 uPMatrix;

    void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
        //gl_Position = uMVMatrix * vec4(aVertexPosition, 1.0);
    }

fragment shader
    #ifdef GL_ES
    precision highp float; // Not sure why this is required, need to google it
    #endif

    uniform vec4 uColor;

    void main() {
            gl_FragColor = uColor;
    }


    function init() {

        // Get a reference to our drawing surface
        canvas = document.getElementById("webglSurface");
        gl = canvas.getContext("experimental-webgl");

        /** Create our simple program **/
        // Get our shaders
        var v = document.getElementById("vertexShader").firstChild.nodeValue;
        var f = document.getElementById("fragmentShader").firstChild.nodeValue;

        // Compile vertex shader
        var vs = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vs, v);
        gl.compileShader(vs);

        // Compile fragment shader
        var fs = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fs, f);
        gl.compileShader(fs);

        // Create program and attach shaders
        program = gl.createProgram();
        gl.attachShader(program, vs);
        gl.attachShader(program, fs);
        gl.linkProgram(program);

        // Some debug code to check for shader compile errors and log them to console
        if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS))
            console.log(gl.getShaderInfoLog(vs));

        if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS))
                console.log(gl.getShaderInfoLog(fs));

        if (!gl.getProgramParameter(program, gl.LINK_STATUS))
                console.log(gl.getProgramInfoLog(program));


        /* Create some simple VBOs*/
        // Vertices for a cube
        var vertices = new Float32Array([
            -0.5, 0.5, 0.5, // 0
            -0.5, -0.5, 0.5, // 1
            0.5, 0.5, 0.5, // 2
            0.5, -0.5, 0.5, // 3
            -0.5, 0.5, -0.5, // 4
            -0.5, -0.5, -0.5, // 5 
            -0.5, 0.5, -0.5, // 6
            -0.5,-0.5, -0.5 // 7  
        ]);

        // Indices of the cube
        var indicies = new Int16Array([
            0, 1, 2, 1, 2, 3, // front
            5, 4, 6, 5, 6, 7, // back
            0, 1, 5, 0, 5, 4, // left
            2, 3, 6, 6, 3, 7, // right
            0, 4, 2, 4, 2, 6, // top
            5, 3, 1, 5, 3, 7 // bottom
        ]);

        // create vertices object on the GPU
        vbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

        // Create indicies object on th GPU
        ibo = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indicies, gl.STATIC_DRAW);

        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.enable(gl.DEPTH_TEST);
        // Render scene every 33 milliseconds
        setInterval(render, 33);

    }

    var mvMatrix = mat4.create();
    var pMatrix = mat4.create();

    function render() {

        // Set our viewport and clear it before we render
        gl.viewport(0, 0, canvas.width, canvas.height);
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        gl.useProgram(program);

        // Bind appropriate VBOs
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);

        // Set the color for the fragment shader
        program.uColor = gl.getUniformLocation(program, "uColor");
        gl.uniform4fv(program.uColor, [0.3, 0.3, 0.3, 1.0]);

        // 
        // code.google.com/p/glmatrix/wiki/Usage

        program.uPMatrix = gl.getUniformLocation(program, "uPMatrix");
        program.uMVMatrix = gl.getUniformLocation(program, "uMVMatrix");

        mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 1.0, 10.0, pMatrix);

        mat4.identity(mvMatrix);

        mat4.translate(mvMatrix, [0.0, -0.25, -1.0]);

        gl.uniformMatrix4fv(program.uPMatrix, false, pMatrix);
        gl.uniformMatrix4fv(program.uMVMatrix, false, mvMatrix);


        // Set the position for the vertex shader
        program.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
        gl.enableVertexAttribArray(program.aVertexPosition);

        gl.vertexAttribPointer(program.aVertexPosition, 3, gl.FLOAT, false, 3*4, 0); // position

        // Render the Object         
        gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
    }

Заранее благодарен за любую помощь

Ответы [ 2 ]

2 голосов
/ 24 марта 2012

Проблема здесь:

..., gl.viewportWidth / gl.viewportHeight, ...

И gl.viewportWidth, и gl.viewportHeight являются неопределенными значениями.

Я думаю, что вы пропустили эти две строки:

gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;

Вы увидите, что многие люди делают это:

canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;

gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;

Но учтите, что в контексте WebGL также есть два атрибута :

gl.drawingBufferWidth
gl.drawingBufferHeight
0 голосов
/ 24 марта 2012

То есть ваш куб отображается без матрицы перспективы, верно?

На первый взгляд, я думаю, что вы, возможно, обрезаете свою геометрию ближней плоскостью. Вы предоставляете ближнюю дальнюю плоскость для соответствующей функции как 1,0 и 10,0 соответственно. Это означает, что для того, чтобы любые фрагменты были видимы, они должны попадать в диапазон z [1, 10]. Ваш куб равен 1 единице на сторону, центрирован в (0, 0, 0), и вы перемещаете его «назад» из камеры на 1 единицу. Это означает, что ближайшее лицо к камере будет на самом деле при 0,5 Z, что находится вне диапазона отсечения и поэтому отбрасывается. Около половины вашего куба будет при z> 1, но вы будете смотреть на внутреннюю часть куба в этой точке. Если у вас включен обрезки задней поверхности, вы ничего не увидите.

Короче говоря - ваш куб, вероятно, слишком близко к камере. Попробуйте вместо этого:

mat4.translate(mvMatrix, [0.0, -0.25, -3.0]);

...