PageSourceSearch

https://open.gl/transformations

html open.gl collected 2026-10-03 19:35:46 UTC 48,448 bytes, 1,053 lines download raw bytes

1<!DOCTYPE html>
2<html>
3	<head>
4		<meta charset="UTF-8">
5
6		<title>OpenGL - Transformations</title>
7
8		<meta name="description" content="An extensive, yet beginner friendly guide to using modern OpenGL for game development on all major platforms." />
9		<meta name="author" content="Alexander Overvoorde" />
10		<meta name="keywords" content="opengl, opengl 3.2, deprecated, non-deprecated, tutorial, guide, cross-platform, game, games, graphics, sfml, sdl, glfw, glut, openglut, beginner, easy" />
11
12		<link rel="shortcut icon" type="image/png" href="/media/tag.png" />
13		<link rel="stylesheet" type="text/css" href="/media/stylesheet.css" />
14
15		<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
16		<link rel="stylesheet" type="text/css" href="/media/mobile.css" media="screen and (max-width: 1024px)" />
17
18		
18<script type="text/x-mathjax-config">
19			// MathJax
20			MathJax.Hub.Config( {
21			  tex2jax: { inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ] },
22			  menuSettings: { context: "Browser" }
23			} );
24		</script>
24
25		
25<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
25
26
27		<link rel="stylesheet" href="/includes/zenburn.min.css" />
28		
28<script type="text/javascript" src="//yandex.st/highlightjs/6.1/highlight.min.js"></script>
28
29		
29<script type="text/javascript" src="/includes/glmatrix.js"></script>
29
30		
30<script type="text/javascript">
31			// Syntax highlighting
32			hljs.initHighlightingOnLoad();
33
34			// Disqus
35			var disqus_url = "http://open.gl/?content=transformations";
36			var disqus_identifier = "transformations";
37
38			// WebGL demos
39			var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame;
40			var callbacks = [];
41			var frame = function() {
42				var time = +new Date() / 1000;
43
44				for (var i = 0; i < callbacks.length; i++) {
45					var rect = callbacks[i].canvas.getBoundingClientRect();
46
47					if (rect.bottom > 0 && rect.top < window.innerHeight)
48						callbacks[i].callback( time );
49				}
50
51				requestAnimationFrame(frame);
52			}
53			function registerAnimatedCanvas(canvas, callback) {
54				callbacks.push({canvas: canvas, callback: callback});
55			}
56			requestAnimationFrame(frame);
57		</script>
57
58		<!--[if lt IE 9]>
59		
59<script src="media/html5shiv.js"></script>
59
60		<![endif]-->
61
62		<!-- Matomo -->
63		
63<script type="text/javascript">
64		  var _paq = _paq || [];
65		  /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
66		  _paq.push(["setDocumentTitle", document.domain + "/" + document.title]);
67		  _paq.push(["setCookieDomain", "*.open.gl"]);
68		  _paq.push(["setDomains", ["*.open.gl"]]);
69		  _paq.push(['trackPageView']);
70		  _paq.push(['enableLinkTracking']);
71		  (function() {
72		    var u="//matomo.while.io/";
73		    _paq.push(['setTrackerUrl', u+'piwik.php']);
74		    _paq.push(['setSiteId', '4']);
75		    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
76		    g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
77		  })();
78		</script>
78
79		<!-- End Matomo Code -->
80	</head>
81
82	<body>
83		<div id="page">
84			<!-- Work in progress ribbon -->
85			<a href="https://github.com/Overv/Open.GL"><img id="ribbon" src="/media/ribbon_fork.png" alt="Fork me!" /></a>
86
87			<!-- Navigation items -->
88			<input type="checkbox" id="nav_toggle" />
89			<nav>
90				<label for="nav_toggle" data-open="&#x2261;" data-close="&#x2715;"></label>
91				<ul>
92					<li><a href="/introduction">Introduction</a></li>
93<li><a href="/context">Context creation</a></li>
94<li><a href="/drawing">Drawing polygons</a></li>
95<li><a href="/textures">Textures</a></li>
96<li class="selected">Transformations</li>
97<li><a href="/depthstencils">Depth and stencils</a></li>
98<li><a href="/framebuffers">Framebuffers</a></li>
99<li><a href="/geometry">Geometry shaders</a></li>
100<li><a href="/feedback">Transform Feedback</a></li>
101				</ul>
102
103				<blockquote style="padding-bottom: 8px; font-size: 14px">
104					<h2 style="margin: 0">Links</h2>
105
106                    <a href="https://github.com/Polytonic/Glitter" style="text-decoration: underline">OpenGL boilerplate code</a><br>
107
108                    <a href="https://github.com/zuck/opengl-examples" style="text-decoration: underline">Easy-to-build code</a><br>
109                    <a href="https://www.youtube.com/playlist?list=PLW3Zl3wyJwWNQjMz941uyOIq3Nw6bcDYC" style="text-decoration: underline">Matrix math tutorials</a><br>
110                    <a href="http://docs.gl" style="text-decoration: underline">OpenGL reference</a>
111				</blockquote>
112
113                <div id="adbox">
114                    
114<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
114
115                    <!-- Open.GL Responsive -->
116                    <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-4259747131061893" data-ad-slot="6609097747" data-ad-format="auto"></ins>
117                    
117<script>
118                        (adsbygoogle = window.adsbygoogle || []).push({});
119                    </script>
119
120                </div>
121			</nav>
122
123			<!-- Content container -->
124			<main>
125				<article>
126					<h1 id="transformations">Matrices</h1>
127
128<p>Since this is a guide on graphics programming, this chapter will not cover a lot of the extensive theory behind matrices. Only the theory that applies to their use in computer graphics will be considered here and they will be explained from a programmer's perspective. If you want to learn more about the topic, <a href="https://www.khanacademy.org/math/algebra2/algebra-matrices/Basic_matrix_operations/v/introduction-to-the-matrix">these Khan Academy videos</a> are a really good general introduction to the subject.</p>
129
130<p>A matrix is a rectangular array of mathematical expressions, much like a two-dimensional array. Below is an example of a matrix displayed in the common square brackets form.</p>
131
132<span class="MathJax_Preview">[a = \begin{bmatrix}
133    1 & 2 \\
134    3 & 4 \\
135    5 & 6
136  \end{bmatrix}]</span>
136<script type="math/tex; mode=display">a = \begin{bmatrix}
137    1 & 2 \\
138    3 & 4 \\
139    5 & 6
140  \end{bmatrix}</script>
140
141
142<p>Matrices values are indexed by <code>(i,j)</code> where <code>i</code> is the row and <code>j</code> is the column. That is why the matrix displayed above is called a 3-by-2 matrix. To refer to a specific value in the matrix, for example <code>5</code>, the <span class="MathJax_Preview">[a_{31}]</span>
142<script type="math/tex">a_{31}</script>
142 notation is used.</p>
143
144<h2>Basic operations</h2>
145
146<p>To get a bit more familiar with the concept of an array of numbers, let's first look at a few basic operations.</p>
147
148<h3>Addition and subtraction</h3>
149
150<p>Just like regular numbers, the addition and subtraction operators are also defined for matrices. The only requirement is that the two operands have exactly the same row and column dimensions.</p>
151
152<span class="MathJax_Preview">[\begin{bmatrix}
153    3 & 2 \\
154    0 & 4
155  \end{bmatrix}
156  +
157  \begin{bmatrix}
158    4 & 2 \\
159    2 & 2
160  \end{bmatrix}
161  =
162  \begin{bmatrix}
163    3 + 4 & 2 + 2 \\
164    0 + 2 & 4 + 2
165  \end{bmatrix}
166  =
167  \begin{bmatrix}
168    7 & 4 \\
169    2 & 6
170  \end{bmatrix}]</span>
170<script type="math/tex; mode=display">\begin{bmatrix}
171    3 & 2 \\
172    0 & 4
173  \end{bmatrix}
174  +
175  \begin{bmatrix}
176    4 & 2 \\
177    2 & 2
178  \end{bmatrix}
179  =
180  \begin{bmatrix}
181    3 + 4 & 2 + 2 \\
182    0 + 2 & 4 + 2
183  \end{bmatrix}
184  =
185  \begin{bmatrix}
186    7 & 4 \\
187    2 & 6
188  \end{bmatrix}</script>
188
189
190<span class="MathJax_Preview">[\begin{bmatrix}
191    4 & 2 \\
192    2 & 7
193  \end{bmatrix}
194  -
195  \begin{bmatrix}
196    3 & 2 \\
197    0 & 4
198  \end{bmatrix}
199  =
200  \begin{bmatrix}
201    4 - 3 & 2 - 2 \\
202    2 - 0 & 7 - 4
203  \end{bmatrix}
204  =
205  \begin{bmatrix}
206    1 & 0 \\
207    2 & 3
208  \end{bmatrix}]</span>
208<script type="math/tex; mode=display">\begin{bmatrix}
209    4 & 2 \\
210    2 & 7
211  \end{bmatrix}
212  -
213  \begin{bmatrix}
214    3 & 2 \\
215    0 & 4
216  \end{bmatrix}
217  =
218  \begin{bmatrix}
219    4 - 3 & 2 - 2 \\
220    2 - 0 & 7 - 4
221  \end{bmatrix}
222  =
223  \begin{bmatrix}
224    1 & 0 \\
225    2 & 3
226  \end{bmatrix}</script>
226
227
228<p>The values in the matrices are individually added or subtracted from each other.</p>
229
230<h3>Scalar product</h3>
231
232<p>The product of a scalar and a matrix is as straightforward as addition and subtraction.</p>
233
234<span class="MathJax_Preview">[2 \cdot
235  \begin{bmatrix}
236    1 & 2 \\
237    3 & 4
238  \end{bmatrix}
239  =
240  \begin{bmatrix}
241    2 & 4 \\
242    6 & 8
243   \end{bmatrix}]</span>
243<script type="math/tex; mode=display">2 \cdot
244  \begin{bmatrix}
245    1 & 2 \\
246    3 & 4
247  \end{bmatrix}
248  =
249  \begin{bmatrix}
250    2 & 4 \\
251    6 & 8
252   \end{bmatrix}</script>
252
253
254<p>The values in the matrices are each multiplied by the scalar.</p>
255
256<h2>Matrix-Vector product</h2>
257
258<p>The product of a matrix with another matrix is quite a bit more involved and is often misunderstood, so for simplicity's sake I will only mention the specific cases that apply to graphics programming. To see how matrices are actually used to transform vectors, we'll first dive into the product of a matrix and a vector.</p>
259
260<span class="MathJax_Preview">[\begin{bmatrix}
261    \color{red}a & \color{red}b & \color{red}c & \color{red}d \\
262    \color{blue}e & \color{blue}f & \color{blue}g & \color{blue}h \\
263    \color{green}i & \color{green}j & \color{green}k & \color{green}l \\
264    \color{magenta}m & \color{magenta}n & \color{magenta}o & \color{magenta}p
265  \end{bmatrix}
266  \cdot
267  \begin{pmatrix}
268    x \\
269    y \\
270    z \\
271    1
272  \end{pmatrix}
273  =
274  \begin{pmatrix}
275    \color{red}a\cdot x + \color{red}b\cdot y + \color{red}c\cdot z + \color{red}d\cdot 1 \\
276    \color{blue}e\cdot x + \color{blue}f\cdot y + \color{blue}g\cdot z + \color{blue}h\cdot 1 \\
277    \color{green}i\cdot x + \color{green}j\cdot y + \color{green}k\cdot z + \color{green}l\cdot 1 \\
278    \color{magenta}m\cdot x + \color{magenta}n\cdot y + \color{magenta}o\cdot z + \color{magenta}p\cdot 1
279  \end{pmatrix}]</span>
279<script type="math/tex; mode=display">\begin{bmatrix}
280    \color{red}a & \color{red}b & \color{red}c & \color{red}d \\
281    \color{blue}e & \color{blue}f & \color{blue}g & \color{blue}h \\
282    \color{green}i & \color{green}j & \color{green}k & \color{green}l \\
283    \color{magenta}m & \color{magenta}n & \color{magenta}o & \color{magenta}p
284  \end{bmatrix}
285  \cdot
286  \begin{pmatrix}
287    x \\
288    y \\
289    z \\
290    1
291  \end{pmatrix}
292  =
293  \begin{pmatrix}
294    \color{red}a\cdot x + \color{red}b\cdot y + \color{red}c\cdot z + \color{red}d\cdot 1 \\
295    \color{blue}e\cdot x + \color{blue}f\cdot y + \color{blue}g\cdot z + \color{blue}h\cdot 1 \\
296    \color{green}i\cdot x + \color{green}j\cdot y + \color{green}k\cdot z + \color{green}l\cdot 1 \\
297    \color{magenta}m\cdot x + \color{magenta}n\cdot y + \color{magenta}o\cdot z + \color{magenta}p\cdot 1
298  \end{pmatrix}</script>
298
299
300<p>To calculate the product of a matrix and a vector, the vector is written as a 4-by-1 matrix. The expressions to the right of the equals sign show how the new <code>x</code>, <code>y</code> and <code>z</code> values are calculated after the vector has been transformed. For those among you who aren't very math savvy, the dot is a multiplication sign.</p>
301
302<p>I will mention each of the common vector transformations in this section and how a matrix can be formed that performs them. For completeness, let's first consider a transformation that does absolutely nothing.</p>
303
304<span class="MathJax_Preview">[\begin{bmatrix}
305    \color{red}1 & \color{red}0 & \color{red}0 & \color{red}0 \\
306    \color{blue}0 & \color{blue}1 & \color{blue}0 & \color{blue}0 \\
307    \color{green}0 & \color{green}0 & \color{green}1 & \color{green}0 \\
308    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
309  \end{bmatrix}
310  \cdot
311  \begin{pmatrix}
312    x \\
313    y \\
314    z \\
315    1
316  \end{pmatrix}
317  =
318  \begin{pmatrix}
319    \color{red}1\cdot x + \color{red}0\cdot y + \color{red}0\cdot z + \color{red}0\cdot 1 \\
320    \color{blue}0\cdot x + \color{blue}1\cdot y + \color{blue}0\cdot z + \color{blue}0\cdot 1 \\
321    \color{green}0\cdot x + \color{green}0\cdot y + \color{green}1\cdot z + \color{green}0\cdot 1 \\
322    \color{magenta}0\cdot x + \color{magenta}0\cdot y + \color{magenta}0\cdot z + \color{magenta}1\cdot 1
323  \end{pmatrix}
324  =
325  \begin{pmatrix}
326    \color{red}1\cdot x \\
327    \color{blue}1\cdot y \\
328    \color{green}1\cdot z \\
329    \color{magenta}1\cdot 1
330  \end{pmatrix}]</span>
330<script type="math/tex; mode=display">\begin{bmatrix}
331    \color{red}1 & \color{red}0 & \color{red}0 & \color{red}0 \\
332    \color{blue}0 & \color{blue}1 & \color{blue}0 & \color{blue}0 \\
333    \color{green}0 & \color{green}0 & \color{green}1 & \color{green}0 \\
334    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
335  \end{bmatrix}
336  \cdot
337  \begin{pmatrix}
338    x \\
339    y \\
340    z \\
341    1
342  \end{pmatrix}
343  =
344  \begin{pmatrix}
345    \color{red}1\cdot x + \color{red}0\cdot y + \color{red}0\cdot z + \color{red}0\cdot 1 \\
346    \color{blue}0\cdot x + \color{blue}1\cdot y + \color{blue}0\cdot z + \color{blue}0\cdot 1 \\
347    \color{green}0\cdot x + \color{green}0\cdot y + \color{green}1\cdot z + \color{green}0\cdot 1 \\
348    \color{magenta}0\cdot x + \color{magenta}0\cdot y + \color{magenta}0\cdot z + \color{magenta}1\cdot 1
349  \end{pmatrix}
350  =
351  \begin{pmatrix}
352    \color{red}1\cdot x \\
353    \color{blue}1\cdot y \\
354    \color{green}1\cdot z \\
355    \color{magenta}1\cdot 1
356  \end{pmatrix}</script>
356
357
358<p>This matrix is called the <em>identity matrix</em>, because just like the number <code>1</code>, it will always return the value it was originally multiplied by.</p>
359
360<p>Let's look at the most common vector transformations now and deduce how a matrix can be formed from them.</p>
361
362<h3>Translation</h3>
363
364<p>To see why we're working with 4-by-1 vectors and subsequently 4-by-4 transformation matrices, let's see how a translation matrix is formed. A translation moves a vector a certain distance in a certain direction.</p>
365
366<p><img src="media/img/c4_translation.png" alt="" /></p>
367
368<p>Can you guess from the multiplication overview what the matrix should look like to translate a vector by <code>(X,Y,Z)</code>?</p>
369
370<span class="MathJax_Preview">[\begin{bmatrix}
371    \color{red}1 & \color{red}0 & \color{red}0 & \color{red}X \\
372    \color{blue}0 & \color{blue}1 & \color{blue}0 & \color{blue}Y \\
373    \color{green}0 & \color{green}0 & \color{green}1 & \color{green}Z \\
374    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
375  \end{bmatrix}
376  \cdot
377  \begin{pmatrix}
378    x \\
379    y \\
380    z \\
381    1
382  \end{pmatrix}
383  =
384  \begin{pmatrix}
385    x+\color{red}X\cdot 1 \\
386    y+\color{blue}Y\cdot 1 \\
387    z+\color{green}Z\cdot 1 \\
388    1
389  \end{pmatrix}]</span>
389<script type="math/tex; mode=display">\begin{bmatrix}
390    \color{red}1 & \color{red}0 & \color{red}0 & \color{red}X \\
391    \color{blue}0 & \color{blue}1 & \color{blue}0 & \color{blue}Y \\
392    \color{green}0 & \color{green}0 & \color{green}1 & \color{green}Z \\
393    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
394  \end{bmatrix}
395  \cdot
396  \begin{pmatrix}
397    x \\
398    y \\
399    z \\
400    1
401  \end{pmatrix}
402  =
403  \begin{pmatrix}
404    x+\color{red}X\cdot 1 \\
405    y+\color{blue}Y\cdot 1 \\
406    z+\color{green}Z\cdot 1 \\
407    1
408  \end{pmatrix}</script>
408
409
410<p>Without the fourth column and the bottom <code>1</code> value a translation wouldn't have been possible.</p>
411
412<h3>Scaling</h3>
413
414<p>A scale transformation scales each of a vector's components by a (different) scalar. It is commonly used to shrink or stretch a vector as demonstrated below.</p>
415
416<p><img src="media/img/c4_scaling.png" alt="" /></p>
417
418<p>If you understand how the previous matrix was formed, it should not be difficult to come up with a matrix that scales a given vector by <code>(SX,SY,SZ)</code>.</p>
419
420<span class="MathJax_Preview">[\begin{bmatrix}
421    \color{red}{SX} & \color{red}0 & \color{red}0 & \color{red}0 \\
422    \color{blue}0 & \color{blue}{SY} & \color{blue}0 & \color{blue}0 \\
423    \color{green}0 & \color{green}0 & \color{green}{SZ} & \color{green}0 \\
424    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
425  \end{bmatrix}
426  \cdot
427  \begin{pmatrix}
428    x \\
429    y \\
430    z \\
431    1
432  \end{pmatrix}
433  =
434  \begin{pmatrix}
435    \color{red}{SX}\cdot x \\
436    \color{green}{SY}\cdot y \\
437    \color{blue}{SZ}\cdot z \\
438    1
439  \end{pmatrix}]</span>
439<script type="math/tex; mode=display">\begin{bmatrix}
440    \color{red}{SX} & \color{red}0 & \color{red}0 & \color{red}0 \\
441    \color{blue}0 & \color{blue}{SY} & \color{blue}0 & \color{blue}0 \\
442    \color{green}0 & \color{green}0 & \color{green}{SZ} & \color{green}0 \\
443    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
444  \end{bmatrix}
445  \cdot
446  \begin{pmatrix}
447    x \\
448    y \\
449    z \\
450    1
451  \end{pmatrix}
452  =
453  \begin{pmatrix}
454    \color{red}{SX}\cdot x \\
455    \color{green}{SY}\cdot y \\
456    \color{blue}{SZ}\cdot z \\
457    1
458  \end{pmatrix}</script>
458
459
460<p>If you think about it for a moment, you can see that scaling would also be possible with a mere 3-by-3 matrix.</p>
461
462<h3>Rotation</h3>
463
464<p>A rotation transformation rotates a vector around the origin <code>(0,0,0)</code> using a given <em>axis</em> and <em>angle</em>. To understand how the axis and the angle control a rotation, let's do a small experiment.</p>
465
466<p><img src="media/img/c4_rotation.png" alt="" /></p>
467
468<p>Put your thumb up against your monitor and try rotating your hand around it. The object, your hand, is rotating around your thumb: the rotation axis. The further you rotate your hand away from its initial position, the higher the rotation angle.</p>
469
470<p>In this way the rotation axis can be imagined as an arrow an object is rotating around. If you imagine your monitor to be a 2-dimensional XY surface, the rotation axis (your thumb) is pointing in the Z direction.</p>
471
472<p>Objects can be rotated around any given axis, but for now only the X, Y and Z axis are important. You'll see later in this chapter that any rotation axis can be established by rotating around the X, Y and Z axis simultaneously.</p>
473
474<p>The matrices for rotating around the three axes are specified here. The rotation angle is indicated by the theta ($\theta$).</p>
475
476<p>Rotation around X-axis:</p>
477
478<span class="MathJax_Preview">[\begin{bmatrix}
479    \color{red}1 & \color{red}0 & \color{red}0 & \color{red}0 \\
480    \color{blue}0 & \color{blue}{\cos\theta} & \color{blue}{-\sin\theta} & \color{blue}0 \\
481    \color{green}0 & \color{green}{\sin\theta} & \color{green}{\cos\theta} & \color{green}0 \\
482    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
483  \end{bmatrix}
484  \cdot
485  \begin{pmatrix}
486    x \\
487    y \\
488    z \\
489    1
490  \end{pmatrix}
491  =
492  \begin{pmatrix}
493    x \\
494    \color{blue}{\cos\theta}\cdot y \color{blue}{-\sin\theta}\cdot z \\
495    \color{green}{\sin\theta}\cdot y + \color{green}{\cos\theta}\cdot z \\
496    1
497  \end{pmatrix}]</span>
497<script type="math/tex; mode=display">\begin{bmatrix}
498    \color{red}1 & \color{red}0 & \color{red}0 & \color{red}0 \\
499    \color{blue}0 & \color{blue}{\cos\theta} & \color{blue}{-\sin\theta} & \color{blue}0 \\
500    \color{green}0 & \color{green}{\sin\theta} & \color{green}{\cos\theta} & \color{green}0 \\
501    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
502  \end{bmatrix}
503  \cdot
504  \begin{pmatrix}
505    x \\
506    y \\
507    z \\
508    1
509  \end{pmatrix}
510  =
511  \begin{pmatrix}
512    x \\
513    \color{blue}{\cos\theta}\cdot y \color{blue}{-\sin\theta}\cdot z \\
514    \color{green}{\sin\theta}\cdot y + \color{green}{\cos\theta}\cdot z \\
515    1
516  \end{pmatrix}</script>
516
517
518<p>Rotation around Y-axis:</p>
519
520<span class="MathJax_Preview">[\begin{bmatrix}
521    \color{red}{\cos\theta} & \color{red}0 & \color{red}{\sin\theta} & \color{red}0 \\
522    \color{blue}0 & \color{blue}1 & \color{blue}0 & \color{blue}0 \\
523    \color{green}{-\sin\theta} & \color{green}0 & \color{green}{\cos\theta} & \color{green}0 \\
524    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
525  \end{bmatrix}
526  \cdot
527  \begin{pmatrix}
528    x \\
529    y \\
530    z \\
531    1
532  \end{pmatrix}
533  =
534  \begin{pmatrix}
535    \color{red}{\cos\theta}\cdot x + \color{red}{\sin\theta}\cdot z \\
536    y \\
537    \color{green}{-\sin\theta}\cdot x + \color{green}{\cos\theta}\cdot z \\
538    1
539  \end{pmatrix}]</span>
539<script type="math/tex; mode=display">\begin{bmatrix}
540    \color{red}{\cos\theta} & \color{red}0 & \color{red}{\sin\theta} & \color{red}0 \\
541    \color{blue}0 & \color{blue}1 & \color{blue}0 & \color{blue}0 \\
542    \color{green}{-\sin\theta} & \color{green}0 & \color{green}{\cos\theta} & \color{green}0 \\
543    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
544  \end{bmatrix}
545  \cdot
546  \begin{pmatrix}
547    x \\
548    y \\
549    z \\
550    1
551  \end{pmatrix}
552  =
553  \begin{pmatrix}
554    \color{red}{\cos\theta}\cdot x + \color{red}{\sin\theta}\cdot z \\
555    y \\
556    \color{green}{-\sin\theta}\cdot x + \color{green}{\cos\theta}\cdot z \\
557    1
558  \end{pmatrix}</script>
558
559
560<p>Rotation around Z-axis:</p>
561
562<span class="MathJax_Preview">[\begin{bmatrix}
563    \color{red}{\cos\theta} & \color{red}{-\sin\theta} & \color{red}0 & \color{red}0 \\
564    \color{blue}{\sin\theta} & \color{blue}{\cos\theta} & \color{blue}0 & \color{blue}0 \\
565    \color{green}0 & \color{green}0 & \color{green}1 & \color{green}0 \\
566    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
567  \end{bmatrix}
568  \cdot
569  \begin{pmatrix}
570    x \\
571    y \\
572    z \\
573    1
574  \end{pmatrix}
575  =
576  \begin{pmatrix}
577    \color{red}{\cos\theta}\cdot x \color{red}{-\sin\theta}\cdot y \\
578    \color{blue}{\sin\theta}\cdot x + \color{blue}{\cos\theta}\cdot y \\
579    z \\
580    1
581  \end{pmatrix}]</span>
581<script type="math/tex; mode=display">\begin{bmatrix}
582    \color{red}{\cos\theta} & \color{red}{-\sin\theta} & \color{red}0 & \color{red}0 \\
583    \color{blue}{\sin\theta} & \color{blue}{\cos\theta} & \color{blue}0 & \color{blue}0 \\
584    \color{green}0 & \color{green}0 & \color{green}1 & \color{green}0 \\
585    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
586  \end{bmatrix}
587  \cdot
588  \begin{pmatrix}
589    x \\
590    y \\
591    z \\
592    1
593  \end{pmatrix}
594  =
595  \begin{pmatrix}
596    \color{red}{\cos\theta}\cdot x \color{red}{-\sin\theta}\cdot y \\
597    \color{blue}{\sin\theta}\cdot x + \color{blue}{\cos\theta}\cdot y \\
598    z \\
599    1
600  \end{pmatrix}</script>
600
601
602<p>Don't worry about understanding the actual geometry behind this, explaining that is beyond the scope of this guide. What matters is that you have a solid idea of how a rotation is described by a rotation axis and an angle and that you've at least seen what a rotation matrix looks like.</p>
603
604<h2>Matrix-Matrix product</h2>
605
606<p>In the previous section you've seen how transformation matrices can be used to apply transformations to vectors, but this by itself is not very useful. It clearly takes far less effort to do a translation and scaling by hand without all those pesky matrices!</p>
607
608<p>Now, what if I told you that it is possible to combine as many transformations as you want into a single matrix by simply multiplying them? You would be able to apply even the most complex transformations to any vertex with a simple multiplication.</p>
609
610<p>In the same style as the previous section, this is how the product of two 4-by-4 matrices is determined:</p>
611
612<span class="MathJax_Preview">[\begin{bmatrix}
613    \color{red}a & \color{red}b & \color{red}c & \color{red}d \\
614    \color{blue}e & \color{blue}f & \color{blue}g & \color{blue}h \\
615    \color{green}i & \color{green}j & \color{green}k & \color{green}l \\
616    \color{magenta}m & \color{magenta}n & \color{magenta}o & \color{magenta}p
617  \end{bmatrix}
618  \cdot
619  \begin{bmatrix}
620    \color{red}A & \color{blue}B & \color{green}C & \color{magenta}D \\
621    \color{red}E & \color{blue}F & \color{green}G & \color{magenta}H \\
622    \color{red}I & \color{blue}J & \color{green}K & \color{magenta}L \\
623    \color{red}M & \color{blue}N & \color{green}O & \color{magenta}P
624  \end{bmatrix}
625  = \\
626  \begin{bmatrix}
627    \color{red}{aA} + \color{red}{bE} + \color{red}{cI} + \color{red}{dM} &
628      \color{red}a\color{blue}B + \color{red}b\color{blue}F + \color{red}c\color{blue}J + \color{red}d\color{blue}N &
629      \color{red}a\color{green}C + \color{red}b\color{green}G + \color{red}c\color{green}K + \color{red}d\color{green}O &
630      \color{red}a\color{magenta}D + \color{red}b\color{magenta}H + \color{red}c\color{magenta}L + \color{red}d\color{magenta}P \\
631    \color{blue}e\color{red}A + \color{blue}f\color{red}E + \color{blue}g\color{red}I + \color{blue}h\color{red}M &
632      \color{blue}{eB} + \color{blue}{fF} + \color{blue}{gJ} + \color{blue}{hN} &
633      \color{blue}e\color{green}C + \color{blue}f\color{green}G + \color{blue}g\color{green}K + \color{blue}h\color{green}O &
634      \color{blue}e\color{magenta}D + \color{blue}f\color{magenta}H + \color{blue}g\color{magenta}L + \color{blue}h\color{magenta}P \\
635    \color{green}i\color{red}A + \color{green}j\color{red}E + \color{green}k\color{red}I + \color{green}l\color{red}M &
636      \color{green}i\color{blue}B + \color{green}j\color{blue}F + \color{green}k\color{blue}J + \color{green}l\color{blue}N &
637      \color{green}{iC} + \color{green}{jG} + \color{green}{kK} + \color{green}{lO} &
638      \color{green}i\color{magenta}D + \color{green}j\color{magenta}H + \color{green}k\color{magenta}L + \color{green}l\color{magenta}P \\
639    \color{magenta}m\color{red}A + \color{magenta}n\color{red}E + \color{magenta}o\color{red}I + \color{magenta}p\color{red}M &
640      \color{magenta}m\color{blue}B + \color{magenta}n\color{blue}F + \color{magenta}o\color{blue}J + \color{magenta}p\color{blue}N &
641      \color{magenta}m\color{green}C + \color{magenta}n\color{green}G + \color{magenta}o\color{green}K + \color{magenta}p\color{green}O &
642      \color{magenta}{mD} + \color{magenta}{nH} + \color{magenta}{oL} + \color{magenta}{pP}
643  \end{bmatrix}]</span>
643<script type="math/tex; mode=display">\begin{bmatrix}
644    \color{red}a & \color{red}b & \color{red}c & \color{red}d \\
645    \color{blue}e & \color{blue}f & \color{blue}g & \color{blue}h \\
646    \color{green}i & \color{green}j & \color{green}k & \color{green}l \\
647    \color{magenta}m & \color{magenta}n & \color{magenta}o & \color{magenta}p
648  \end{bmatrix}
649  \cdot
650  \begin{bmatrix}
651    \color{red}A & \color{blue}B & \color{green}C & \color{magenta}D \\
652    \color{red}E & \color{blue}F & \color{green}G & \color{magenta}H \\
653    \color{red}I & \color{blue}J & \color{green}K & \color{magenta}L \\
654    \color{red}M & \color{blue}N & \color{green}O & \color{magenta}P
655  \end{bmatrix}
656  = \\
657  \begin{bmatrix}
658    \color{red}{aA} + \color{red}{bE} + \color{red}{cI} + \color{red}{dM} &
659      \color{red}a\color{blue}B + \color{red}b\color{blue}F + \color{red}c\color{blue}J + \color{red}d\color{blue}N &
660      \color{red}a\color{green}C + \color{red}b\color{green}G + \color{red}c\color{green}K + \color{red}d\color{green}O &
661      \color{red}a\color{magenta}D + \color{red}b\color{magenta}H + \color{red}c\color{magenta}L + \color{red}d\color{magenta}P \\
662    \color{blue}e\color{red}A + \color{blue}f\color{red}E + \color{blue}g\color{red}I + \color{blue}h\color{red}M &
663      \color{blue}{eB} + \color{blue}{fF} + \color{blue}{gJ} + \color{blue}{hN} &
664      \color{blue}e\color{green}C + \color{blue}f\color{green}G + \color{blue}g\color{green}K + \color{blue}h\color{green}O &
665      \color{blue}e\color{magenta}D + \color{blue}f\color{magenta}H + \color{blue}g\color{magenta}L + \color{blue}h\color{magenta}P \\
666    \color{green}i\color{red}A + \color{green}j\color{red}E + \color{green}k\color{red}I + \color{green}l\color{red}M &
667      \color{green}i\color{blue}B + \color{green}j\color{blue}F + \color{green}k\color{blue}J + \color{green}l\color{blue}N &
668      \color{green}{iC} + \color{green}{jG} + \color{green}{kK} + \color{green}{lO} &
669      \color{green}i\color{magenta}D + \color{green}j\color{magenta}H + \color{green}k\color{magenta}L + \color{green}l\color{magenta}P \\
670    \color{magenta}m\color{red}A + \color{magenta}n\color{red}E + \color{magenta}o\color{red}I + \color{magenta}p\color{red}M &
671      \color{magenta}m\color{blue}B + \color{magenta}n\color{blue}F + \color{magenta}o\color{blue}J + \color{magenta}p\color{blue}N &
672      \color{magenta}m\color{green}C + \color{magenta}n\color{green}G + \color{magenta}o\color{green}K + \color{magenta}p\color{green}O &
673      \color{magenta}{mD} + \color{magenta}{nH} + \color{magenta}{oL} + \color{magenta}{pP}
674  \end{bmatrix}</script>
674
675
676<p>The above is commonly recognized among mathematicians as an <em>indecipherable mess</em>. To get a better idea of what's going on, let's consider two 2-by-2 matrices instead.</p>
677
678<span class="MathJax_Preview">[\begin{bmatrix}
679    \color{red}1 & \color{red}2 \\
680    \color{blue}3 & \color{blue}4
681  \end{bmatrix}
682  \cdot
683  \begin{bmatrix}
684    \color{green}a & \color{magenta}b \\
685    \color{green}c & \color{magenta}d
686  \end{bmatrix}
687  =
688  \begin{bmatrix}
689    \color{red}1\cdot \color{green}a + \color{red}2 \cdot \color{green}c & \color{red}1 \cdot \color{magenta}b + \color{red}2 \cdot \color{magenta}d \\
690    \color{blue}3\cdot \color{green}a + \color{blue}4 \cdot \color{green}c & \color{blue}3 \cdot \color{magenta}b + \color{blue}4 \cdot \color{magenta}d
691  \end{bmatrix}]</span>
691<script type="math/tex; mode=display">\begin{bmatrix}
692    \color{red}1 & \color{red}2 \\
693    \color{blue}3 & \color{blue}4
694  \end{bmatrix}
695  \cdot
696  \begin{bmatrix}
697    \color{green}a & \color{magenta}b \\
698    \color{green}c & \color{magenta}d
699  \end{bmatrix}
700  =
701  \begin{bmatrix}
702    \color{red}1\cdot \color{green}a + \color{red}2 \cdot \color{green}c & \color{red}1 \cdot \color{magenta}b + \color{red}2 \cdot \color{magenta}d \\
703    \color{blue}3\cdot \color{green}a + \color{blue}4 \cdot \color{green}c & \color{blue}3 \cdot \color{magenta}b + \color{blue}4 \cdot \color{magenta}d
704  \end{bmatrix}</script>
704
705
706<p>Try to see the pattern here with help of the colors. The factors on the left side (<code>1,2</code> and <code>3,4</code>) of the multiplication dot are the values in the row of the first matrix. The factors on the right side are the values in the rows of the second matrix repeatedly. It is not necessary to remember how exactly this works, but it's good to have seen how it's done at least once.</p>
707
708<h3>Combining transformations</h3>
709
710<p>To demonstrate the multiplication of two matrices, let's try scaling a given vector by <code>(2,2,2)</code> and translating it by <code>(1,2,3)</code>. Given the translation and scaling matrices above, the following product is calculated:</p>
711
712<span class="MathJax_Preview">[M_\text{translate}\cdot M_\text{scale} =
713  \begin{bmatrix}
714    \color{red}1 & \color{red}0 & \color{red}0 & \color{red}1 \\
715    \color{blue}0 & \color{blue}1 & \color{blue}0 & \color{blue}2 \\
716    \color{green}0 & \color{green}0 & \color{green}1 & \color{green}3 \\
717    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
718  \end{bmatrix}
719  \cdot
720  \begin{bmatrix}
721    \color{red}{2} & \color{red}0 & \color{red}0 & \color{red}0 \\
722    \color{blue}0 & \color{blue}{2} & \color{blue}0 & \color{blue}0 \\
723    \color{green}0 & \color{green}0 & \color{green}{2} & \color{green}0 \\
724    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
725  \end{bmatrix}
726  =
727  \begin{bmatrix}
728    \color{red}{2} & \color{red}0 & \color{red}0 & \color{red}1 \\
729    \color{blue}0 & \color{blue}{2} & \color{blue}0 & \color{blue}2 \\
730    \color{green}0 & \color{green}0 & \color{green}{2} & \color{green}3 \\
731    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
732  \end{bmatrix}]</span>
732<script type="math/tex; mode=display">M_\text{translate}\cdot M_\text{scale} =
733  \begin{bmatrix}
734    \color{red}1 & \color{red}0 & \color{red}0 & \color{red}1 \\
735    \color{blue}0 & \color{blue}1 & \color{blue}0 & \color{blue}2 \\
736    \color{green}0 & \color{green}0 & \color{green}1 & \color{green}3 \\
737    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
738  \end{bmatrix}
739  \cdot
740  \begin{bmatrix}
741    \color{red}{2} & \color{red}0 & \color{red}0 & \color{red}0 \\
742    \color{blue}0 & \color{blue}{2} & \color{blue}0 & \color{blue}0 \\
743    \color{green}0 & \color{green}0 & \color{green}{2} & \color{green}0 \\
744    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
745  \end{bmatrix}
746  =
747  \begin{bmatrix}
748    \color{red}{2} & \color{red}0 & \color{red}0 & \color{red}1 \\
749    \color{blue}0 & \color{blue}{2} & \color{blue}0 & \color{blue}2 \\
750    \color{green}0 & \color{green}0 & \color{green}{2} & \color{green}3 \\
751    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
752  \end{bmatrix}</script>
752
753
754<p>Notice how we want to scale the vector first, but the scale transformation comes last in the multiplication. Pay attention to this when combining transformations or you'll get the opposite of what you've asked for.</p>
755
756<p>Now, let's try to transform a vector and see if it worked:</p>
757
758<span class="MathJax_Preview">[\begin{bmatrix}
759    \color{red}{2} & \color{red}0 & \color{red}0 & \color{red}1 \\
760    \color{blue}0 & \color{blue}{2} & \color{blue}0 & \color{blue}2 \\
761    \color{green}0 & \color{green}0 & \color{green}{2} & \color{green}3 \\
762    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
763  \end{bmatrix}
764  \cdot
765  \begin{pmatrix}
766    x \\
767    y \\
768    z \\
769    1
770  \end{pmatrix}
771  =
772  \begin{pmatrix}
773    \color{red}2 x + \color{red}1 \\
774    \color{blue}2y + \color{blue}2 \\
775    \color{green}2z + \color{green}3 \\
776    1
777  \end{pmatrix}]</span>
777<script type="math/tex; mode=display">\begin{bmatrix}
778    \color{red}{2} & \color{red}0 & \color{red}0 & \color{red}1 \\
779    \color{blue}0 & \color{blue}{2} & \color{blue}0 & \color{blue}2 \\
780    \color{green}0 & \color{green}0 & \color{green}{2} & \color{green}3 \\
781    \color{magenta}0 & \color{magenta}0 & \color{magenta}0 & \color{magenta}1
782  \end{bmatrix}
783  \cdot
784  \begin{pmatrix}
785    x \\
786    y \\
787    z \\
788    1
789  \end{pmatrix}
790  =
791  \begin{pmatrix}
792    \color{red}2 x + \color{red}1 \\
793    \color{blue}2y + \color{blue}2 \\
794    \color{green}2z + \color{green}3 \\
795    1
796  \end{pmatrix}</script>
796
797
798<p>Perfect! The vector is first scaled by two and then shifted in position by <code>(1,2,3)</code>.</p>
799
800<h2>Transformations in OpenGL</h2>
801
802<p>You've seen in the previous sections how basic transformations can be applied to vectors to move them around in the world. The job of transforming 3D points into 2D coordinates on your screen is also accomplished through matrix transformations. Just like the graphics pipeline, transforming a vector is done step-by-step. Although OpenGL allows you to decide on these steps yourself, all 3D graphics applications use a variation of the process described here.</p>
803
804<p><img src="media/img/c4_transformation.png" alt="" /></p>
805
806<p>Each transformation transforms a vector into a new coordinate system, thus moving to the next step. These transformations and coordinate systems will be discussed below in more detail.</p>
807
808<h3>Model matrix</h3>
809
810<p>The model matrix transforms a position in a model to the position in the world. This position is affected by the position, scale and rotation of the model that is being drawn. It is generally a combination of the simple transformations you've seen before. If you are already specifying your vertices in world coordinates (common when drawing a simple test scene), then this matrix can simply be set to the identity matrix.</p>
811
812<h3>View matrix</h3>
813
814<p>In real life you're used to moving the camera to alter the view of a certain scene, in OpenGL it's the other way around. The camera in OpenGL cannot move and is defined to be located at <code>(0,0,0)</code> facing the negative Z direction. That means that instead of moving and rotating the camera, the world is moved and rotated around the camera to construct the appropriate view.</p>
815
816<blockquote>
817  <p>Older versions of OpenGL forced you to use <em>ModelView</em> and <em>Projection</em> transformations. The ModelView matrix combined the model and view transformations into one. I personally find it is easier to separate the two, so the view transformation can be modified independently of the model matrix.</p>
818</blockquote>
819
820<p>That means that to simulate a camera transformation, you actually have to transform the world with the inverse of that transformation. Example: if you want to move the camera up, you have to move the world down instead.</p>
821
822<h3>Projection matrix</h3>
823
824<p>After the world has been aligned with your camera using the view transformation, the projection transformation can be applied, resulting in the clip coordinates. If you're doing a perspective transformation, these clip coordinates are not ready to be used as normalized device coordinates just yet.</p>
825
826<p>To transform the clipping coordinate into a normalized device coordinate, <em>perspective division</em> has to be performed. A clipping coordinate resulting from a perspective projection has a number different than 1 in the fourth row, also known as <code>w</code>. This number directly reflects the effect of objects further away being smaller than those up front.</p>
827
828<span class="MathJax_Preview">[v_\text{normalized} =
829  \begin{pmatrix}
830    x_\text{clip} / w_\text{clip} \\
831    y_\text{clip} / w_\text{clip} \\
832    z_\text{clip} / w_\text{clip}
833  \end{pmatrix}]</span>
833<script type="math/tex; mode=display">v_\text{normalized} =
834  \begin{pmatrix}
835    x_\text{clip} / w_\text{clip} \\
836    y_\text{clip} / w_\text{clip} \\
837    z_\text{clip} / w_\text{clip}
838  \end{pmatrix}</script>
838
839
840<p>The <code>x</code> and <code>y</code> coordinates will be in the familiar <code>-1</code> and <code>1</code> range now, which OpenGL can transform into window coordinates. The <code>z</code> is known as the depth and will play an important role in the next chapter.</p>
841
842<p>The coordinates resulting from the projection transformation are called clipping coordinates because the value of <code>w</code> is used to determine whether an object is too close or behind the camera or too far away to be drawn. The projection matrix is created with those limits, so you'll be able to specify these yourself.</p>
843
844<h3>Putting it all together</h3>
845
846<p>To sum it all up, the final transformation of a vertex is the product of the model, view and projection matrices.</p>
847
848<span class="MathJax_Preview">[v' = M_\text{proj} \cdot M_\text{view} \cdot M_\text{model} \cdot v]</span>
848<script type="math/tex; mode=display">v' = M_\text{proj} \cdot M_\text{view} \cdot M_\text{model} \cdot v</script>
848
849
850<p>This operation is typically performed in the vertex shader and assigned to the <code>gl_Position</code> return value in clipping coordinates. OpenGL will perform the perspective division and transformation into window coordinates. It is important to be aware of these steps, because you'll have to do them yourself when working with techniques like shadow mapping.</p>
851
852<h2>Using transformations for 3D</h2>
853
854<p>Now that you know three important transformations, it is time to implement these in code to create an actual 3D scene. You can use any of the programs developed in the last two chapters as a base, but I'll use the texture blending sample from the end of the last chapter here.</p>
855
856<p>To introduce matrices in the code, we can make use of the GLM (OpenGL Math) library. This library comes with vector and matrix classes and will handle all the math efficiently without ever having to worry about it. It is a header-only library, which means you don't have to link with anything.</p>
857
858<p>To use it, add the GLM root directory to your include path and include these three headers:</p>
859
860<pre><code class="cpp">#include &lt;glm/glm.hpp&gt;
861#include &lt;glm/gtc/matrix_transform.hpp&gt;
862#include &lt;glm/gtc/type_ptr.hpp&gt;
863</code></pre>
864
865<p>The second header includes functions to ease the calculation of the view and projection matrices. The third header adds functionality for converting a matrix object into a float array for usage in OpenGL.</p>
866
867<h3>A simple transformation</h3>
868
869<p>Before diving straight into 3D, let's first try a simple 2D rotation.</p>
870
871<pre><code class="cpp">glm::mat4 trans = glm::mat4(1.0f);
872trans = glm::rotate(trans, glm::radians(180.0f), glm::vec3(0.0f, 0.0f, 1.0f));
873</code></pre>
874
875<p>The first line creates a new 4-by-4 matrix and initializes it to the identity matrix. The <code>glm::rotate</code> function multiplies this matrix by a rotation transformation of 180 degrees around the Z axis. Remember that since the screen lies in the XY plane, the Z axis is the axis you want to rotate points around.</p>
876
877<p>To see if it works, let's try to rotate a vector with this transformation:</p>
878
879<pre><code class="cpp">glm::vec4 result = trans * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
880printf("%f, %f, %f\n", result.x, result.y, result.z);
881</code></pre>
882
883<p>As expected, the output is <code>(-1,0,0)</code>. A counter-clockwise rotation of 180 degrees of a vector pointing to the right results in a vector pointing to the left. Note that the rotation would be clockwise if an axis <code>(0,0,-1)</code> was used.</p>
884
885<p>The next step is to perform this transformation in the vertex shader to rotate every drawn vertex. GLSL has a special <code>mat4</code> type to hold matrices and we can use that to upload the transformation to the GPU as uniform.</p>
886
887<pre><code class="cpp">GLint uniTrans = glGetUniformLocation(shaderProgram, "trans");
888glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(trans));
889</code></pre>
890
891<p>The second parameter of the <a href="http://docs.gl/gl3/glUniform"><code>glUniformMatrix4fv</code></a> function specifies how many matrices are to be uploaded, because you can have arrays of matrices in GLSL. The third parameter specifies whether the specified matrix should be transposed before usage. This is related to the way matrices are stored as <code>float</code> arrays in memory; you don't have to worry about it. The last parameter specifies the matrix to upload, where the <code>glm::value_ptr</code> function converts the matrix class into an array of 16 (4x4) floats.</p>
892
893<p>All that remains is updating the vertex shader to include this uniform and use it to transform each vertex:</p>
894
895<pre><code class="cpp">#version 150 core
896
897in vec2 position;
898in vec3 color;
899in vec2 texcoord;
900
901out vec3 Color;
902out vec2 Texcoord;
903
904uniform mat4 trans;
905
906void main()
907{
908    Color = color;
909    Texcoord = texcoord;
910    gl_Position = trans * vec4(position, 0.0, 1.0);
911}
912</code></pre>
913
914<p>The primitives in your scene will now be upside down.</p>
915
916<p><img src="media/img/c4_window.png" alt="" /></p>
917
918<p>To spice things up a bit, you could change the rotation with time:</p>
919
920<pre><code class="cpp">auto t_start = std::chrono::high_resolution_clock::now();
921
922...
923
924// Calculate transformation
925auto t_now = std::chrono::high_resolution_clock::now();
926float time = std::chrono::duration_cast&lt;std::chrono::duration&lt;float&gt;&gt;(t_now - t_start).count();
927
928glm::mat4 trans;
929trans = glm::rotate(
930    trans,
931    time * glm::radians(180.0f),
932    glm::vec3(0.0f, 0.0f, 1.0f)
933);
934glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(trans));
935
936// Draw a rectangle from the 2 triangles using 6 indices
937glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
938
939...
940</code></pre>
941
942<p>This will result in something like this:</p>
943
944<div class="livedemo_wrap">
945    <div class="livedemo" id="demo_c4_rotation" style="background: url('/media/img/c4_window2.png')">
946        <canvas width="640" height="480"></canvas>
947        
947<script type="text/javascript" src="https://open.gl/content/demos/c4_rotation.js"></script>
947
948    </div>
949</div>
950
951<p>You can find the full code <a href="https://open.gl/content/code/c4_transformation.txt">here</a> if you have any issues.</p>
952
953<h3>Going 3D</h3>
954
955<p>The rotation above can be considered the model transformation, because it transforms the vertices in object space to world space using the rotation of the object.</p>
956
957<pre><code class="cpp">glm::mat4 view = glm::lookAt(
958    glm::vec3(1.2f, 1.2f, 1.2f),
959    glm::vec3(0.0f, 0.0f, 0.0f),
960    glm::vec3(0.0f, 0.0f, 1.0f)
961);
962GLint uniView = glGetUniformLocation(shaderProgram, "view");
963glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));
964</code></pre>
965
966<p>To create the view transformation, GLM offers the useful <code>glm::lookAt</code> function that simulates a moving camera. The first parameter specifies the position of the camera, the second the point to be centered on-screen and the third the <code>up</code> axis. Here <code>up</code> is defined as the Z axis, which implies that the XY plane is the "ground".</p>
967
968<pre><code class="cpp">glm::mat4 proj = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 1.0f, 10.0f);
969GLint uniProj = glGetUniformLocation(shaderProgram, "proj");
970glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj));
971</code></pre>
972
973<p>Similarly, GLM comes with the <code>glm::perspective</code> function to create a perspective projection matrix. The first parameter is the vertical field-of-view, the second parameter the aspect ratio of the screen and the last two parameters are the <em>near</em> and <em>far</em> planes.</p>
974
975<blockquote>
976  <p><strong>Field-of-view</strong> <br /><br />
977  The field-of-view defines the angle between the top and bottom of the 2D surface on which the world will be projected. Zooming in games is often accomplished by decreasing this angle as opposed to moving the camera closer, because it more closely resembles real life.</p>
978  
979  <p><img src="media/img/c4_fov.png" alt="" /></p>
980  
981  <p>By decreasing the angle, you can imagine that the "rays" from the camera spread out less and thus cover a smaller area of the scene.</p>
982</blockquote>
983
984<p>The near and far planes are known as the clipping planes. Any vertex closer to the camera than the <code>near</code> clipping plane and any vertex farther away than the <code>far</code> clipping plane is clipped as these influence the <code>w</code> value.</p>
985
986<p>Now piecing it all together, the vertex shader looks something like this:</p>
987
988<pre><code class="cpp">#version 150 core
989
990in vec2 position;
991in vec3 color;
992in vec2 texcoord;
993
994out vec3 Color;
995out vec2 Texcoord;
996
997uniform mat4 model;
998uniform mat4 view;
999uniform mat4 proj;
1000
1001void main()
1002{
1003    Color = color;
1004    Texcoord = texcoord;
1005    gl_Position = proj * view * model * vec4(position, 0.0, 1.0);
1006}
1007</code></pre>
1008
1009<p>Notice that I've renamed the matrix previously known as <code>trans</code> to <code>model</code> and it is still updated every frame.</p>
1010
1011<div class="livedemo_wrap">
1012    <div class="livedemo" id="demo_c4_3d" style="background: url('/media/img/c4_window3.png')">
1013        <canvas width="640" height="480"></canvas>
1014        
1014<script type="text/javascript" src="https://open.gl/content/demos/c4_3d.js"></script>
1014
1015    </div>
1016</div>
1017
1018<p>Success! You can find the full code <a href="https://open.gl/content/code/c4_3d.txt">here</a> if you get stuck.</p>
1019
1020<h2>Exercises</h2>
1021
1022<ul>
1023<li>Make the rectangle with the blended image grow bigger and smaller with <code>sin</code>. (<a href="https://open.gl/content/code/c4_exercise_1.txt">Solution</a>)</li>
1024<li>Make the rectangle flip around the X axis after pressing the space bar and slowly stop again. (<a href="https://open.gl/content/code/c4_exercise_2.txt">Solution</a>)</li>
1025</ul>
1026				</article>
1027
1028                <div id="adbox-article">
1029                    <hr />
1030
1031                    
1031<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
1031
1032                    <!-- Open.GL Responsive -->
1033                    <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-4259747131061893" data-ad-slot="6609097747" data-ad-format="auto"></ins>
1034                    
1034<script>
1035                        (adsbygoogle = window.adsbygoogle || []).push({});
1036                    </script>
1036
1037                </div>
1038
1039				
1040				<!-- Disqus comments -->
1041				<hr />
1042				<aside id="disqus_thread"></aside>
1043				
1043<script type="text/javascript">
1044					var dsq = document.createElement("script");
1045					dsq.type = "text/javascript";
1046					dsq.async = true;
1047					dsq.src = "//opengl.disqus.com/embed.js";
1048					document.getElementsByTagName("head")[0].appendChild( dsq );
1049				</script>
1049
1050							</main>
1051		</div>
1052	</body>
1053</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.