如何在3D WebGL中渲染三角带

时间:2019-05-29 08:26:01

标签: javascript webgl

我正在努力在WebGL 3D中渲染2D三角带。

我的飞机渲染得很好,但是我的三角带没有显示在屏幕上。

我认为这可能与我的相机查看场景的方式或我如何渲染地带有关。

我尝试了一个普通的三角形,一个具有不同顶点的条带等,但屏幕上似乎没有任何显示。

“三角形”在“运行”功能的结尾处显示在第273+行上。

谢谢。

"use strict";

// Shader code

// 3) Add a_colour attribute to the vertex shader
//    Add v_colour varying to pass colours to fragments

const vertexShaderSource = `
attribute vec4 a_position;
attribute vec3 a_colour;

uniform mat4 u_worldMatrix;
uniform mat4 u_viewMatrix;
uniform mat4 u_projectionMatrix;

varying vec3 v_colour;

void main() {
    // send colour to fragment shader (interpolated)
    v_colour = a_colour;
    gl_Position = u_projectionMatrix *u_viewMatrix * u_worldMatrix * a_position;
}
`;

// 3c) Set fragment colour to interpolated v_colour

const fragmentShaderSource = `
precision mediump float;
varying vec3 v_colour;

void main() {
    // set colour
    gl_FragColor = vec4(v_colour, 1); 
}
`;

// Vertex shader for everything that doesn't move + Speedometer

var VertexSource =
'attribute vec3 coordinates;' +
'void main(void) {' +
  ' gl_Position = vec4(coordinates, 1.0);' +
'}';

            // House fragment shader

const ShaderSource = `
precision mediump float;

void main() {
    gl_FragColor = vec4(0.3, 0.6, 1.0, 1.0);
}
`;

function createShader(gl, type, source) {
    const shader = gl.createShader(type);
    gl.shaderSource(shader, source);
    gl.compileShader(shader);

    const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    if (!success) {
        console.error(gl.getShaderInfoLog(shader));
        gl.deleteShader(shader);
        return null;
    }
    return shader;
}

function createProgram(gl, vertexShader, fragmentShader) {
    const program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);

    const success = gl.getProgramParameter(program, gl.LINK_STATUS);
    if (!success) {
        console.error(gl.getProgramInfoLog(program));
        gl.deleteProgram(program);
        return null;
    }
    return program;
}

function resize(canvas) {
    const resolution = window.devicePixelRatio || 1.0;

    const displayWidth = Math.floor(canvas.clientWidth * resolution);
    const displayHeight = Math.floor(canvas.clientHeight * resolution);

    if (canvas.width !== displayWidth || canvas.height !== displayHeight) {
        canvas.width = canvas.clientWidth;
        canvas.height = canvas.clientHeight;
        return true;
    }
    else {
        return false;
    }    
}

function onFileSelect(e) {
    let files = e.target.files; 

    if (files.length > 0) {
        let reader = new FileReader();

        reader.onload = function(e) {
            let level = JSON.parse(e.target.result);
            run(level);
        };
        
        reader.readAsText(files[0]);
    }
}

function run(level) {
    
    const width = level.heightmap.width;
    const depth = level.heightmap.depth;
    
    for (let x = 0; x < width; x++) {
       for (let z = 0; z < depth; z++) {
          let y = level.heightmap.height[x + z * width];
          console.log("(" + x + ", " + y + ", " + z + ")");
       }
    }

    const array = new Float32Array(level.heightmap.height)

    console.log(level.heightmap.height[52]);
    
    // YOUR CODE GOES HERE 



    // Get the canvas element & gl rendering context
    const canvas = document.getElementById("c");
    const gl = canvas.getContext("webgl");
    if (gl === null) {
        window.alert("WebGL not supported!");
        return;
    }

    // 1) Enable depth testing and back-face culling
    gl.enable(gl.DEPTH_TEST);
    gl.enable(gl.CULL_FACE);
    gl.cullFace(gl.BACK);

    const vertexShaderMesh = createShader(gl, gl.VERTEX_SHADER, VertexSource);
    const fragmentShaderMesh = createShader(gl, gl.FRAGMENT_SHADER, ShaderSource);
    const MeshProgram = createProgram(gl, vertexShaderMesh, fragmentShaderMesh);
    gl.useProgram(MeshProgram);
    
    var Vertices = [
        1, 25, 2,
        2, 25, 6,
        50, 26, 3,
        3, 6, 7,
    ]

    const positionBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(Vertices), gl.STATIC_DRAW);

    const Coordinates = gl.getAttribLocation(MeshProgram, "coordinates");

    // Compile the shaders
    const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
    const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
    const program =  createProgram(gl, vertexShader, fragmentShader);
    gl.useProgram(program);

    

    // Initialise the shader attributes & uniforms
    const shader = {
        program: program
    };

    const nAttributes = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
    for (let i = 0; i < nAttributes; i++) {
        const name = gl.getActiveAttrib(program, i).name;
        shader[name] = gl.getAttribLocation(program, name);
        gl.enableVertexAttribArray(shader[name]);
    }

    const nUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
    for (let i = 0; i < nUniforms; i++) {
        const name = gl.getActiveUniform(program, i).name;
        shader[name] = gl.getUniformLocation(program, name);
    }
    
    // Initialise the position attribute

    // Construct the objects

    let plane = new Plane(gl, 20);
    plane.scale = [3,3,3]; 


    // === Per Frame Operations

    // animation loop
    let oldTime = 0;
    let animate = function(time) {
        time = time / 1000;
        let deltaTime = time - oldTime;
        oldTime = time;

        resize(canvas);
        update(deltaTime);
        render();

        requestAnimationFrame(animate);
    };

    let cameraDist = 3;
    let cameraAngle = 0;
    let cameraHeight = 1;
    let cameraPos = [3, 1, 0];
    const cameraRotationSpeed = 2 * Math.PI / 120;
    // update objects in the scene
    let update = function(deltaTime) {
        cameraAngle += cameraRotationSpeed * deltaTime;
        cameraPos = [cameraDist * Math.cos(cameraAngle), cameraHeight, cameraDist * Math.sin(cameraAngle)];
    };

    // create the matrices once, to avoid garbage collection
    const projectionMatrix = glMatrix.mat4.create();
    const viewMatrix = glMatrix.mat4.create();

    // redraw the scene
    let render = function() {
        // clear the screen
        gl.useProgram(program);
        gl.viewport(0, 0, canvas.width, canvas.height);        
        gl.clearColor(0, 0, 0, 1);
        gl.clear(gl.COLOR_BUFFER_BIT);

        // 4) clear the depth buffer
        gl.clear(gl.DEPTH_BUFFER_BIT);

        // calculate the projection matrix
        {
            const aspect = canvas.width / canvas.height;
            const fovy = glMatrix.glMatrix.toRadian(60);
            const near = 0.1;
            const far = 10;

            glMatrix.mat4.perspective(projectionMatrix, fovy, aspect, near, far);
            gl.uniformMatrix4fv(shader["u_projectionMatrix"], false, projectionMatrix);
        }
        
        // calculate the view matrix
        {
            const eye = cameraPos;
            const center = plane.position;
            const up = [0, 1, 0];

            glMatrix.mat4.lookAt(viewMatrix, eye, center, up);
            gl.uniformMatrix4fv(shader["u_viewMatrix"], false, viewMatrix);
        }

        const size = 2;          // 2 components per iteration
        const type = gl.FLOAT;   // the data is 32bit floats
        const normalize = false; // don't normalize the data
        const stride = 0;        // 0 = move forward size * sizeof(type) each iteration to get the next position
        const offset = 0;        // start at the beginning of the buffer

        // render the plane
        plane.render(gl, shader);

        {
        gl.useProgram(MeshProgram);
            
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
            gl.vertexAttribPointer(Coordinates, size, type, normalize, stride, offset);
            gl.enableVertexAttribArray(Coordinates);
            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 3);
           
        }
        
    };
    
    // start it going
    animate(0);
}    

/**
 * Load the selected level file and run it.
 * @param {*} e 
 */

function main() {

    // === Initialisation ===

    // Check for the various File API support.
    if (window.File && window.FileReader && window.FileList && window.Blob) {
        document.getElementById('files').addEventListener('change', onFileSelect, false);
    } else {
        alert('The File APIs are not fully supported in this browser.');
        return;
    }

    

}

0 个答案:

没有答案