Adnan Shahid
Adnan Shahid

Reputation: 53

Draw Multiple Shapes in WebGL

I am facing the same issue of creating multiple objects ( One rotating and One static). I want to draw a static rectangle in the following code (The rotating rectangle code is from Edward Angels WebGL examples). I try to follow the instructions that gman has said from the link Drawing many shapes in WebGL, but still not able to solve. It would be nice to get some help on this to create another static object such as rectangle along with this rotating rectangle in the code. Thanks.

    <script id="vertex-shader" type="x-shader/x-vertex">
    attribute vec4 vPosition;
    uniform float theta;

    void
    main()
    {
        float s = sin( theta );
        float c = cos( theta );

        gl_Position.x = -s * vPosition.x + c * vPosition.y;
        gl_Position.y =  s * vPosition.y + c * vPosition.x;
        gl_Position.z = 0.0;
        gl_Position.w = 1.0;
    }
    </script>

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

    precision mediump float;

    void
    main()
    {
        gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
    }
    </script>



    var canvas;
    var gl;

    var theta = 0.0;
    var thetaLoc;

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

        gl = WebGLUtils.setupWebGL( canvas );
        if ( !gl ) { alert( "WebGL isn't available" ); }

        gl.viewport( 0, 0, canvas.width, canvas.height );
        gl.clearColor( 1.0, 1.0, 1.0, 1.0 );

        var program = initShaders( gl, "vertex-shader", "fragment-shader" );
        gl.useProgram( program );

        var vertices = [
            vec2(  0,  1 ),
            vec2(  1,  0 ),
            vec2( -1,  0 ),
            vec2(  0, -1 )
        ];

        var bufferId = gl.createBuffer();
        gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );
        gl.bufferData( gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW );

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

        thetaLoc = gl.getUniformLocation( program, "theta" );

        render();
    };


    function render() {

        gl.clear( gl.COLOR_BUFFER_BIT );

        theta += 0.1;
        gl.uniform1f( thetaLoc, theta );

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

        window.requestAnimFrame(render);
    }

Upvotes: 1

Views: 7480

Answers (2)

Adnan Shahid
Adnan Shahid

Reputation: 53

Here is what my solution...

SHADER CODE:

    <script id="vertex-shader" type="x-shader/x-vertex">
    attribute vec4 vPosition;
    uniform float theta;

    void
    main()
    {
        float s = sin( theta );
        float c = cos( theta );

        gl_Position.x = -s * vPosition.x + c * vPosition.y;
        gl_Position.y =  s * vPosition.y + c * vPosition.x;
        gl_Position.z = 0.0;
        gl_Position.w = 1.0;
    }
    </script>

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

    precision mediump float;

    void
    main()
    {
        gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
    }
    </script>

JAVASCRIPT CODE:

    var canvas;
    var gl;

    var theta = 0.0;
    var thetaLoc;

    var program;
    var program1;


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

        gl = WebGLUtils.setupWebGL( canvas );
        if ( !gl ) { alert( "WebGL isn't available" ); }

        //
        //  Configure WebGL
        //
        gl.viewport( 0, 0, canvas.width, canvas.height );
        gl.clearColor( 1.0, 1.0, 1.0, 1.0 );

        //  Load shaders and initialize attribute buffers
        program = initShaders( gl, "vertex-shader", "fragment-shader" );
        program1 = initShaders( gl, "vertex-shader", "fragment-shader" );


        //Rotating Rectangle
        var rr_vertices = [
            vec2( 0,  0.25),
            vec2( 0.25,  0),
            vec2(-0.25,  0 ),
            vec2( 0, -0.25)
        ];
        // Load the data into the GPU
        rr_bufferId = gl.createBuffer();
        gl.bindBuffer( gl.ARRAY_BUFFER, rr_bufferId );
        gl.bufferData( gl.ARRAY_BUFFER, flatten(rr_vertices), gl.STATIC_DRAW );
        // Associate out shader variables with our data buffer
        rr_vPosition = gl.getAttribLocation( program, "vPosition" );
        gl.vertexAttribPointer( rr_vPosition, 2, gl.FLOAT, false, 0, 0 );

        //Static Rectangle
        var sr_vertices = [
            vec2( 0.5,  0.5),
            vec2( 1.0,  0.5),
            vec2( 0.5,  1.0 ),
            vec2( 1.0,  1.0)
        ];
        // Load the data into the GPU
        sr_bufferId = gl.createBuffer();
        gl.bindBuffer( gl.ARRAY_BUFFER, sr_bufferId );
        gl.bufferData( gl.ARRAY_BUFFER, flatten(sr_vertices), gl.STATIC_DRAW );
        // Associate out shader variables with our data buffer
        sr_vPosition = gl.getAttribLocation( program, "vPosition" );



        render();
    };

    var rr_vPosition;
    var sr_vPosition;
    var rr_bufferId;
    var sr_bufferId;

    function render() {

        gl.clear( gl.COLOR_BUFFER_BIT );

        gl.useProgram( program1 );
        gl.enableVertexAttribArray( sr_vPosition );
        gl.bindBuffer( gl.ARRAY_BUFFER, sr_bufferId );
        gl.vertexAttribPointer( sr_vPosition, 2, gl.FLOAT, false, 0, 0 );
        gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 );

        gl.useProgram( program );
        thetaLoc = gl.getUniformLocation( program, "theta" );

        gl.enableVertexAttribArray( rr_vPosition );
        gl.bindBuffer( gl.ARRAY_BUFFER, rr_bufferId );
        gl.vertexAttribPointer( rr_vPosition, 2, gl.FLOAT, false, 0, 0 );
        theta += 0.1;
        gl.uniform1f( thetaLoc, theta );
        gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 );




        window.requestAnimFrame(render);
    }

Upvotes: 1

Bizera
Bizera

Reputation: 11

So, were you define your vertices for the rectangle, simply add on more vertices to create an additional rectangle at a different point on the canvas. This one you only need to draw once, so if you have say:

var render = function(){
    //Insert rest of code
    if(!not_First_Time)
    {
        gl.drawArrays(gl.TRIANGLE_STRIP , 4 , 8 );
    }
    gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 );
    //Insert rest of code

But that's more or less the cheating way of doing it as you're still modifying the points to rotate, and if you ever re-drew them, they would rotate as the main square did.

I also notice you stripped out a few of the include commands from the HTML code. You're going to need those.

Upvotes: 1

Related Questions