WebGl 将多个对象添加到一个画布

cad*_*ebe 0 html javascript webgl

这是我在 WebGL 中的第一个实验:我试图将一个立方体、八面体和四面体添加到单个画布上。我分别对每个形状进行编程并测试它们:它们每个都在自己的画布中工作。当我尝试将它们加在一起时,就会出现问题。目前我只看到八面体在旋转(不,它没有遮挡其他形状,我已经检查过)。当我注释掉八面体时,我看到立方体和四面体在旋转,但它们的颜色缓冲区已经混合在一起并且不是我想要的(当我尝试分离它们的颜色缓冲区时,没有任何东西呈现在屏幕上)。我意识到我编码这些的方式存在不一致,但目前的配置是我可以同时显示这两个对象的唯一方法。现在最近添加的八面体使前两个消失了。

我感觉这个问题与顶点和颜色缓冲区有关,但我没有足够的经验和背景来知道要修改什么。我是否为每一个实例化了一个颜色缓冲区?那是有道理的。我试过这个,但前两种形状效果不佳,因此混合了颜色缓冲区。

如果有人能就此提出建议/帮助我,将不胜感激。已经花了无数个小时试图解决这个问题。

var canvas;
var gl;

var NumVertices  = 36;

var points = [];
var colors = [];

var pointsT = [];
var colorsT = [];

var pointsO = [];
var colorsO = [];

var xAxis = 0;
var yAxis = 1;
var zAxis = 2;

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

var thetaLoc;

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

    gl = WebGLUtils.setupWebGL( canvas );
    if ( !gl ) { alert( "WebGL is not available" ); }


    // --------------- Cube --------------------------

    colorCube();

    // --------------- Tetrahedron -------------------

    colorTetra();

    // --------------- Octohedron --------------------

    colorOcto();


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

    gl.enable(gl.DEPTH_TEST);


    // --------------- Load shaders and initialize attribute buffers

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

    var cBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );

    var vColor = gl.getAttribLocation( program, "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(points), gl.STATIC_DRAW );

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

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


    // --------------- Tetrahedron -------------------

    var tcBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, tcBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );

    var tvColor = gl.getAttribLocation( program, "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(points), gl.STATIC_DRAW );

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


    // --------------- Octohedron --------------------      

    var ocBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, ocBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(colorsO), gl.STATIC_DRAW );

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

    var ovBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, ovBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsO), gl.STATIC_DRAW );

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

    render();
}

function render()
{
    gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

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

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

    // Render tetrahedron
    gl.drawArrays( gl.TRIANGLES, 0, points.length );

    // Render sphere
    gl.drawArrays( gl.TRIANGLES, 0, pointsO.length );
    requestAnimFrame( render );
}


// DEFINE CUBE

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 quad(a, b, c, d) 
{
    var vertices = [
        vec3( -0.25, -0.25,  0.25 ),
        vec3( -0.25,  0.25,  0.25 ),
        vec3(  0.25,  0.25,  0.25 ),
        vec3(  0.25, -0.25,  0.25 ),
        vec3( -0.25, -0.25, -0.25 ),
        vec3( -0.25,  0.25, -0.25 ),
        vec3(  0.25,  0.25, -0.25 ),
        vec3(  0.25, -0.25, -0.25 )
    ];

    var vertexColors = [
        [ 0.9, 0.9, 0.2, 1.0 ],  // oarnge
        [ 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
        [ 1.0, 1.0, 1.0, 1.0 ],  // white
        [ 0.0, 1.0, 1.0, 1.0 ]   // cyan
    ];

    // Partion the quad into two triangles in order for
    // WebGL to be able to render it.      
    // 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 ) {
        points.push( vertices[indices[i]] );
        colors.push( vertexColors[indices[i]] );

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

// DEFINE TETRAHEDRON

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] );
    points.push( a );
    colors.push( baseColors[color] );
    points.push( b );
    colors.push( baseColors[color] );
    points.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 );
}


// DEFINE OCTOHEDRON

function colorOcto(){

    var verticesO = [
        vec3(  0.4000, 0.0000, 0.0000 ),        
        vec3(  0.0000, 0.0000, 0.0000 ),
        vec3(  0.0000, 0.4000, 0.0000 ),
        vec3(  0.4000, 0.4000, 0.0000 ),
        vec3(  0.2000, 0.2000, 0.3000 ),
        vec3(  0.2000, 0.2000, -0.3000 )
    ];

    octo(verticesO[0], verticesO[1], verticesO[2], verticesO[3], verticesO[4], verticesO[5]);   
}

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

    var baseColors = [
        vec3(0.6, 0.6, 0.6, 1.0),
        vec3(0.3, 0.4, 0.9, 1.0),
        vec3(0.9, 0.9, 0.9, 1.0),
    ];

    colorsO.push( baseColors[color] );
    pointsO.push( a );
    colorsO.push( baseColors[color] );
    pointsO.push( b );
    colorsO.push( baseColors[color] );
    pointsO.push( c );
}

function octo( a, b, c, d , e, f)
{
    // tetrahedron with each side using
    // a different color

    makeOcto( a, d, e, 0 );
    makeOcto( a, b, e, 1 );
    makeOcto( b, c, e, 0 );
    makeOcto( c, d, e, 1 );
    makeOcto( a, d, f, 1 );
    makeOcto( a, b, f, 2 );
    makeOcto( b, c, f, 1 );
    makeOcto( c, d, f, 2 );
}
Run Code Online (Sandbox Code Playgroud)

我在这里上传了完整的代码结构:

https://gist.github.com/Carla-de-Beer/10ad7c7309fad48d94df

gma*_*man 5

在绘制之前,您需要设置程序,然后为每个模型设置属性和制服。

use program for cube
set attributes for cube
set uniforms for cube
draw cube

use program for tetrahedon
set attributes for tetrahedon
set uniforms for tetrahedon
draw tetrahedon

use program for sphere
set attributes for sphere
set uniforms for sphere
draw sphere
Run Code Online (Sandbox Code Playgroud)
  • 使用程序 = gl.useProgram
  • 设置属性 = gl.enableVertexAttribArray,gl.vertexAttribPointer
  • 设置制服 = gl.uniformXXX, gl.activeTexture+gl.bindTexture

也看到这个答案