2017-03-23 54 views
0

我想执行的WebGL立方体的翻译,但我得到的立方体,而不是翻译 的变形这是我的代码:翻译立方体的

HTML文件

<!DOCTYPE html> 
<html> 

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

attribute vec4 vPosition; 
attribute vec4 vColor; 
varying vec4 fColor; 

uniform vec3 theta; 
uniform vec3 tr; 

void main() 
{ 
    // Compute the sines and cosines of theta for each of 
    // the three axes in one computation. 
    vec3 angles = radians(theta); 
    vec3 c = cos(angles); 
    vec3 s = sin(angles); 

    // Remeber: thse matrices are column-major 
    mat4 rx = mat4(1.0, 0.0, 0.0, 0.0, 
       0.0, c.x, s.x, 0.0, 
       0.0, -s.x, c.x, 0.0, 
       0.0, 0.0, 0.0, 1.0); 

    mat4 ry = mat4(c.y, 0.0, -s.y, 0.0, 
       0.0, 1.0, 0.0, 0.0, 
       s.y, 0.0, c.y, 0.0, 
       0.0, 0.0, 0.0, 1.0); 


    mat4 rz = mat4(c.z, s.z, 0.0, 0.0, 
       -s.z, c.z, 0.0, 0.0, 
       0.0, 0.0, 1.0, 0.0, 
       0.0, 0.0, 0.0, 1.0); 

    mat4 t= mat4(1.0, 0.0, 0.0, tr.x, 
        0.0, 1.0, 0.0, tr.y, 
        0.0, 0.0, 1.0, tr.z, 
        0.0, 0.0, 0.0, 1.0); 



    fColor = vColor; 
    gl_Position = rz * ry * rx * t * vPosition; 
    gl_Position.z = -gl_Position.z; 
} 
</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="Lab20170314_1.js"></script> 

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

<br/> 

<button id= "xButton">Rotate X</button> 
<button id= "yButton">Rotate Y</button> 
<button id= "zButton">Rotate Z</button> 
<button id= "stopAnimation"> Start/Stop Animation</button> 
<div> 
rotation angle 0 <input id="slide" type="range" 
min="0" max="10" step="1" value="5" /> 
10 </div> 

<div> 
translation on x -1 <input id="slide1" type="range" 
min="-1" max="1" step="0.1" value="0" /> 
1 </div> 

<div> 
translation on y -1 <input id="slide2" type="range" 
min="-1" max="1" step="0.1" value="0" /> 
1 </div> 

<div> 
translation on z -1 <input id="slide3" type="range" 
min="-1" max="1" step="0.1" value="0" /> 
1 </div> 




</body> 
</html> 

JavaScript代码

"use strict"; 

var canvas; 
var gl; 

var NumVertices = 36; 

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

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

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

var thetaLoc; 
var trLoc; 
var stop = false; 
var trInput = 0; 
var degrees=5; 

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

    gl = WebGLUtils.setupWebGL(canvas); 
    if (!gl) { alert("WebGL isn't available"); } 

    colorCube(); 

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

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

    //event listeners for buttons 

    document.getElementById("xButton").onclick = function() { 
     axis = xAxis; 
    }; 
    document.getElementById("yButton").onclick = function() { 
     axis = yAxis; 
    }; 
    document.getElementById("zButton").onclick = function() { 
     axis = zAxis; 
    }; 
    document.getElementById("stopAnimation").onclick= function() { 
     stop =! stop; 
    }; 
    document.getElementById("slide").onchange= function(){ 
     degrees = parseInt(event.target.value,10); 
    }; 

    document.getElementById("slide1").onchange= function(){ 
     axisTr = xAxis; 
     trInput = parseFloat(event.target.value,10); 
    }; 

    document.getElementById("slide2").onchange= function(){ 
     axisTr = yAxis; 
     trInput = parseFloat(event.target.value,10); 
    }; 

    document.getElementById("slide3").onchange= function(){ 
     axisTr = zAxis; 
     trInput = parseFloat(event.target.value,10); 
    }; 


    render(); 
} 

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 = [ 
     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 = [ 
     [ 0.0, 0.0, 0.0, 1.0 ], // black 
     [ 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 
     [ 0.0, 1.0, 1.0, 1.0 ], // cyan 
     [ 1.0, 1.0, 1.0, 1.0 ] // white 
    ]; 

    // We need to parition the quad into two triangles in order for 
    // WebGL to be able to render it. In this case, we create two 
    // triangles from the quad indices 

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

    } 
} 

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

    if(stop) 
{ 
} 
    else 
{ 
    theta[axis] += degrees; 
} 

    tr[axisTr] = trInput; 

    gl.uniform3fv(thetaLoc, theta); 

    gl.uniform3fv(trLoc, tr); 

    gl.drawArrays(gl.TRIANGLES, 0, NumVertices); 

    requestAnimFrame(render); 
} 

我使用平移矩阵根据齐次坐标的系统,以执行转换。此外,我有三个滑块来设置翻译参数。我错在哪里?

预先感谢您。

回答

0

这将是更好,如果你想发布工作的代码。来自CDN的公共库中的链接为其余部分使用了一段代码。

这里是你的代码的工作和固定的吗?

  • 首先我用twgl来提供一些东西来编译着色器。
  • 您在正在作出忽略
  • 文件的所有其余部分没有理由要使用​​一个帮助了你的canvas标签必须和额外"。所有支持WebGL的浏览器都支持​​。
  • 出现的大多都是没有理由使用任何特殊的函数来获得一个WebGL的上下文。只是做someCanvas.getContext("webgl")
  • 你没有提供flatten功能。看起来你正在使用的扁平化函数会生成一个Float32Array,这对任何习惯于JavaScript的用户都是非常困惑的,并希望它生成一个真正的JavaScript数组。
  • 您未提供vec4功能。不知道为什么,你甚至有一个功能,但它很容易猜到
  • 没有理由使用window.onload。只需将脚本放在HTML的底部,然后直接拨打init即可。
  • 使用oninput代替onchange进行实时更新(因为在滑动滑动时滑动而不是在用户放开滑动条时滑动)。虽然我们认为它使用elem.addEventListener('input', listener)elem.oninput更好。第一个更灵活。它允许多个监听器。

最后到您的实际问题。从编程的角度来看,WebGL的存储顺序是主要的,但它的乘法函数将这些行解释为列。

所以,你可以交换乘法顺序,或者你可以改变你的矩阵。我建议改变矩阵,否则你会不同于其他所有webgl应用程序。

我也建议创建矩阵着色器不灵活,不常见。有些时候,它是做正确的事,但是这可以说是没有的一个,你可能想try these webgl tutorials

"use strict"; 
 

 
var canvas; 
 
var gl; 
 

 
var NumVertices = 36; 
 

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

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

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

 
var thetaLoc; 
 
var trLoc; 
 
var stop = false; 
 
var trInput = 0; 
 
var degrees=5; 
 

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

 
    gl = canvas.getContext("webgl"); 
 
    if (!gl) { alert("WebGL isn't available"); return; } 
 

 
    colorCube(); 
 

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

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

 
    //event listeners for buttons 
 

 
    document.getElementById("xButton").onclick = function() { 
 
     axis = xAxis; 
 
    }; 
 
    document.getElementById("yButton").onclick = function() { 
 
     axis = yAxis; 
 
    }; 
 
    document.getElementById("zButton").onclick = function() { 
 
     axis = zAxis; 
 
    }; 
 
    document.getElementById("stopAnimation").onclick= function() { 
 
     stop =! stop; 
 
    }; 
 
    document.getElementById("slide").oninput = function(){ 
 
     degrees = parseInt(event.target.value,10); 
 
    }; 
 

 
    document.getElementById("slide1").oninput = function(){ 
 
     axisTr = xAxis; 
 
     trInput = parseFloat(event.target.value,10); 
 
    }; 
 

 
    document.getElementById("slide2").oninput = function(){ 
 
     axisTr = yAxis; 
 
     trInput = parseFloat(event.target.value,10); 
 
    }; 
 

 
    document.getElementById("slide3").oninput= function(){ 
 
     axisTr = zAxis; 
 
     trInput = parseFloat(event.target.value,10); 
 
    }; 
 

 

 
    render(); 
 
} 
 

 
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 = [ 
 
     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 = [ 
 
     [ 0.0, 0.0, 0.0, 1.0 ], // black 
 
     [ 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 
 
     [ 0.0, 1.0, 1.0, 1.0 ], // cyan 
 
     [ 1.0, 1.0, 1.0, 1.0 ] // white 
 
    ]; 
 

 
    // We need to parition the quad into two triangles in order for 
 
    // WebGL to be able to render it. In this case, we create two 
 
    // triangles from the quad indices 
 

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

 
    } 
 
} 
 

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

 
    if(stop) 
 
{ 
 
} 
 
    else 
 
{ 
 
    theta[axis] += degrees; 
 
} 
 

 
    tr[axisTr] = trInput; 
 

 
    gl.uniform3fv(thetaLoc, theta); 
 

 
    gl.uniform3fv(trLoc, tr); 
 

 
    gl.drawArrays(gl.TRIANGLES, 0, NumVertices); 
 

 
    requestAnimationFrame(render); 
 
} 
 

 
function initShaders(gl, vsId, fsId) { 
 
    return twgl.createProgramFromScripts(gl, [vsId, fsId]); 
 
} 
 

 
function vec4(x, y, z, w) { 
 
return [x, y, z, w]; 
 
} 
 

 
function flatten(arrays) { 
 
    return new Float32Array([].concat.apply([], arrays)); 
 
} 
 
init();
<script src="https://twgljs.org/dist/3.x/twgl.min.js"></script> 
 
<script id="vertex-shader" type="x-shader/x-vertex"> 
 

 
attribute vec4 vPosition; 
 
attribute vec4 vColor; 
 
varying vec4 fColor; 
 

 
uniform vec3 theta; 
 
uniform vec3 tr; 
 

 
void main() 
 
{ 
 
    // Compute the sines and cosines of theta for each of 
 
    // the three axes in one computation. 
 
    vec3 angles = radians(theta); 
 
    vec3 c = cos(angles); 
 
    vec3 s = sin(angles); 
 

 
    // Remeber: thse matrices are column-major 
 
    mat4 rx = mat4(1.0, 0.0, 0.0, 0.0, 
 
        0.0, c.x, -s.x, 0.0, 
 
        0.0, s.x, c.x, 0.0, 
 
        0.0, 0.0, 0.0, 1.0); 
 

 
    mat4 ry = mat4(c.y, 0.0, s.y, 0.0, 
 
        0.0, 1.0, 0.0, 0.0, 
 
        -s.y, 0.0, c.y, 0.0, 
 
        0.0, 0.0, 0.0, 1.0); 
 

 

 
    mat4 rz = mat4(c.z, -s.z, 0.0, 0.0, 
 
        s.z, c.z, 0.0, 0.0, 
 
        0.0, 0.0, 1.0, 0.0, 
 
        0.0, 0.0, 0.0, 1.0); 
 

 
    mat4 t= mat4(1.0, 0.0, 0.0, 0, 
 
        0.0, 1.0, 0.0, 0, 
 
        0.0, 0.0, 1.0, 0, 
 
        tr.xyz, 1.0); 
 

 

 

 
    fColor = vColor; 
 
    gl_Position = rz * ry * rx * t * vPosition; 
 
    gl_Position.z = -gl_Position.z; 
 
    
 
    // this would too but would be different than most WebGL programs 
 
    //gl_Position = vPosition * t * rx * ry * rz; 
 
    //gl_Position.z = -gl_Position.z; 
 
} 
 
</script> 
 

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

 
precision mediump float; 
 

 
varying vec4 fColor; 
 

 
void 
 
main() 
 
{ 
 
    gl_FragColor = fColor; 
 
} 
 
</script> 
 
<canvas id="gl-canvas" width="512" height="512"> 
 
Oops ... your browser doesn't support the HTML5 canvas element 
 
</canvas> 
 

 
<br/> 
 

 
<button id= "xButton">Rotate X</button> 
 
<button id= "yButton">Rotate Y</button> 
 
<button id= "zButton">Rotate Z</button> 
 
<button id= "stopAnimation"> Start/Stop Animation</button> 
 
<div> 
 
rotation angle 0 <input id="slide" type="range" 
 
min="0" max="10" step="1" value="5" /> 
 
10 </div> 
 

 
<div> 
 
translation on x -1 <input id="slide1" type="range" 
 
min="-1" max="1" step="0.1" value="0" /> 
 
1 </div> 
 

 
<div> 
 
translation on y -1 <input id="slide2" type="range" 
 
min="-1" max="1" step="0.1" value="0" /> 
 
1 </div> 
 

 
<div> 
 
translation on z -1 <input id="slide3" type="range" 
 
min="-1" max="1" step="0.1" value="0" /> 
 
1 </div>

+0

非常感谢您! –