• Aucun résultat trouvé

Matrix-Vector Multiplication

Dans le document OpenGL ES 2 for Android (Page 97-101)

To multiply a vector with a matrix, we put the matrix on the left side and the vector on the right side. We then start with the first row of the matrix and multiply the first component of that row with the first component of the vector, the second component of that row with the second component of the vector, and so on. We then add all of the results for that row together to create the first component of the result.

The following is an example of a complete matrix-vector multiply:

For the first row, we multiply xx and x, xy and y, xz and z, xw and w, and then add all four results together to create the x component of the result.

The labeling of the matrix should hopefully make more sense now that we’ve seen it in action. All four components of the first row of the matrix will affect the resulting x, all four components of the second row will affect the resulting y, and so on. Within each row of the matrix, the first component gets multi-plied with the x of the vector, the second component gets multimulti-plied with the y, and so on.

The Identity Matrix

Let’s look at an example with some actual numbers. We’ll start off with a very basic matrix, called the identity matrix. An identity matrix looks like the following:

Chapter 5. Adjusting to the Screen’s Aspect Ratio

84

The reason this is called an identity matrix is because we can multiply this matrix with any vector and we’ll always get back the same vector, just like we get back the same number if we multiply any number by 1.

Here’s an example of multiplying an identity matrix with a vector containing 1, 2, 3, and 4:

For the first row, we multiply the first component of the vector by 1 and ignore the other components by multiplying them by 0. For the second row, we do the same thing, except we preserve the second component of the vector. The net result of all of this is that the answer will be identical to the original vector.

Let’s simplify those multiplies and add the results together. This is what we’ll get:

Translations Using a Matrix

Now that we understand the identity matrix, let’s look at a very simple type of matrix that gets used quite often in OpenGL: the translation matrix. With this type of matrix, we can move one of our objects along a distance that we specify. This matrix looks just like an identity matrix, with three additional elements specified on the right-hand side:

Linear Algebra 101

85

Let’s look at an example with a position of (2, 2), with a default z of 0 and a default w of 1. We want to translate the vector by 3 along the x-axis and 3 along the y-axis, so we’ll put 3 for xtranslation and 3 for ytranslation.

Here’s the result:

After we simplify the multiplies, we’re left with this:

Adding the results together gives us the final answer:

The position is now at (5, 5), which is what we expected.

The reason this works is that we built this matrix from an identity matrix, so the first thing that will happen is that the original vector will be copied over.

Since the translation components are multiplied by w, and we normally specify a position’s w component as 1 (remember that if we don’t specify the w component, OpenGL sets it to 1 by default), the translation components just get added to the result.

The effect of w is important to take note of here. In the next chapter, we’ll learn about perspective projections, and a coordinate may not have a w value of 1 after such a projection. If we try to do a translation or another type of Chapter 5. Adjusting to the Screen’s Aspect Ratio

86

transformation with that coordinate after we’ve done a projection and the w component is no longer 1, then we’ll run into trouble and things will get distorted.

We’ve learned just enough about vector and matrix math to get us on our feet; let’s go ahead and learn how to define an orthographic projection.

5.4 Defining an Orthographic Projection

To define an orthographic projection, we’ll use Android’s Matrix class, which resides in the android.opengl package. In that class there’s a method called orthoM(), which will generate an orthographic projection for us. We’ll use that projection to adjust the coordinate space, as we just discussed in Adjusting to the Aspect Ratio, on page 80, and as we’ll soon see, an orthographic projec-tion is very similar to a translaprojec-tion matrix.

Let’s take a look at all of the parameters for orthoM():

orthoM(float[] m, int mOffset, float left, float right, float bottom, float top, float near, float far) The destination array—this array’s length should be at least sixteen elements so it can store the orthographic projection matrix.

float[] m

The offset into m into which the result is written int mOffset

The minimum range of the x-axis float left

The maximum range of the x-axis float right

The minimum range of the y-axis float bottom

The maximum range of the y-axis float top

The minimum range of the z-axis float near

The maximum range of the z-axis float far

When we call this method, it should produce the following orthographic pro-jection matrix:

Defining an Orthographic Projection

87

Don’t let the fractions overwhelm you: this is very similar to the translation matrix that we saw in Translations Using a Matrix, on page 85. This ortho-graphic projection matrix will map everything between left and right, bottom and top, and near and far into the range -1 to 1 in normalized device coordi-nates, and everything within this range will be visible on the screen.

The main difference is that the z-axis has a negative sign on it, which has the effect of inverting the z coordinate. This means that as things get further away, their z coordinate becomes more and more negative. The reason for this is entirely due to history and convention.

Dans le document OpenGL ES 2 for Android (Page 97-101)