首页 > 解决方案 > 旋转机械臂

问题描述

目标:以下代码的目标是制作一个移动的机器人手臂,它具有三层(上、下和中),所有这些都连接到底座上。给出了 4 个滑块,它们可以独立移动每个部分,除了将移动所有手臂的底座。

问题:我遇到的问题是,当我尝试运行此代码时,屏幕上没有任何视觉效果,控制台中也没有错误,我找不到问题的原因。我还附上了输出的图片。

解决方法:还没找到。

var NumVertices = 36;

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

var vertices = [
    vec4( -0.5, -0.5,  0.5, 1.0 ),
    vec4( -0.5,  0.5,  0.5, 1.0 ),
    vec4(  0.5,  0.5,  0.5, 1.0 ),
    vec4(  0.5, -0.5,  0.5, 1.0 ),
    vec4( -0.5, -0.5, -0.5, 1.0 ),
    vec4( -0.5,  0.5, -0.5, 1.0 ),
    vec4(  0.5,  0.5, -0.5, 1.0 ),
    vec4(  0.5, -0.5, -0.5, 1.0 )
];

var vertexColors = [
    vec4( 0.0, 0.0, 0.0, 1.0 ),  // black
    vec4( 1.0, 0.0, 0.0, 1.0 ),  // red
    vec4( 1.0, 1.0, 0.0, 1.0 ),  // yellow
    vec4( 0.0, 1.0, 0.0, 1.0 ),  // green
    vec4( 0.0, 0.0, 1.0, 1.0 ),  // blue
    vec4( 1.0, 0.0, 1.0, 1.0 ),  // magenta
    vec4( 1.0, 1.0, 1.0, 1.0 ),  // white
    vec4( 0.0, 1.0, 1.0, 1.0 )   // cyan
];


var BASE_HEIGHT      = 2.0;
var BASE_WIDTH       = 5.0;
var LOWER_ARM_HEIGHT = 5.0;
var LOWER_ARM_WIDTH  = 0.5;
var UPPER_ARM_HEIGHT = 5.0;
var UPPER_ARM_WIDTH  = 0.5;
var MIDDLE_ARM_HEIGHT = 5.0;
var MIDDLE_ARM_WIDTH  = 0.5;

var modelViewMatrix, projectionMatrix;

var Base = 0;
var LowerArm = 1;
var UpperArm = 2;
var MiddleArm = 3;


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

var angle = 0;

var modelViewMatrixLoc;

var vBuffer, cBuffer;


function quad(  a,  b,  c,  d ) {
    colors.push(vertexColors[a]); 
    points.push(vertices[a]); 
    colors.push(vertexColors[a]); 
    points.push(vertices[b]); 
    colors.push(vertexColors[a]); 
    points.push(vertices[c]);
    colors.push(vertexColors[a]); 
    points.push(vertices[a]); 
    colors.push(vertexColors[a]); 
    points.push(vertices[c]); 
    colors.push(vertexColors[a]); 
    points.push(vertices[d]); 
}


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 scale4(a, b, c, d) {
   var result = mat4();
   result[0][0] = a;
   result[1][1] = b;
   result[2][2] = c;
   result[3][3] = d;
   return result;
}

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 );
    gl.enable( gl.DEPTH_TEST ); 
    
    program = initShaders( gl, "vertex-shader", "fragment-shader" );
    
    gl.useProgram( program );

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

    
    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, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vPosition );

    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 );

    document.getElementById("slider1").onchange = function(event) {
        theta[0] = event.target.value;
    };
    document.getElementById("slider2").onchange = function(event) {
         theta[1] = event.target.value;
    };
    document.getElementById("slider3").onchange = function(event) {
         theta[2] =  event.target.value;
    };
      document.getElementById("slider4").onchange = function(event) {
         theta[3] =  event.target.value;
    };
    modelViewMatrixLoc = gl.getUniformLocation(program, "modelViewMatrix");

    projectionMatrix = ortho(-10, 10, -10, 10, -10, 10);
    gl.uniformMatrix4fv( gl.getUniformLocation(program, "projectionMatrix"),  false, flatten(projectionMatrix) );
    
    render();
}

function base() {
    var s = scale4(BASE_WIDTH, BASE_HEIGHT, BASE_WIDTH);
    var instanceMatrix = mult( translate( 0.0, 0.5 * BASE_HEIGHT, 0.0 ), s);
    var t = mult(modelViewMatrix, instanceMatrix);
    gl.uniformMatrix4fv(modelViewMatrixLoc,  false, flatten(t) );
    gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}

function upperArm() {
    var s = scale4(UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH);
    var instanceMatrix = mult(translate( 0.0, 0.5 * UPPER_ARM_HEIGHT, 0.0 ),s);    
    var t = mult(modelViewMatrix, instanceMatrix);
    gl.uniformMatrix4fv( modelViewMatrixLoc,  false, flatten(t) );
    gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}


function lowerArm()
{
    var s = scale4(LOWER_ARM_WIDTH, LOWER_ARM_HEIGHT, LOWER_ARM_WIDTH);
    var instanceMatrix = mult( translate( 0.0, 0.5 * LOWER_ARM_HEIGHT, 0.0 ), s);
    var t = mult(modelViewMatrix, instanceMatrix);
    gl.uniformMatrix4fv( modelViewMatrixLoc,  false, flatten(t) );
    gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}


function middleArm()
{
    var s = scale4(MIDDLE_ARM_WIDTH, MIDDLE_ARM_HEIGHT, MIDDLE_ARM_WIDTH);
    var instanceMatrix = mult( translate( 0.0, 0.5 * MIDDLE_ARM_HEIGHT, 0.0 ), s);
    var t = mult(modelViewMatrix, instanceMatrix);
    gl.uniformMatrix4fv( modelViewMatrixLoc,  false, flatten(t) );
    gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}

var render = function() {

    gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
    
    modelViewMatrix = rotate(theta[Base], 0, 1, 0 );
    base();
 
    modelViewMatrix = mult(modelViewMatrix, translate(0.0, BASE_HEIGHT, 0.0)); 
    modelViewMatrix = mult(modelViewMatrix, rotate(theta[LowerArm], 0, 0, 1 ));
    lowerArm();

    modelViewMatrix  = mult(modelViewMatrix, translate(0.0, LOWER_ARM_HEIGHT, 0.0));
    modelViewMatrix  = mult(modelViewMatrix, rotate(theta[UpperArm], 0, 0, 1) );
    upperArm();

    modelViewMatrix  = mult(modelViewMatrix, translate(0.0, UPPER_ARM_HEIGHT, 0.0));
    modelViewMatrix  = mult(modelViewMatrix, rotate(theta[MiddleArm], 0, 0, 1) );
    middleArm();
    
    requestAnimFrame(render);
}
<html>

<script id="vertex-shader" type="x-shader/x-vertex">
attribute  vec4 vPosition;
attribute  vec4 vColor;
varying vec4 fColor;

uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;

void main() 
{
    fColor = vColor;
    gl_Position = projectionMatrix * modelViewMatrix * vPosition;
} 
</script>

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

precision mediump float;

varying  vec4 fColor;

void main() 
{ 
    gl_FragColor = fColor;
} 
</script>

<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script type="text/javascript"src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<script type="text/javascript" src="robotArm.js"></script>

<div id="slider1">
body angle -180 <input id="slide" type="range"
 min="-180" max="180" step="10" value="0"
  />
 180
</div><br/>

<div id="slider2">
lower arm angle -180 <input id="slide" type="range"
 min="-180" max="180" step="10" value="0"
  />
 180
</div><br/>
<div id="slider4">
middle arm angle -180 <input id="slide" type="range"
 min="-180" max="180" step="10" value="0"
  />
 180
</div><br/>
<div id="slider3">
upper arm angle -180 <input id="slide" type="range"
 min="-180" max="180" step="10" value="0"
  />
 180
</div><br/>


<body>
<canvas id="gl-canvas" width="512"" height="512"
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>

输出

标签: javascripthtmlcsshtml5-canvaswebgl

解决方案


我做的第一件事是添加webgl-lint

<script src="https://greggman.github.io/webgl-lint/webgl-lint.js" crossorigin></script>

那立即得到了错误

Uncaught Error: https://greggman.github.io/webgl-lint/webgl-lint.js:2843: 
error in 
uniformMatrix4fv(WebGLUniformLocation("modelViewMatrix"),
false,
[5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 0, NaN, NaN, NaN, NaN]): element 12 of argument 2 is NaN
: trying to set uniform 'modelViewMatrix'
    at reportError (webgl-lint.js:2163)
    at reportFunctionError (webgl-lint.js:2924)
    at checkArrayForUniformImpl (webgl-lint.js:2843)
    at webgl-lint.js:2869
    at checkArgs (webgl-lint.js:2972)
    at WebGLRenderingContext.ctx.<computed> [as uniformMatrix4fv] (webgl-lint.js:3016)
    at base (js:230)
    at render (js:267)
    at init (js:223)

查看您的代码,问题是rotate不需要 4 个参数,它需要 2 个参数,一个角度和一个轴

   r = rotate(angle, x, y, z); // BAD!
   r = rotate(angle, [x, y, z]); // Good

修复 webgl-lint 打印了一个新错误。问题是scale4需要 4 个参数。

   s = scale4(x, y, z); // BAD!
   s = scale4(x, y, z, w); // good

你想通过1w。

那个固定的渲染。至于您可能想要render在每个onchange函数中调用的滑块。您可能还想使用oninput而不是onchange

var NumVertices = 36;

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

var vertices = [
    vec4( -0.5, -0.5,  0.5, 1.0 ),
    vec4( -0.5,  0.5,  0.5, 1.0 ),
    vec4(  0.5,  0.5,  0.5, 1.0 ),
    vec4(  0.5, -0.5,  0.5, 1.0 ),
    vec4( -0.5, -0.5, -0.5, 1.0 ),
    vec4( -0.5,  0.5, -0.5, 1.0 ),
    vec4(  0.5,  0.5, -0.5, 1.0 ),
    vec4(  0.5, -0.5, -0.5, 1.0 )
];

var vertexColors = [
    vec4( 0.0, 0.0, 0.0, 1.0 ),  // black
    vec4( 1.0, 0.0, 0.0, 1.0 ),  // red
    vec4( 1.0, 1.0, 0.0, 1.0 ),  // yellow
    vec4( 0.0, 1.0, 0.0, 1.0 ),  // green
    vec4( 0.0, 0.0, 1.0, 1.0 ),  // blue
    vec4( 1.0, 0.0, 1.0, 1.0 ),  // magenta
    vec4( 1.0, 1.0, 1.0, 1.0 ),  // white
    vec4( 0.0, 1.0, 1.0, 1.0 )   // cyan
];


var BASE_HEIGHT      = 2.0;
var BASE_WIDTH       = 5.0;
var LOWER_ARM_HEIGHT = 5.0;
var LOWER_ARM_WIDTH  = 0.5;
var UPPER_ARM_HEIGHT = 5.0;
var UPPER_ARM_WIDTH  = 0.5;
var MIDDLE_ARM_HEIGHT = 5.0;
var MIDDLE_ARM_WIDTH  = 0.5;

var modelViewMatrix, projectionMatrix;

var Base = 0;
var LowerArm = 1;
var UpperArm = 2;
var MiddleArm = 3;


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

var angle = 0;

var modelViewMatrixLoc;

var vBuffer, cBuffer;


function quad(  a,  b,  c,  d ) {
    colors.push(vertexColors[a]); 
    points.push(vertices[a]); 
    colors.push(vertexColors[a]); 
    points.push(vertices[b]); 
    colors.push(vertexColors[a]); 
    points.push(vertices[c]);
    colors.push(vertexColors[a]); 
    points.push(vertices[a]); 
    colors.push(vertexColors[a]); 
    points.push(vertices[c]); 
    colors.push(vertexColors[a]); 
    points.push(vertices[d]); 
}


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 scale4(a, b, c, d) {
   var result = mat4();
   result[0][0] = a;
   result[1][1] = b;
   result[2][2] = c;
   result[3][3] = d;
   return result;
}

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 );
    gl.enable( gl.DEPTH_TEST ); 
    
    program = initShaders( gl, "vertex-shader", "fragment-shader" );
    
    gl.useProgram( program );

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

    
    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, 4, gl.FLOAT, false, 0, 0 );
    gl.enableVertexAttribArray( vPosition );

    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 );

    document.getElementById("slider1").oninput = function(event) {
        theta[0] = event.target.value;
         render();
    };
    document.getElementById("slider2").oninput = function(event) {
         theta[1] = event.target.value;
         render();
    };
    document.getElementById("slider3").oninput = function(event) {
         theta[2] =  event.target.value;
         render();
    };
      document.getElementById("slider4").oninput = function(event) {
         theta[3] =  event.target.value;
         render();
    };
    modelViewMatrixLoc = gl.getUniformLocation(program, "modelViewMatrix");

    projectionMatrix = ortho(-10, 10, -10, 10, -10, 10);
    gl.uniformMatrix4fv( gl.getUniformLocation(program, "projectionMatrix"),  false, flatten(projectionMatrix) );
    
    render();
}

function base() {
    var s = scale4(BASE_WIDTH, BASE_HEIGHT, BASE_WIDTH, 1);
    var instanceMatrix = mult( translate( 0.0, 0.5 * BASE_HEIGHT, 0.0 ), s);
    var t = mult(modelViewMatrix, instanceMatrix);
    gl.uniformMatrix4fv(modelViewMatrixLoc,  false, flatten(t) );
    gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}

function upperArm() {
    var s = scale4(UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH, 1);
    var instanceMatrix = mult(translate( 0.0, 0.5 * UPPER_ARM_HEIGHT, 0.0 ),s);    
    var t = mult(modelViewMatrix, instanceMatrix);
    gl.uniformMatrix4fv( modelViewMatrixLoc,  false, flatten(t) );
    gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}


function lowerArm()
{
    var s = scale4(LOWER_ARM_WIDTH, LOWER_ARM_HEIGHT, LOWER_ARM_WIDTH, 1);
    var instanceMatrix = mult( translate( 0.0, 0.5 * LOWER_ARM_HEIGHT, 0.0 ), s);
    var t = mult(modelViewMatrix, instanceMatrix);
    gl.uniformMatrix4fv( modelViewMatrixLoc,  false, flatten(t) );
    gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}


function middleArm()
{
    var s = scale4(MIDDLE_ARM_WIDTH, MIDDLE_ARM_HEIGHT, MIDDLE_ARM_WIDTH, 1);
    var instanceMatrix = mult( translate( 0.0, 0.5 * MIDDLE_ARM_HEIGHT, 0.0 ), s);
    var t = mult(modelViewMatrix, instanceMatrix);
    gl.uniformMatrix4fv( modelViewMatrixLoc,  false, flatten(t) );
    gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}

var render = function() {

    gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
    
    modelViewMatrix = rotate(theta[Base], [0, 1, 0]);
    base();
 
    modelViewMatrix = mult(modelViewMatrix, translate(0.0, BASE_HEIGHT, 0.0)); 
    modelViewMatrix = mult(modelViewMatrix, rotate(theta[LowerArm], [0, 0, 1] ));
    lowerArm();

    modelViewMatrix  = mult(modelViewMatrix, translate(0.0, LOWER_ARM_HEIGHT, 0.0));
    modelViewMatrix  = mult(modelViewMatrix, rotate(theta[UpperArm], [0, 0, 1]) );
    upperArm();

    modelViewMatrix  = mult(modelViewMatrix, translate(0.0, UPPER_ARM_HEIGHT, 0.0));
    modelViewMatrix  = mult(modelViewMatrix, rotate(theta[MiddleArm], [0, 0, 1]) );
    middleArm();
    
    requestAnimFrame(render);
}
<html>

<script id="vertex-shader" type="x-shader/x-vertex">
attribute  vec4 vPosition;
attribute  vec4 vColor;
varying vec4 fColor;

uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;

void main() 
{
    fColor = vColor;
    gl_Position = projectionMatrix * modelViewMatrix * vPosition;
} 
</script>

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

precision mediump float;

varying  vec4 fColor;

void main() 
{ 
    gl_FragColor = fColor;
} 
</script>
<script src="https://greggman.github.io/webgl-lint/webgl-lint.js" crossorigin></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script type="text/javascript"src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<script type="text/javascript" src="robotArm.js"></script>

<div id="slider1">
body angle -180 <input id="slide" type="range"
 min="-180" max="180" step="10" value="0"
  />
 180
</div><br/>

<div id="slider2">
lower arm angle -180 <input id="slide" type="range"
 min="-180" max="180" step="10" value="0"
  />
 180
</div><br/>
<div id="slider4">
middle arm angle -180 <input id="slide" type="range"
 min="-180" max="180" step="10" value="0"
  />
 180
</div><br/>
<div id="slider3">
upper arm angle -180 <input id="slide" type="range"
 min="-180" max="180" step="10" value="0"
  />
 180
</div><br/>


<body>
<canvas id="gl-canvas" width="512"" height="512"
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>


推荐阅读