1

後で木の葉のように見えるように変更できる球メッシュを描画しようとしています。ただし、pointsArray には、球体メッシュから生成された頂点よりも前にある頂点もあります。各三角形を順番に描画するためのインデックスを含むインデックス バッファーがありますが、インデックス バッファーが他の頂点から三角形を描画することなく、球メッシュである頂点の最後の部分にアクセスする必要があります。ここでは、頂点、色、テクスチャ座標のバッファーを作成して、シェーダー コードに転送します。また、球メッシュ用に作成されたインデックス バッファもあります。

function loadBuffers()
{   
    // Load the colors for the triangles and enable the attribute vColor
    var cBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(colorsArray), gl.STATIC_DRAW );

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


    // Load the vertices for the triangles and enable the attribute vPosition
    var vBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW );

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

    var tBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, tBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(texturesArray), gl.STATIC_DRAW );

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

    iBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, iBuffer);
    console.log(indexBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexBuffer), gl.STATIC_DRAW);
    iBuffer.itemSize = 1;
    iBuffer.numItems = indexBuffer.length;
}

ここに私の球体生成コードがあります:

function sphere()
{
    genSphereVertices(1, 10, 10, 0, 0, 1.5);
    plotSphere(10, 10);
}

function genSphereVertices(radius, latBands, lonBands, X, Y, Z)
{
    var normRadius = 1;

    for (var lat = 0; lat < latBands + 1; ++lat)
    {
        var theta = lat * Math.PI/latBands; //0 to pi
        var z = normRadius * Math.cos(theta);

        for (var lon = 0; lon < lonBands + 1; ++lon)
        {
            var phi = 2 * lon * Math.PI/lonBands;//0 to 2pi

            var u = Math.sqrt((normRadius * normRadius) - (z * z));

            var x = u * Math.cos(phi);
            var y = u * Math.sin(phi);

            //here I push my new x,y,z vertex to the pointsArray,
            //however pointsArray is also being used to draw a building
            //with textures
            pointsArray.push(vec4((X+x)*radius, (Y+y)*radius, (Z+z)*radius, 1.0));
            numVertices++;
            colorsArray.push(faceColors[lon%7]);
        }
    }
}

function plotSphere(latBands, lonBands)
{
    for (var lat = 0; lat < latBands; ++lat)
    {
        for (var lon = 0; lon < lonBands; ++lon)
        {
            //map indices to tell what order to connect each vertex
            var vA = lat * (lonBands + 1) + lon;
            var vB = vA + (latBands + 1);
            var vC = vA + 1;
            var vD = vB + 1;

            indexBuffer.push(vA);
            indexBuffer.push(vB);
            indexBuffer.push(vC);
            indexBuffer.push(vB);
            indexBuffer.push(vD);
            indexBuffer.push(vC);
        }
    }
}

ここでは、残りの頂点を描画した後に球を描画しようとしています。

function render()
{
    objOffset = 0;

    if (loadedImageCount == imageTextures.length)//textures on building
    {
        for (var i = 0; i < numFaces; ++i)//move through each face and map textures to specific faces
        {
            if (i < 60){//walls
                gl.uniform1i(fs_textureLoc, 0);
            }else if (i < 69){//building tops
                gl.uniform1i(fs_textureLoc, 1);
            }else if (i < 73){//slanted rooves
                gl.uniform1i(fs_textureLoc, 2);
            }else if (i < 93){//stairs
                gl.uniform1i(fs_textureLoc, 3);
            }
            //draw each face (each is a rect with 2 triangles)
            gl.drawArrays(gl.TRIANGLES, objOffset, twoTriangles);
            objOffset += twoTriangles;
        }
    }


    //now I want to draw the sphere, but the index buffer is starting from
    //the beginning of the pointsArray! :(
    gl.drawElements(gl.TRIANGLES, iBuffer.numItems, gl.UNSIGNED_SHORT, 0);

    //animate scene
    requestAnimFrame(render);
}

このコードを実行すると、インデックス バッファーは pointsArray の先頭から描画を開始し、建物全体を描画します。球体メッシュのインデックス バッファのみを使用するには、pointsArray のオフセットから開始する方法を教えてください。

メッシュを描画する前の状態は次のとおりです。球メッシュを描画しようとすると、次のようになります。

4

0 に答える 0