2016-04-17 9 views
6

ここでは何が欠けているのか分かりません。ユーザーが「回転」ボタンをクリックすることによって惑星(すなわち球体)を作ることを試みるが、それを理解しているようには見えない。私はマウスを使ってユーザーとの対話の方法で球を回転させ、次のセグメント持っています。この1つは正常に動作しますWebGLで球を回転させる

document.onmousemove = function() { 
     if (!mouseDown) { 
      return; 
     } 
     var newX = event.clientX; 
     var newY = event.clientY; 

     var deltaX = newX - lastMouseX 
     var newRotationMatrix = mat4.create(); 
     mat4.identity(newRotationMatrix); 
     mat4.rotate(newRotationMatrix, degToRad(deltaX/10), [0, 1, 0]); 

     var deltaY = newY - lastMouseY; 
     mat4.rotate(newRotationMatrix, degToRad(deltaY/10), [1, 0, 0]); 

     mat4.multiply(newRotationMatrix, planetRotationMatrix, planetRotationMatrix); 

     lastMouseX = newX 
     lastMouseY = newY; 
} 

を、私はまた、惑星を作りたいユーザーがボタンをクリックした後に自動的に回転させます。ここに私のonLoad機能である:

window.onload = function onLoad() { 
     canvas = document.getElementById("gl-canvas"); 
     initGL(canvas); 
     initShaders(); 
     initBuffers(); 
     initTexture(); 
     initEvtHandlers(); 

     gl.clearColor(0.0, 0.0, 0.0, 1.0); 
     gl.enable(gl.DEPTH_TEST); 

     var newRotationMatrix = mat4.create(); 
     mat4.identity(newRotationMatrix); 
     document.getElementById("rotate").onclick = function() { 
      // rotation code goes here? 
     } 
     render(); 
} 

私の質問は:どのようにI「トグル」は、ユーザがボタンをクリックした後に回転できますか?これまで私が試したことは、球がユーザーの介入なしに回転するようにするためにonmousemove関数を変更することですが、それは機能しません。

var myRotationMatrix = mat4.create(); 
mat4.identity(myRotationMatrix); 

doRotate = function() { 
    var dx = 1; 
    var newMatrix = mat4.create(); 
    mat4.identity(newMatrix); 
    mat4.rotate(newMatrix, degToRad(dx/10), [0, 1, 0]); 

    mat4.multiply(newMatrix, myRotationMatrix); 
    requestAnimFrame(doRotate); 
} 

現在、私のために働いていません。

は更新として、ここで私が追加された新しいdoRotate()機能です。この関数は、ボタンがクリックされたときに呼び出され、回転を切り替えます。

更新:同様のデモについては

this pageを参照してください。私がしようとしているのは、ユーザーが関連するボタンをクリックした後に球が自動的に回転するようにすることです。これは明らかにリンクされたデモではありません - それは説明のためだけです。

アップデート2:

私は考え出したので、それをしました。詳細は下記の私の答えをご覧ください。

+1

あなたが何を求めているのかは分かりません。回転させたい場合は、 'requestAnimationFrame'を使用して何らかのアニメーションループを作成する必要があります。ループのたびに、惑星を少し回転させる必要があります。 [例](http://webglfundamentals.org/webgl/lessons/webgl-animation.html)。 – gman

+0

マウスを使ってボタンを操作しなくても、ユーザーがボタンをクリックした後で球体を回転させようとしています。私はこれがrequestAnimationFrameを必要としていることを認識していますが、これまで成功していません。 –

+0

興味深い質問。例をまとめると助けになります。 codepenまたはjsfiddleを使用します。問題をよりよくデモして、最も早く回答を得ることができます。 –

答えて

3

私は試行錯誤の数え切れないほどの量の後に自分でそれを考え出しました。基本的には、WaclawJapserと書いてありましたが、私はそのシーンを再描画していませんでした。私は全部制服を無視していた。コード全体を投稿するつもりはありませんが、修正後の関連する関数は次のとおりです。

requestAnimationFrame(rotatePlanet); 

    function rotatePlanet(now) { 
     if (flag == false) { 
      return; // do nothing if unchecked 
     } else { 
      // Start by clearing the current buffers to avoid an overlap. 
      gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 
      // Subtract the previous time from the current time. 
      now *= 0.001; 
      var deltaTime = now - then; 
      // Cache the current time to remember it for the next frame. 
      then = now; 

      // Every frame increases the rotation a little. 
      rotation[0] += rotationSpeed * deltaTime; 

      // Perform the necessary transformations. 
      mat4.identity(mvMatrix); 
      mat4.translate(mvMatrix, [0, 0, -6]); 
      mat4.rotate(mvMatrix, rotation[0], [0, 1, 0]); // rotates around y 
      mat4.rotate(mvMatrix, rotation[1], [1, 0, 0]); // rotates around x 

      // Set the matrix. 
      setMatrixUniforms(); 

      // Draw the geometry. 
      gl.drawElements(gl.TRIANGLES, planetVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0); 

      requestAnimationFrame(rotatePlanet); 
     } 
    } 

これは本来意図したとおりに機能します。かなり狭い問題のように思えるので、それが誰にも役立つかどうかは分かりませんが、私はステータスアップデートを投稿したいと考えています。

お手伝いをしてくださった皆様、ありがとうございます!

3

あなたのdoRotateの問題は、シーンを再描画しないということです。確かに、新しい回転行列を計算しましたが、gpuに情報を渡したり、シーンを再度描画するよう指示したりしていません。しかし、あなたのプログラムがどのように書かれているかを知らなければ、それが実際に問題であるかどうかは言うことができません。

通常、すべてのフレームで実行され、すべての必要な更新を処理してシーンを再描画する関数mainLoopの周りにプログラムを構成することをお勧めします。これと同じように:

var lastTimeStamp = 0; 

function mainLoop(timeStamp){ 
    var dt = timeStamp - lastTimeStamp; 
    lastTimeStamp = timeStamp; 

    everythingThatNeedsUpdate.doUpdate(dt); // this should calculate the new rotationMatrix for your sphere and send it to GPU 

    gl.drawEverything(); 

    requestAnimationFrame(mainLoop); 
} 

そして、例えば、*.doUpdateは、同様に実施することができる。

*.doUpdate = function(dt){ 
    if (clickedOnSphere){ 
     rotationMatrix = doCalculations(dt); 
     // send or flag rotationMatrix to be sent to GPU; 
    } 
} 
関連する問題