WebGL - рисовать несколько вращающихся 3D-объектов - PullRequest
0 голосов
/ 28 сентября 2019

Я пытаюсь отобразить 2 вращающихся объекта на одном полотне webGL, оба они вращаются по 3 осям (x, y, z).Это работает, когда я пытаюсь распечатать только куб, но я не могу использовать вторую программу для отображения тетраэдра.

JS файл:

"use strict"; 

var canvas;
var gl;

var CubeNumVertices = 36;
var CubePoints = [];

var TetrPoints = [];
var colorsT = [];

var colors = [];
var xAxis = 0;
var yAxis = 1;
var zAxis = 2;

var axis = 0;
var theta = [0, 0, 0];

var thetaLoc;


    var program;
    var program1;

window.onload = function init() {    
    canvas = document.getElementById( "gl-canvas" ); // getting the canvas element

    gl = WebGLUtils.setupWebGL( canvas ); // setting up webgl with the canvas
    if ( !gl ) { alert( "WebGL isn't available" ); }

    colorCube();
    colorTetra();


    // the size of the viewport
    gl.viewport( 0, 0, canvas.width, canvas.height );
    // the color of background!
    gl.clearColor( 0.0, 0.0, 0.0, 1.0 );
    gl.enable(gl.DEPTH_TEST)

    // CUBE!!!!!!!!!!!!!!!!!!!!!!!!!!!
    var CubeProgram = initShaders( gl, "vertex-shader", "fragment-shader" ); // initializing shaders
    gl.useProgram(CubeProgram);
    /// SENDING THE DATA TO OUR SHADER!!!!!!!!
    var cBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );

    var vColor = gl.getAttribLocation( CubeProgram, "vColor" );
    gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vColor );

    var vBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(CubePoints), gl.STATIC_DRAW );


    var vPosition = gl.getAttribLocation( CubeProgram, "vPosition" );
    gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vPosition );

    thetaLoc = gl.getUniformLocation(CubeProgram, "theta");
    render();


    // --------------- Tetrahedron -------------------
    var TetraProgram = initShaders( gl, "vertex-shader", "fragment-shader" ); // initializing shaders
    gl.useProgram(TetraProgram);
    var tcBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, tcBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );

    var tvColor = gl.getAttribLocation( TetraProgram, "vColor" );
    gl.vertexAttribPointer( tvColor, 3, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( tvColor );

    var tvBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, tvBuffer);
    gl.bufferData( gl.ARRAY_BUFFER, flatten(TetrPoints), gl.STATIC_DRAW );

    var tvPosition = gl.getAttribLocation( TetraProgram, "vPosition" );
    gl.vertexAttribPointer( tvPosition, 3, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( tvPosition );


    document.getElementById( "xButton" ).onclick = function () {
        axis = xAxis;
    };
    document.getElementById( "yButton" ).onclick = function () {
        axis = yAxis;
    };
    document.getElementById( "zButton" ).onclick = function () {
        axis = zAxis;
    };

};

var render = function(){
    gl.enable(gl.CULL_FACE);
    gl.enable(gl.SCISSOR_TEST);

    const {width, height} = gl.canvas;
    const leftWidth = width / 2 | 0;

    gl.viewport(0, 0, leftWidth, height);
    gl.scissor(0, 0, leftWidth, height);

    gl.clearColor(0, 0, 0, 1); 

    theta[axis] += 2.0;
    gl.uniform3fv(thetaLoc, theta);

    // Render cube
    gl.drawArrays( gl.TRIANGLES, 0, CubeNumVertices );

    gl.useProgram(TetraProgram);
    const rightWidth = width - leftWidth;
    gl.viewport(leftWidth, 0, rightWidth, height);
    gl.scissor(leftWidth, 0, rightWidth, height);
    gl.clearColor(0, 0, 1, 1);
    gl.uniform3fv(thetaLoc, theta)
    requestAnimFrame( render );

}

function colorTetra(){

    var verticesT = [
        vec3(  0.0000,  0.0000, -0.3500 ),
        vec3(  0.0000,  0.3500,  0.1500 ),
        vec3( -0.3500, -0.1500,  0.1500 ),
        vec3(  0.3500, -0.1500,  0.1500 )
    ];

    tetra(verticesT[0], verticesT[1], verticesT[2], verticesT[3]);
}

function makeTetra( a, b, c, color )
{
    // add colors and vertices for one triangle

    var baseColors = [
        vec3(0.7, 0.7, 0.9, 1.0),
        vec3(0.6, 0.8, 0.9, 1.0),
        vec3(0.5, 0.6, 0.9, 1.0),
        vec3(1.0, 1.0, 0.2, 1.0)
    ];

    colors.push( baseColors[color] );
    TetrPoints.push( a );
    colors.push( baseColors[color] );
    TetrPoints.push( b );
    colors.push( baseColors[color] );
    TetrPoints.push( c );
}

function tetra( p, q, r, s )
{
    // tetrahedron with each side using
    // a different color

    makeTetra( p, r, q, 0 );
    makeTetra( p, r, s, 1 );
    makeTetra( p, q, s, 2 );
    makeTetra( q, r, s, 3 );
}

function colorCube()
{
    quad( 1, 0, 3, 2 );
    quad( 2, 3, 7, 6 );
    quad( 3, 0, 4, 7 );
    quad( 6, 5, 1, 2 );
    quad( 4, 5, 6, 7 );
    quad( 5, 4, 0, 1 );
}

function colorPyramid()
{
    quad(0, 3, 7, 4);
}

function quad(a, b, c, d)
{
    var vertices = [
        vec4( -0.25, -0.25, -0.25, 1.0 ), //1
        vec4( -0.25, 0.25, -0.25, 1.0 ), //2
        vec4(  0.25, 0.25, -0.25, 1.0 ), //3
        vec4(  0.25, -0.25, -0.25, 1.0 ), //4
        vec4(  -0.25, -0.25, 0.25, 1.0 ), //5
        vec4( -0.25, 0.25, 0.25, 1.0 ), //6
        vec4(  0.25, 0.25, 0.25, 1.0 ), //7
        vec4(  0.25, -0.25, 0.25, 1.0 )  //8
    ];

    var vertexColors = [
        [ 0.0, 0.0, 0.0, 1.0 ],  // black
        [ 1.0, 0.0, 0.0, 1.0 ],  // red
        [ 1.0, 1.0, 0.0, 1.0 ],  // yellow
        [ 0.0, 1.0, 0.0, 1.0 ],  // green
        [ 0.0, 0.0, 1.0, 1.0 ],  // blue
        [ 1.0, 0.0, 1.0, 1.0 ],  // magenta
        [ 0.0, 1.0, 1.0, 1.0 ],  // cyan
        [ 1.0, 1.0, 1.0, 1.0 ]   // white
    ];

    // We need to parition the quad into two triangles in order for
    // WebGL to be able to render it.  In this case, we create two
    // triangles from the quad indices

    //vertex color assigned by the index of the vertex

    var indices = [ a, b, c, a, c, d ];

    for ( var i = 0; i < indices.length; ++i ) {
        CubePoints.push( vertices[indices[i]] );
        //colors.push( vertexColors[indices[i]] );

        // for solid colored faces use
        colors.push(vertexColors[a]);

    }
}

HTML-файл выглядитпримерно так:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
        <title>CG Lab0 <3</title>

        <!-- vertex shader code block -->
        <script id="vertex-shader" type="x-shader/x-vertex">

attribute  vec4 vPosition;
attribute  vec4 vColor;
varying vec4 fColor;

uniform vec3 theta;

void main()
{
    // Compute the sines and cosines of theta for each of
    //   the three axes in one computation.
    vec3 angles = radians( theta );
    vec3 c = cos( angles );
    vec3 s = sin( angles );

    // Remeber: thse matrices are column-major
    mat4 rx = mat4( 1.0,  0.0,  0.0, 0.0,
            0.0,  c.x,  s.x, 0.0,
            0.0, -s.x,  c.x, 0.0,
            0.0,  0.0,  0.0, 1.0 );

    mat4 ry = mat4( c.y, 0.0, -s.y, 0.0,
            0.0, 1.0,  0.0, 0.0,
            s.y, 0.0,  c.y, 0.0,
            0.0, 0.0,  0.0, 1.0 );


    mat4 rz = mat4( c.z, s.z, 0.0, 0.0,
            -s.z,  c.z, 0.0, 0.0,
            0.0,  0.0, 1.0, 0.0,
            0.0,  0.0, 0.0, 1.0 );

    fColor = vColor;
    gl_Position = rz * ry * rx * vPosition;
    gl_Position.z = -gl_Position.z;
}
</script>

<script id="fragment-shader" type="x-shader/x-fragment">

precision mediump float;

varying vec4 fColor;

uniform vec4 u_colorMult;

void
main()
{
    gl_FragColor = fColor;
}
</script>

        <!-- including all scripts needed -->
        <script type="text/javascript" src="../Common/webgl-utils.js"></script>
        <script type="text/javascript" src="../Common/initShaders.js"></script>
        <script type="text/javascript" src="../Common/MV.js"></script>
        <script type="text/javascript" src="webgl-triangle.js"></script>
    </head>

    <body>
        <!-- canvas element with size attributes!! -->
        <canvas id="gl-canvas" width="1024" height="512">
        Oops ... your browser doesn't support the HTML5 canvas element
        </canvas>
        <br/>

        <button id= "xButton">Rotate X</button>
        <button id= "yButton">Rotate Y</button>
        <button id= "zButton">Rotate Z</button>

    </body>
</html>

Полагаю, вы не можете запустить 2 программы с одинаковым углом тета одновременно.

Я был бы очень признателен, если бы кто-нибудь мог помочь мне решить эту проблемупроблема.

...