WebGl 将多个对象添加到一个 canvas
WebGl adding multiple objects to one canvas
这是我在 WebGL 中的第一个实验:我正在尝试将立方体、八面体和四面体添加到单个 canvas。我分别对每个形状进行了编程并对其进行了测试:它们在各自的 canvases 中工作。当我尝试将它们加在一起时,事情就出错了。目前我只看到八面体在旋转(不,它没有遮挡其他形状,我已经检查过了)。当我注释掉八面体时,我看到立方体和四面体在旋转,但它们的颜色缓冲区已经混合在一起并且不是我想要的(当我尝试分离它们的颜色缓冲区时,没有任何东西呈现到屏幕上)。我意识到我的编码方式存在不一致,但目前的配置是我可以同时显示这两个对象的唯一方式。现在最近添加的八面体使前两个消失了。
我感觉这个问题与顶点和颜色缓冲区有关,但我没有足够的经验和背景来知道要修改什么。我是否为其中的每一个实例化一个颜色缓冲区?那是有道理的。我试过了,但是前两个形状效果不佳,因此混合了颜色缓冲区。
如果有人能就此提出建议/帮助我,我将不胜感激。已经花了无数个小时试图解决这个问题。
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 );
}
我在这里上传了完整的代码结构:
您需要设置程序,然后在绘制之前为每个模型设置属性和制服。
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
- 使用程序=
gl.useProgram
- 设置属性=
gl.enableVertexAttribArray
,gl.vertexAttribPointer
- 套装制服=
gl.uniformXXX
,gl.activeTexture
+gl.bindTexture
See this answer as well
这是我在 WebGL 中的第一个实验:我正在尝试将立方体、八面体和四面体添加到单个 canvas。我分别对每个形状进行了编程并对其进行了测试:它们在各自的 canvases 中工作。当我尝试将它们加在一起时,事情就出错了。目前我只看到八面体在旋转(不,它没有遮挡其他形状,我已经检查过了)。当我注释掉八面体时,我看到立方体和四面体在旋转,但它们的颜色缓冲区已经混合在一起并且不是我想要的(当我尝试分离它们的颜色缓冲区时,没有任何东西呈现到屏幕上)。我意识到我的编码方式存在不一致,但目前的配置是我可以同时显示这两个对象的唯一方式。现在最近添加的八面体使前两个消失了。
我感觉这个问题与顶点和颜色缓冲区有关,但我没有足够的经验和背景来知道要修改什么。我是否为其中的每一个实例化一个颜色缓冲区?那是有道理的。我试过了,但是前两个形状效果不佳,因此混合了颜色缓冲区。
如果有人能就此提出建议/帮助我,我将不胜感激。已经花了无数个小时试图解决这个问题。
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 );
}
我在这里上传了完整的代码结构:
您需要设置程序,然后在绘制之前为每个模型设置属性和制服。
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
- 使用程序=
gl.useProgram
- 设置属性=
gl.enableVertexAttribArray
,gl.vertexAttribPointer
- 套装制服=
gl.uniformXXX
,gl.activeTexture
+gl.bindTexture
See this answer as well