如何在Webgl的缓冲区中仅使用4个顶点绘制2个嵌套矩形?

时间:2015-01-29 22:14:34

标签: webgl

我知道如何使用一个统一变量来移动矩形,但我不知道如何使它变小或变大以适应另一个。任何帮助表示赞赏。谢谢!

var vertices = 
    [
  vec2(0.0, 0.0 ),  
  vec2(0.4, 0),
  vec2(0, 0.4),
  vec2(0.4, 0.4)  
];

gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 0.9, 0.9, 0.9, 1.0 );

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

// Create a buffer for the vertex shader in the GPU.
var bufferId = gl.createBuffer();

// Tell the GPU to expect data for this buffer
gl.bindBuffer( gl.ARRAY_BUFFER, bufferId );

    // Send data into the buffer.   
gl.bufferData( gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW );   

// Set up the buffer for use
var vPosition = gl.getAttribLocation( program, "myvPosition" );

// myvPosition (identified using vPosition) will correspond to 2 floats per vertex,
gl.vertexAttribPointer( vPosition, 2, gl.FLOAT, false, 0, 0 );

// Enable use of the vertex buffer with myvPosition
gl.enableVertexAttribArray( vPosition );

// Get an index to each uniform variable in the GPU's shader      
var xIndex   = gl.getUniformLocation( program, "xAdjust" );
var yIndex   = gl.getUniformLocation( program, "yAdjust" );
var rIndex   = gl.getUniformLocation(  program, "red" );
var gIndex   = gl.getUniformLocation(  program, "green" );
var bIndex   = gl.getUniformLocation(  program, "blue" );

gl.uniform1f( xIndex, -0.25 );    // move to the left

gl.uniform1f( gIndex,  1.0 );


gl.clear( gl.COLOR_BUFFER_BIT );  // note new place to put clear

render();

gl.uniform1f( xIndex, +0.25 );    // move to the right

gl.uniform1f( rIndex,  1.0 );

render();   
};

function render()  
{   
   gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 );
 }

例如:我可以更改gl.uniform1f(xIndex)中的值以沿x轴移动矩形

1 个答案:

答案 0 :(得分:1)

了解转换矩阵的时间。有很多数学,但我会尝试尽可能简单地解释它。

让我们选择新的广场1x1:

var vertices = 
    [
  vec2(0, 0),  
  vec2(1, 0),
  vec2(0, 1),
  vec2(1, 1)  
];

现在,如果你想将它向左移动1(正如你所做的那样),你想在所有顶点的[x]中加1。这看起来很简单。 如果你想旋转它,它会复杂得多。想象一下,你的物体将来自50000个顶点而不仅仅是4 =>超级复杂!

因此人们发明了一些被广泛使用的程序。我们为每个对象创建转换矩阵。在2D中,矩阵是3x3。在3D中,矩阵是4x4。

矩阵如何工作?首先创建顶点,然后使用

初始化矩阵
// js example
var model1M = mat3.create([
 1, 0, 0,
 0, 1, 0,
 0, 0, 1]);

这意味着"没有完成转型"然而。然后通过矩阵运算来平移,旋转,缩放对象。 请记住,转型订单很重要!!

move & rotate != rotate & move

想要渲染后,将矩阵发送到着色器。

// this is how you send 1 float value
gl.uniform1f( xIndex, -0.25 );    // move to the left

// this is how we send 3x3 matrix
var mvmi = gl.getUniformLocation( program, "modelViewMatrix" );
gl.uniformMatrix3fv(mvmi, false, model1M);

在着色器中:

// you have to modify what is in vec4
gl_Position = modelViewMatrix * vec4( position, 1.0 );

并完成了。

问题是mat3在js中不存在。转换数学: http://upload.wikimedia.org/wikipedia/commons/2/2c/2D_affine_transformation_matrix.svg

您需要先实现所有数学。但更简单的是下载库,例如http://glmatrix.net/并包含gl-matrix-min.js。然后按照文档http://glmatrix.net/docs/2.2.0/symbols/mat3.html

简单的食谱:

var DEG_TO_RAD = 0.0174532925;

// create matrix, you dont have to type numbers in
var modelMatrix = mat3.create();

// move
mat3.translate(modelMatrix, modelMatrix, [-0.5, -0.5]);

// rotate by 45 degrees
mat3.rotate(modelMatrix, modelMatrix, 45*DEG_TO_RAD);

// make square smaller
mat3.scale(modelMatrix, modelMatrix, [0.4, 0.4]);