私はWebGLモデルの階層を学習しており、胴に接続された独立した可動アームセグメントを持つロボットを描画するプログラムを作成しました。私はこれを達成することができました。スライダを介して操作するまで、右上腕と下腕がレンダリングされないという副作用がありました。ロボットの右側が操作されるまでレンダリングされませんWebGL
物事は私が試してみました:
は、左右の腕、効果なしの両方のために別々の変数を宣言します。 スタックからプッシュ/ポップする代わりにmodelViewMatrixのコピーを作成します。効果はありません。 drawrobot関数を無効にして、レンダリング関数内で独立した階層(腕)を直接描画します。効果はありません。 チェックしてください。何も見つかりませんでした。
私は本当に私の問題を突き止めようとしています。ヘルプ/感謝のアイデアは、コードは以下の通りです:
<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="../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="myrobotArm.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 leftarm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider3">
upper leftarm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider4">
lower rightarm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider5">
upper rightarm 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>
var NumVertices = 36; //(6 faces)(2 triangles/face)(3 vertices/triangle)
var points = [];
var colors = [];
var myStack = [];
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)
];
// RGBA colors
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
];
// Parameters controlling the size of the Robot's arm
var BASE_HEIGHT = 5.0;
var BASE_WIDTH = 2.0;
var LOWER_ARM_HEIGHT = 0.5;
var LOWER_ARM_WIDTH = 2.0;
var UPPER_ARM_HEIGHT = 0.5;
var UPPER_ARM_WIDTH = 2.0;
var LOWERR_ARM_HEIGHT = 0.5;
var LOWERR_ARM_WIDTH = 2.0;
var UPPERR_ARM_HEIGHT = 0.5;
var UPPERR_ARM_WIDTH = 2.0;
// Shader transformation matrices
var modelViewMatrix, projectionMatrix;
// Array of rotation angles (in degrees) for each rotation axis
var Base = 0;
var LowerArmL = 1;
var UpperArmL = 2;
var LowerArmR = 3;
var UpperArmR = 4;
var theta= [ 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);
}
//____________________________________________
// Remmove when scale in MV.js supports scale matrices
function scale4(a, b, c) {
var result = mat4();
result[0][0] = a;
result[1][1] = b;
result[2][2] = c;
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);
//
// Load shaders and initialize attribute buffers
//
program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
colorCube();
// Load shaders and use the resulting shader program
program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
// Create and initialize buffer objects
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/2;
};
document.getElementById("slider2").onchange = function(event) {
theta[1] = event.target.value/2;
};
document.getElementById("slider3").onchange = function(event) {
theta[2] = event.target.value/2;
};
document.getElementById("slider4").onchange = function(event) {
theta[3] = event.target.value/2;
};
document.getElementById("slider5").onchange = function(event) {
theta[4] = event.target.value/2;
};
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 upperArmL() {
var s = scale4(UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH);
var instanceMatrix = mult(translate(-0.5 * UPPER_ARM_WIDTH, 0.0, 0.0),s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(t));
gl.drawArrays(gl.TRIANGLES, 0, NumVertices);
}
//----------------------------------------------------------------------------
function lowerArmL()
{
var s = scale4(LOWER_ARM_WIDTH, LOWER_ARM_HEIGHT, LOWER_ARM_WIDTH);
var instanceMatrix = mult(translate(-0.5 * LOWER_ARM_WIDTH, 0.0, 0.0),s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(t));
gl.drawArrays(gl.TRIANGLES, 0, NumVertices);
}
function upperArmR() {
var s = scale4(UPPERR_ARM_WIDTH, UPPERR_ARM_HEIGHT, UPPERR_ARM_WIDTH);
var instanceMatrix = mult(translate(0.5 * UPPERR_ARM_WIDTH, 0.0, 0.0),s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(t));
gl.drawArrays(gl.TRIANGLES, 0, NumVertices);
}
//----------------------------------------------------------------------------
function lowerArmR()
{
var s = scale4(LOWERR_ARM_WIDTH, LOWERR_ARM_HEIGHT, LOWERR_ARM_WIDTH);
var instanceMatrix = mult(translate(0.5 * LOWERR_ARM_WIDTH, 0.0, 0.0),s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(t));
gl.drawArrays(gl.TRIANGLES, 0, NumVertices);
}
//----------------------------------------------------------------------------
function drawRobot()
{
modelViewMatrix = rotate(theta[Base], 0, 1, 0);
var myMVM = modelViewMatrix;
// myStack.push(modelViewMatrix);
base();
// modelViewMatrix = myStack.pop();
// modelViewMatrix = myMVM;
// myStack.push(modelViewMatrix);
modelViewMatrix = mult(modelViewMatrix, translate(-0.5 * BASE_WIDTH, BASE_HEIGHT - 0.5 * UPPER_ARM_HEIGHT, 0.0)); //POSITION OF RECT
modelViewMatrix = mult(modelViewMatrix, rotate(theta[UpperArmL], 0, 0, 1)); //ROTATE AROUND Z AXIS BY UPPERARML Degrees
upperArmL();
modelViewMatrix = mult(modelViewMatrix, translate(-UPPER_ARM_WIDTH, 0.0, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[LowerArmL], 0, 0, 1));
lowerArmL();
// modelViewMatrix = myStack.pop();
modelViewMatrix = myMVM;
modelViewMatrix = mult(modelViewMatrix, translate(0.5 * BASE_WIDTH, BASE_HEIGHT - 0.5 * UPPERR_ARM_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[UpperArmR], 0, 0, 1));
upperArmR();
modelViewMatrix = mult(modelViewMatrix, translate(UPPERR_ARM_WIDTH, 0.0, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[LowerArmR], 0, 0, 1));
lowerArmR();
}
var render = function() {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
drawRobot();
requestAnimFrame(render);
}
最初の段落の情報は無関係なので削除しました。 *あなたが投稿したコードに関して、コードがエラーなく実行され、意図したとおりに動作する*より多くの詳細を提供すれば、おそらくもっと速く答えを得るのに役立ちます。 –
@Cos 'var myMVM = new ...'、 'myMVM.copy(modelViewMatrix)'のように、 'var myMVM = modelViewMatrix;'、 'myMVM'と' modelViewMatrix'の後ろに同じオブジェクト。 – Rabbid76
私は応答を感謝します。私の本で使われているメソッドでは、スタックに親として使用したい行列をプッシュし、各子ブランチ変換を行う前にポップ/プッシュバックして、継承された各子の最初のmodelViewMatrix(胴体)変換を保持しますつかいます。これにより、腕全体が描かれた後でpop/pushを呼び出すだけで腕のセグメントを追加することができます。私はこのアプローチを試みました。それは私の現在の "varを作成し、それを保存したい行列に設定する"と同じ結果を与えます。それで、それは適切に通過しています。 – Cos