Re: [Public WebGL] Re: Get Viewport for converting coordinates

On Wed, Aug 18, 2010 at 9:47 AM, Mehmet Sirin wrote:

> The size the canvas is rendered to is independent of the size it is
> displayed at.
> <cavnas width="100" height="100" style="width: 300px; height:
> 400px"></canvas>
> Will create a canvas that renders to a 100x100 pixel backbuffer but is
> stretched and displayed at 300x400 pixels so you should use the size it's
> displayed at to do your projection and click computations.
I have this one:
<canvas id="lesson03-canvas" width="700" height="530" style="border:
none;" width="700" height="530" false"></canvas>

> Assuming you are doing standard world * view * projection math for your
> models
yes, i do that standard.

> here's how you should calculate the correct projection for your
> projection matrix based on the size the backbuffer is displayed

is it necessary to use the perspective matrix you posted? I'm using
the matrices-functions which Vladimir Y. has written:

I'm sure his are just fine. The point is you don't want gl.viewportWidth / gl.viewportHeight. You should use canvas.clientWidth / canvas.clientHeight

perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 20000000.0);

var pMatrix;
function perspective(fovy, aspect, znear, zfar) {
pMatrix = makePerspective(fovy, aspect, znear, zfar);
}

function makePerspective(fovy, aspect, znear, zfar)
{
var ymax = znear * Math.tan(fovy * Math.PI / 360.0);
var ymin = -ymax;
var xmin = ymin * aspect;
var xmax = ymax * aspect;

return makeFrustum(xmin, xmax, ymin, ymax, znear, zfar);
}

and

function makeFrustum(left, right,
bottom, top,
znear, zfar)
{
var X = 2*znear/(right-left);
var Y = 2*znear/(top-bottom);
var A = (right+left)/(right-left);
var B = (top+bottom)/(top-bottom);
var C = -(zfar+znear)/(zfar-znear);
var D = -2*zfar*znear/(zfar-znear);

return \$M([[X, 0, A, 0],
[0, Y, B, 0],
[0, 0, C, D],
[0, 0, -1, 0]]);
}

> If you need code for viewProjectionInverse I can post that as well.

you mean inverse(projectionMatrix*mvMatrix) ? Got that..but sure I
would be glad if you post that,too :)

If you're using these functions?

Then I'd guess it's something like

var projection = M4x4.makePerspective(45, canvas.clientWidth / canvas.clientHeight,  0.1, 20000000.0);
var view = M4x4.makeLookAt(eye, center, up);
var viewProjection = M4x4.mul(view, projection);  (or is it projection, view?)

It doesn't appear he provided an matrix inverse function
var viewInverseProjection = inverse(viewProjection);

where inverse is

function inverse(m) {
var tmp_0 = m[2*4+2] * m[3*4+3];
var tmp_1 = m[3*4+2] * m[2*4+3];
var tmp_2 = m[1*4+2] * m[3*4+3];
var tmp_3 = m[3*4+2] * m[1*4+3];
var tmp_4 = m[1*4+2] * m[2*4+3];
var tmp_5 = m[2*4+2] * m[1*4+3];
var tmp_6 = m[0*4+2] * m[3*4+3];
var tmp_7 = m[3*4+2] * m[0*4+3];
var tmp_8 = m[0*4+2] * m[2*4+3];
var tmp_9 = m[2*4+2] * m[0*4+3];
var tmp_10 = m[0*4+2] * m[1*4+3];
var tmp_11 = m[1*4+2] * m[0*4+3];
var tmp_12 = m[2*4+0] * m[3*4+1];
var tmp_13 = m[3*4+0] * m[2*4+1];
var tmp_14 = m[1*4+0] * m[3*4+1];
var tmp_15 = m[3*4+0] * m[1*4+1];
var tmp_16 = m[1*4+0] * m[2*4+1];
var tmp_17 = m[2*4+0] * m[1*4+1];
var tmp_18 = m[0*4+0] * m[3*4+1];
var tmp_19 = m[3*4+0] * m[0*4+1];
var tmp_20 = m[0*4+0] * m[2*4+1];
var tmp_21 = m[2*4+0] * m[0*4+1];
var tmp_22 = m[0*4+0] * m[1*4+1];
var tmp_23 = m[1*4+0] * m[0*4+1];

var t0 = (tmp_0 * m[1*4+1] + tmp_3 * m[2*4+1] + tmp_4 * m[3*4+1]) -
(tmp_1 * m[1*4+1] + tmp_2 * m[2*4+1] + tmp_5 * m[3*4+1]);
var t1 = (tmp_1 * m[0*4+1] + tmp_6 * m[2*4+1] + tmp_9 * m[3*4+1]) -
(tmp_0 * m[0*4+1] + tmp_7 * m[2*4+1] + tmp_8 * m[3*4+1]);
var t2 = (tmp_2 * m[0*4+1] + tmp_7 * m[1*4+1] + tmp_10 * m[3*4+1]) -
(tmp_3 * m[0*4+1] + tmp_6 * m[1*4+1] + tmp_11 * m[3*4+1]);
var t3 = (tmp_5 * m[0*4+1] + tmp_8 * m[1*4+1] + tmp_11 * m[2*4+1]) -
(tmp_4 * m[0*4+1] + tmp_9 * m[1*4+1] + tmp_10 * m[2*4+1]);

var d = 1.0 / (m[0*4+0] * t0 + m[1*4+0] * t1 + m[2*4+0] * t2 + m[3*4+0] * t3);

return [d * t0, d * t1, d * t2, d * t3,
d * ((tmp_1 * m[1*4+0] + tmp_2 * m[2*4+0] + tmp_5 * m[3*4+0]) -
(tmp_0 * m[1*4+0] + tmp_3 * m[2*4+0] + tmp_4 * m[3*4+0])),
d * ((tmp_0 * m[0*4+0] + tmp_7 * m[2*4+0] + tmp_8 * m[3*4+0]) -
(tmp_1 * m[0*4+0] + tmp_6 * m[2*4+0] + tmp_9 * m[3*4+0])),
d * ((tmp_3 * m[0*4+0] + tmp_6 * m[1*4+0] + tmp_11 * m[3*4+0]) -
(tmp_2 * m[0*4+0] + tmp_7 * m[1*4+0] + tmp_10 * m[3*4+0])),
d * ((tmp_4 * m[0*4+0] + tmp_9 * m[1*4+0] + tmp_10 * m[2*4+0]) -
(tmp_5 * m[0*4+0] + tmp_8 * m[1*4+0] + tmp_11 * m[2*4+0])),
d * ((tmp_12 * m[1*4+3] + tmp_15 * m[2*4+3] + tmp_16 * m[3*4+3]) -
(tmp_13 * m[1*4+3] + tmp_14 * m[2*4+3] + tmp_17 * m[3*4+3])),
d * ((tmp_13 * m[0*4+3] + tmp_18 * m[2*4+3] + tmp_21 * m[3*4+3]) -
(tmp_12 * m[0*4+3] + tmp_19 * m[2*4+3] + tmp_20 * m[3*4+3])),
d * ((tmp_14 * m[0*4+3] + tmp_19 * m[1*4+3] + tmp_22 * m[3*4+3]) -
(tmp_15 * m[0*4+3] + tmp_18 * m[1*4+3] + tmp_23 * m[3*4+3])),
d * ((tmp_17 * m[0*4+3] + tmp_20 * m[1*4+3] + tmp_23 * m[2*4+3]) -
(tmp_16 * m[0*4+3] + tmp_21 * m[1*4+3] + tmp_22 * m[2*4+3])),
d * ((tmp_14 * m[2*4+2] + tmp_17 * m[3*4+2] + tmp_13 * m[1*4+2]) -
(tmp_16 * m[3*4+2] + tmp_12 * m[1*4+2] + tmp_15 * m[2*4+2])),
d * ((tmp_20 * m[3*4+2] + tmp_12 * m[0*4+2] + tmp_19 * m[2*4+2]) -
(tmp_18 * m[2*4+2] + tmp_21 * m[3*4+2] + tmp_13 * m[0*4+2])),
d * ((tmp_18 * m[1*4+2] + tmp_23 * m[3*4+2] + tmp_15 * m[0*4+2]) -
(tmp_22 * m[3*4+2] + tmp_14 * m[0*4+2] + tmp_19 * m[1*4+2])),
d * ((tmp_22 * m[2*4+2] + tmp_16 * m[0*4+2] + tmp_21 * m[1*4+2]) -
(tmp_20 * m[1*4+2] + tmp_23 * m[2*4+2] + tmp_17 * m[0*4+2]))];
};