在Javascript / WebGL中的for循环中创建随机形状对象

时间:2017-03-02 04:31:39

标签: javascript html webgl

我目前正试图弄清楚如何创建多个随机三角形对象(大小不一),并将所有这些对象同时翻译到屏幕右侧。当他们离开屏幕时,我打算创建新的对象来替换它们。

我不确定如何正确渲染这些内容,并且不确定我缺少什么来解决这个问题。目前看起来我正在绘制某种随机多边形,并且它正在翻译屏幕。尽管对象是WERE创建的,但它肯定不会生成多个。

HTML相关代码:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
        <title>Rotating Square</title>

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

        attribute vec4 myPosition;
        uniform float theta;
        uniform vec2 mouseCoordinates;

        void main() {

            gl_PointSize=10.0;
            gl_Position.x=myPosition.x *cos(theta)+myPosition.y *sin(theta)+ mouseCoordinates.x;
            gl_Position.y=-myPosition.x *sin(theta)+myPosition.y *cos(theta)+mouseCoordinates.y;
            gl_Position.z=0.0;
            gl_Position.w=1.0;
            }

        </script>

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

            void main(){
                gl_FragColor =vec4(0.0,1.0,0.0,1.0);
                }

            </script>
            <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="project1.js"></script>          
</head>

**相关JS / WEBGL代码:**

var canvas;
var gl;
var myShaderProgram;
var theta;
var stopStartFlag;
var mouseCoordinatesUniform;
var clipX;
var clipY;
var stepX;
var stepY;
var speed;

var triangleAmount = 25;
var triangles = [];

function init() {
    theta =.0;
    speed=0.0025;
    stopStartFlag=0;
    clipX =.0;
    clipY =.0;
    stepX=1.0;
    stepY=0.0;
    randomX_X = 0.0;
    randomX_Y = 0.0;
    randomY_X = 0.0;
    randomY_Y = 0.0;
    randomZ_X = 0.0;
    randomZ_Y = 0.0;
    randomTheta = 0.0;
    randomSpeed = 0.0;


    for ( var i = 0; i < triangleAmount; i++ ){
        randomX_X = (Math.random() * 1) - 1;
        randomX_Y = (Math.random() * 1);
        randomY_X = (Math.random() * 1) - 1; // get it off the screen x-wise
        randomY_Y = (Math.random() * 1);
        randomZ_X = (Math.random() * 1) - 1;
        randomZ_Y = (Math.random() * 1);
        var triangle = new Triangle(vec2(randomX_X,randomX_Y),
                                  vec2(randomY_X,randomY_Y),
                                  vec2(randomZ_X,randomZ_Y),
                                  randomTheta,
                                  randomSpeed)
    triangles.push(triangle);
    }

    canvas = document.getElementById("gl-canvas");
    gl= WebGLUtils.setupWebGL(canvas);
    if(!gl){ alert("WebGL is not working");}

    gl.viewport(0,0,512,512);
    gl.clearColor(0.0,0.0,1.0,1.0);

    myShaderProgram=initShaders(gl,"vertex-shader","fragment-shader");
    gl.useProgram(myShaderProgram); 
    mouseCoordinatesUniform = gl.getUniformLocation( myShaderProgram,"mouseCoordinates");
    gl.uniform2f( mouseCoordinatesUniform,.0,.0);

    setupSquare();
    render();
}

// vec2 points for args
function Triangle(x, y, z, thetaInc, spd) {
    this.onScreen = true;
    this.x = x;
    this.y = y;
    this.z = z;

    this.spawnY = y[1]; // y value of the y vertex
                        // decides where on the y axis the triangle appears offscreen


    this.theta = 0;
    this.rotationSpeed = thetaInc;
    this.speed = spd;

    this.counter = 0;


}



function setupSquare() {

    var point0 = vec2(-.2,-.2);
    var point1 = vec2(-.2,.2);
    var point2 = vec2(.2,.2);
    var point3 = vec2(.2,-.2);
    var point4 = vec2(0,.75)


    var pointa = vec2(-0.5, .4);
    var pointb = vec2( -0.25, .4);
    var pointc = vec2(-0.35, .8);

    var arrayOfpointsForSquare=[point0,point1,point2,point3,point4];
    var arrayOfPointsForTriangle=[pointa,pointb,pointc];

    var bufferId =gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER,bufferId);

    gl.bufferData(gl.ARRAY_BUFFER,flatten(arrayOfpointsForSquare),gl.STATIC_DRAW );


    var myPosition = gl.getAttribLocation(myShaderProgram,"myPosition");
    gl.vertexAttribPointer(myPosition,2,gl.FLOAT,false,0,0);
    gl.enableVertexAttribArray(myPosition);
}


function drawTriangles(){
    arrayOfPointsForTriangle = [];
    var arrayOfPointsForTriangle=[];

    for (var i = 0; i < triangleAmount; i++){
        arrayOfPointsForTriangle.push(triangles[i].x, triangles[i].y, triangles[i].z);
        console.log(triangles[i].x);
    }
    var bufferId =gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER,bufferId);

    gl.bufferData(gl.ARRAY_BUFFER,flatten(arrayOfPointsForTriangle),gl.STATIC_DRAW );


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

}


function render() {
    var thetaUniform = gl.getUniformLocation(myShaderProgram,"theta" );
    gl.uniform1f(thetaUniform,theta);
    gl.clear(gl.COLOR_BUFFER_BIT );
    gl.drawArrays(gl.TRIANGLE_FAN,0,5);

    drawTriangles();
    gl.drawArrays(gl.TRIANGLE_FAN,0,3);

    theta+=.01*stopStartFlag;
    clipX=clipX+stepX*speed;
    clipY=clipY+stepY*speed;
    gl.uniform2f(mouseCoordinatesUniform,clipX,clipY);
    requestAnimFrame(render);
}

可以在http://www.aceverything.com/cskelly/project1/project1.html

查看当前状态的示例

1 个答案:

答案 0 :(得分:1)

  

您正在使用它来绘制三角形:

gl.drawArrays(gl.TRIANGLE_FAN,0,3);

这意味着&#34;使用3个顶点&#34;绘制风扇。它更适合使用gl.drawArrays(gl.TRIANGLES,0,3);,但粉丝也应该没问题。

这是三角扇:btw:

enter image description here

我在您添加的网站上找到的代码中的

但是,我看到gl.drawArrays( gl.TRIANGLE_FAN, 0, 6 );gl.drawArrays( gl.TRIANGLE_FAN, 0, 4 );。这导致多边形ofc。

  

顶点属性指针大小与准备好的数组不匹配,与顶点着色器

不匹配

另一个问题在于:

arrayOfPointsForTriangle.push(triangles[i].x, triangles[i].y, triangles[i].z);

...

gl.vertexAttribPointer(myPosition,2,gl.FLOAT,false,0,0);

...可能在顶点着色器中:

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

    attribute vec4 myPosition;

让我解释一下,首先你说三角形的每个顶点都有x,y z坐标,但你的演示似乎是2D,所以你应该只有x,y?

然后gl.vertexAttribPointer(myPosition, 2 ... 这意味着您的gl.drawArrays将为每个顶点使用2个项目。但是包含数据的数组包含3个组件,所以这很麻烦。

最后一件事,在您定义attribute vec4 myPosition的顶点着色器中,但因为您使用了gl.vertexAttribPointer(myPosition, 2 ...,它应该是attribute vec2 myPosition。但是你不在着色器中使用z和w属性,所以至少它似乎是&#34;工作&#34;。